注意

本文档适用于 Ceph 的开发版本。

块设备和 Nomad

与 Kubernetes 一样,Nomad 可以使用 Ceph 块设备。这得益于 ceph-csi,它允许您动态配置 RBD 镜像或导入现有的 RBD 镜像。

每个版本的 Nomad 都与 ceph-csi 兼容,但用于生成本文档中的步骤和指南的参考版本 Nomad 是 Nomad v1.1.2,这是撰写本文时可用的最新版本。

要将 Ceph 块设备与 Nomad 一起使用,您必须在 Nomad 环境中安装和配置 ceph-csi。下图显示了 Nomad/Ceph 技术栈。

注意

Nomad 有许多可能的任务驱动程序,但此示例仅使用 Docker 容器。

重要

ceph-csi 默认使用 RBD 内核模块,该模块可能不支持所有 Ceph CRUSH 可调参数RBD 镜像特性

创建池

默认情况下,Ceph 块设备使用 rbd 池。确保您的 Ceph 集群正在运行,然后为 Nomad 持久存储创建一个池

ceph osd pool create nomad

有关为池指定放置组数量的详细信息,请参阅 创建池。有关应为池设置的放置组数量的详细信息,请参阅 放置组

新创建的池在使用前必须进行初始化。使用 rbd 工具初始化池

rbd pool init nomad

配置 ceph-csi

Ceph 客户端身份验证设置

为 Nomad 和 ceph-csi 创建一个新用户。执行以下命令并记录生成的密钥

$ ceph auth get-or-create client.nomad mon 'profile rbd' osd 'profile rbd pool=nomad' mgr 'profile rbd pool=nomad'
[client.nomad]
        key = AQAlh9Rgg2vrDxAARy25T7KHabs6iskSHpAEAQ==

配置 Nomad

配置 Nomad 以允许容器使用特权模式

默认情况下,Nomad 不允许容器使用特权模式。我们必须配置 Nomad 以允许容器使用特权模式。编辑 Nomad 配置文件,将以下配置块添加到 /etc/nomad.d/nomad.hcl

plugin "docker" {
  config {
    allow_privileged = true
  }
}

加载 rbd 模块

Nomad 必须加载 rbd 模块。运行以下命令以确认 rbd 模块已加载

$ lsmod | grep rbd
rbd                    94208  2
libceph               364544  1 rbd

如果未加载 rbd 模块,请加载它

sudo modprobe rbd

重启 Nomad

重启 Nomad

sudo systemctl restart nomad

创建 ceph-csi 控制器和插件节点

ceph-csi 插件需要两个组件

  • 控制器插件:与提供者的 API 通信。

  • 节点插件:在客户端执行任务。

注意

我们将在这些文件中设置 ceph-csi 的版本。有关 ceph-csi 与其他版本兼容性的信息,请参阅 ceph-csi 版本

配置控制器插件

控制器插件需要 Ceph 集群的 Ceph 监视器地址。收集 (1) Ceph 集群唯一的 fsid 和 (2) 监视器地址

$ ceph mon dump
<...>
fsid b9127830-b0cc-4e34-aa47-9d1a2e9949a8
<...>
0: [v2:192.168.1.1:3300/0,v1:192.168.1.1:6789/0] mon.a
1: [v2:192.168.1.2:3300/0,v1:192.168.1.2:6789/0] mon.b
2: [v2:192.168.1.3:3300/0,v1:192.168.1.3:6789/0] mon.c

生成一个类似于下面示例的 ceph-csi-plugin-controller.nomad 文件。将 fsid 替换为“clusterID”,将监视器地址替换为“monitors”

job "ceph-csi-plugin-controller" {
  datacenters = ["dc1"]
  group "controller" {
    network {
      port "metrics" {}
    }
    task "ceph-controller" {
      template {
        data        = <<EOF
[{
    "clusterID": "b9127830-b0cc-4e34-aa47-9d1a2e9949a8",
    "monitors": [
        "192.168.1.1",
        "192.168.1.2",
        "192.168.1.3"
    ]
}]
EOF
        destination = "local/config.json"
        change_mode = "restart"
      }
      driver = "docker"
      config {
        image = "quay.io/cephcsi/cephcsi:v3.3.1"
        volumes = [
          "./local/config.json:/etc/ceph-csi-config/config.json"
        ]
        mounts = [
          {
            type     = "tmpfs"
            target   = "/tmp/csi/keys"
            readonly = false
            tmpfs_options = {
              size = 1000000 # size in bytes
            }
          }
        ]
        args = [
          "--type=rbd",
          "--controllerserver=true",
          "--drivername=rbd.csi.ceph.com",
          "--endpoint=unix://csi/csi.sock",
          "--nodeid=${node.unique.name}",
          "--instanceid=${node.unique.name}-controller",
          "--pidlimit=-1",
          "--logtostderr=true",
          "--v=5",
          "--metricsport=$${NOMAD_PORT_metrics}"
        ]
      }
      resources {
        cpu    = 500
        memory = 256
      }
      service {
        name = "ceph-csi-controller"
        port = "metrics"
        tags = [ "prometheus" ]
      }
      csi_plugin {
        id        = "ceph-csi"
        type      = "controller"
        mount_dir = "/csi"
      }
    }
  }
}

配置插件节点

生成一个类似于下面示例的 ceph-csi-plugin-nodes.nomad 文件。将 fsid 替换为“clusterID”,将监视器地址替换为“monitors”

job "ceph-csi-plugin-nodes" {
  datacenters = ["dc1"]
  type        = "system"
  group "nodes" {
    network {
      port "metrics" {}
    }
    task "ceph-node" {
      driver = "docker"
      template {
        data        = <<EOF
[{
    "clusterID": "b9127830-b0cc-4e34-aa47-9d1a2e9949a8",
    "monitors": [
        "192.168.1.1",
        "192.168.1.2",
        "192.168.1.3"
    ]
}]
EOF
        destination = "local/config.json"
        change_mode = "restart"
      }
      config {
        image = "quay.io/cephcsi/cephcsi:v3.3.1"
        volumes = [
          "./local/config.json:/etc/ceph-csi-config/config.json"
        ]
        mounts = [
          {
            type     = "tmpfs"
            target   = "/tmp/csi/keys"
            readonly = false
            tmpfs_options = {
              size = 1000000 # size in bytes
            }
          }
        ]
        args = [
          "--type=rbd",
          "--drivername=rbd.csi.ceph.com",
          "--nodeserver=true",
          "--endpoint=unix://csi/csi.sock",
          "--nodeid=${node.unique.name}",
          "--instanceid=${node.unique.name}-nodes",
          "--pidlimit=-1",
          "--logtostderr=true",
          "--v=5",
          "--metricsport=$${NOMAD_PORT_metrics}"
        ]
        privileged = true
      }
      resources {
        cpu    = 500
        memory = 256
      }
      service {
        name = "ceph-csi-nodes"
        port = "metrics"
        tags = [ "prometheus" ]
      }
      csi_plugin {
        id        = "ceph-csi"
        type      = "node"
        mount_dir = "/csi"
      }
    }
  }
}

启动插件控制器和节点

要启动插件控制器和 Nomad 节点,请运行以下命令

nomad job run ceph-csi-plugin-controller.nomad
nomad job run ceph-csi-plugin-nodes.nomad

ceph-csi 镜像将被下载。

几分钟后检查插件状态

$ nomad plugin status ceph-csi
ID                   = ceph-csi
Provider             = rbd.csi.ceph.com
Version              = 3.3.1
Controllers Healthy  = 1
Controllers Expected = 1
Nodes Healthy        = 1
Nodes Expected       = 1

Allocations
ID        Node ID   Task Group  Version  Desired  Status   Created    Modified
23b4db0c  a61ef171  nodes       4        run      running  3h26m ago  3h25m ago
fee74115  a61ef171  controller  6        run      running  3h26m ago  3h25m ago

使用 Ceph 块设备

创建 rbd 镜像

ceph-csi 需要 cephx 凭据才能与 Ceph 集群通信。使用新创建的 Nomad 用户 ID 和 cephx 密钥生成一个类似于下面示例的 ceph-volume.hcl 文件

id = "ceph-mysql"
name = "ceph-mysql"
type = "csi"
plugin_id = "ceph-csi"
capacity_max = "200G"
capacity_min = "100G"

capability {
  access_mode     = "single-node-writer"
  attachment_mode = "file-system"
}

secrets {
  userID  = "admin"
  userKey = "AQAlh9Rgg2vrDxAARy25T7KHabs6iskSHpAEAQ=="
}

parameters {
  clusterID = "b9127830-b0cc-4e34-aa47-9d1a2e9949a8"
  pool = "nomad"
  imageFeatures = "layering"
  mkfsOptions = "-t ext4"
}

生成 ceph-volume.hcl 文件后,创建卷

nomad volume create ceph-volume.hcl

将 rbd 镜像与容器一起使用

作为使用 rbd 镜像与容器一起使用的练习,修改 Hashicorp nomad stateful 示例。

生成一个类似于下面示例的 mysql.nomad 文件

job "mysql-server" {
  datacenters = ["dc1"]
  type        = "service"
  group "mysql-server" {
    count = 1
    volume "ceph-mysql" {
      type      = "csi"
      attachment_mode = "file-system"
      access_mode     = "single-node-writer"
      read_only = false
      source    = "ceph-mysql"
    }
    network {
      port "db" {
        static = 3306
      }
    }
    restart {
      attempts = 10
      interval = "5m"
      delay    = "25s"
      mode     = "delay"
    }
    task "mysql-server" {
      driver = "docker"
      volume_mount {
        volume      = "ceph-mysql"
        destination = "/srv"
        read_only   = false
      }
      env {
        MYSQL_ROOT_PASSWORD = "password"
      }
      config {
        image = "hashicorp/mysql-portworx-demo:latest"
        args  = ["--datadir", "/srv/mysql"]
        ports = ["db"]
      }
      resources {
        cpu    = 500
        memory = 1024
      }
      service {
        name = "mysql-server"
        port = "db"
        check {
          type     = "tcp"
          interval = "10s"
          timeout  = "2s"
        }
      }
    }
  }
}

启动作业

nomad job run mysql.nomad

检查作业状态

$ nomad job status mysql-server
...
Status        = running
...
Allocations
ID        Node ID   Task Group    Version  Desired  Status   Created  Modified
38070da7  9ad01c63  mysql-server  0        run      running  6s ago   3s ago

要检查数据是否持久,请修改数据库,清除作业,然后使用同一文件创建它。将使用(实际上是重新使用)相同的 RBD 镜像。

由 Ceph 基金会为您呈现

Ceph 文档是由非营利性 Ceph 基金会 资助和托管的社区资源。如果您希望支持这项工作和我们的其他努力,请考虑 立即加入