基于Ceph的存储连接到Kubernetes集群的实际示例

容器存储接口(CSI)是 Kubernetes 和存储系统之间的统一接口。 我们已经简单地讨论过了 告诉,今天我们将仔细研究 CSI 和 Ceph 的组合:我们将展示如何 连接 Ceph 存储 到 Kubernetes 集群。
为了便于理解,本文提供了真实但稍微简化的示例。 我们不考虑安装和配置Ceph和Kubernetes集群。

您想知道它是如何工作的吗?

基于Ceph的存储连接到Kubernetes集群的实际示例

因此,您已经拥有一个触手可及的 Kubernetes 集群,例如已部署: 库贝喷雾。 附近有一个 Ceph 集群正在运行 - 您也可以安装它,例如,使用以下命令 一套剧本。 我希望无需提及,为了进行生产,它们之间必须有一个带宽至少为 10 Gbit/s 的网络。

如果你拥有这一切,我们就出发吧!

首先,让我们转到一个 Ceph 集群节点并检查一切是否正常:

ceph health
ceph -s

接下来,我们将立即为 RBD 磁盘创建一个池:

ceph osd pool create kube 32
ceph osd pool application enable kube rbd

让我们继续讨论 Kubernetes 集群。 首先,我们将为 RBD 安装 Ceph CSI 驱动程序。 我们将按照预期通过 Helm 安装。
我们添加一个带有图表的存储库,我们获得 ceph-csi-rbd 图表的一组变量:

helm repo add ceph-csi https://ceph.github.io/csi-charts
helm inspect values ceph-csi/ceph-csi-rbd > cephrbd.yml

现在您需要填写 cephrbd.yml 文件。 为此,请找出 Ceph 中监视器的集群 ID 和 IP 地址:

ceph fsid  # так мы узнаем clusterID
ceph mon dump  # а так увидим IP-адреса мониторов

我们将获得的值输入到cephrbd.yml文件中。 同时,我们允许创建 PSP 策略(Pod 安全策略)。 部分选项 节点插件 и 供应商 已在文件中,可以按如下所示更正它们:

csiConfig:
  - clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"
    monitors:
      - "v2:172.18.8.5:3300/0,v1:172.18.8.5:6789/0"
      - "v2:172.18.8.6:3300/0,v1:172.18.8.6:6789/0"
      - "v2:172.18.8.7:3300/0,v1:172.18.8.7:6789/0"

nodeplugin:
  podSecurityPolicy:
    enabled: true

provisioner:
  podSecurityPolicy:
    enabled: true

接下来,我们剩下的就是将图表安装到 Kubernetes 集群中。

helm upgrade -i ceph-csi-rbd ceph-csi/ceph-csi-rbd -f cephrbd.yml -n ceph-csi-rbd --create-namespace

太好了,RBD 驱动程序工作了!
让我们在 Kubernetes 中创建一个新的 StorageClass。 这又需要对 Ceph 进行一些修改。

我们在 Ceph 中创建一个新用户并授予他写入池的权限 库贝:

ceph auth get-or-create client.rbdkube mon 'profile rbd' osd 'profile rbd pool=kube'

现在让我们看看访问密钥仍然存在:

ceph auth get-key client.rbdkube

该命令将输出如下内容:

AQCO9NJbhYipKRAAMqZsnqqS/T8OYQX20xIa9A==

让我们将此值添加到 Kubernetes 集群中的 Secret - 我们需要它的地方 用户密钥:

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: ceph-csi-rbd
stringData:
  # Значения ключей соответствуют имени пользователя и его ключу, как указано в
  # кластере Ceph. ID юзера должен иметь доступ к пулу,
  # указанному в storage class
  userID: rbdkube
  userKey: <user-key>

我们创造了我们的秘密:

kubectl apply -f secret.yaml

接下来,我们需要一个 StorageClass 清单,如下所示:

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
   clusterID: <cluster-id>
   pool: kube

   imageFeatures: layering

   # Эти секреты должны содержать данные для авторизации
   # в ваш пул.
   csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
   csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-rbd
   csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
   csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-rbd
   csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
   csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-rbd

   csi.storage.k8s.io/fstype: ext4

reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
  - discard

需要填写 簇ID,我们团队已经了解到了 头孢夫西德,并将此清单应用到 Kubernetes 集群:

kubectl apply -f storageclass.yaml

为了检查集群如何协同工作,让我们创建以下 PVC(持久卷声明):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: csi-rbd-sc

让我们立即看看 Kubernetes 如何在 Ceph 中创建请求的卷:

kubectl get pvc
kubectl get pv

一切似乎都很棒! 这在 Ceph 方面看起来是什么样的?
我们获取池中卷的列表并查看有关卷的信息:

rbd ls -p kube
rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653  # тут, конечно же, будет другой ID тома, который выдала предыдущая команда

现在让我们看看如何调整 RBD 卷的大小。
将 pvc.yaml 清单中的卷大小更改为 2Gi 并应用它:

kubectl apply -f pvc.yaml

让我们等待更改生效并再次查看卷大小。

rbd -p kube info csi-vol-eb3d257d-8c6c-11ea-bff5-6235e7640653

kubectl get pv
kubectl get pvc

我们看到PVC的尺寸没有变化。 要找出原因,您可以查询 Kubernetes 以获取 PVC 的 YAML 描述:

kubectl get pvc rbd-pvc -o yaml

问题是这样的:

消息:等待用户(重新)启动 Pod 以完成节点上卷的文件系统大小调整。 类型:FileSystemResizePending

也就是说,磁盘增长了,但其上的文件系统却没有增长。
要扩展文件系统,您需要安装卷。 在我国,目前还没有以任何方式使用所创造的 PVC/PV。

我们可以创建一个测试 Pod,例如这样:

---
apiVersion: v1
kind: Pod
metadata:
  name: csi-rbd-demo-pod
spec:
  containers:
    - name: web-server
      image: nginx:1.17.6
      volumeMounts:
        - name: mypvc
          mountPath: /data
  volumes:
    - name: mypvc
      persistentVolumeClaim:
        claimName: rbd-pvc
        readOnly: false

现在让我们看看 PVC:

kubectl get pvc

尺寸变了,一切都很好。

在第一部分中,我们使用 RBD 块设备(它代表 Rados 块设备),但如果不同的微服务需要同时使用该磁盘,则无法完成此操作。 CephFS 更适合处理文件而不是磁盘映像。
使用 Ceph 和 Kubernetes 集群的示例,我们将配置 CSI 和其他必要的实体以与 CephFS 配合使用。

让我们从新的 Helm 图表中获取我们需要的值:

helm inspect values ceph-csi/ceph-csi-cephfs > cephfs.yml

您再次需要填写 cephfs.yml 文件。 和以前一样,Ceph 命令将提供帮助:

ceph fsid
ceph mon dump

使用如下值填写文件:

csiConfig:
  - clusterID: "bcd0d202-fba8-4352-b25d-75c89258d5ab"
    monitors:
      - "172.18.8.5:6789"
      - "172.18.8.6:6789"
      - "172.18.8.7:6789"

nodeplugin:
  httpMetrics:
    enabled: true
    containerPort: 8091
  podSecurityPolicy:
    enabled: true

provisioner:
  replicaCount: 1
  podSecurityPolicy:
    enabled: true

请注意,监视器地址以地址:端口的简单形式指定。 为了在节点上挂载 cephfs,这些地址会被传输到内核模块,而内核模块还不知道如何使用 v2 监控协议。
我们更改 httpMetrics 的端口(Prometheus 将去那里监视指标),以便它不会与 Kubespray 安装的 nginx-proxy 冲突。 你可能不需要这个。

在 Kubernetes 集群中安装 Helm Chart:

helm upgrade -i ceph-csi-cephfs ceph-csi/ceph-csi-cephfs -f cephfs.yml -n ceph-csi-cephfs --create-namespace

让我们转到 Ceph 数据存储并在那里创建一个单独的用户。 文档指出 CephFS 配置程序需要集群管理员访问权限。 但我们将创建一个单独的用户 fs 具有有限权利:

ceph auth get-or-create client.fs mon 'allow r' mgr 'allow rw' mds 'allow rws' osd 'allow rw pool=cephfs_data, allow rw pool=cephfs_metadata'

让我们立即查看他的访问密钥,稍后我们将需要它:

ceph auth get-key client.fs

让我们创建单独的 Secret 和 StorageClass。
没什么新鲜的,我们已经在 RBD 的例子中看到了这一点:

---
apiVersion: v1
kind: Secret
metadata:
  name: csi-cephfs-secret
  namespace: ceph-csi-cephfs
stringData:
  # Необходимо для динамически создаваемых томов
  adminID: fs
  adminKey: <вывод предыдущей команды>

应用清单:

kubectl apply -f secret.yaml

现在 - 一个单独的 StorageClass:

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
  clusterID: <cluster-id>

  # Имя файловой системы CephFS, в которой будет создан том
  fsName: cephfs

  # (необязательно) Пул Ceph, в котором будут храниться данные тома
  # pool: cephfs_data

  # (необязательно) Разделенные запятыми опции монтирования для Ceph-fuse
  # например:
  # fuseMountOptions: debug

  # (необязательно) Разделенные запятыми опции монтирования CephFS для ядра
  # См. man mount.ceph чтобы узнать список этих опций. Например:
  # kernelMountOptions: readdir_max_bytes=1048576,norbytes

  # Секреты должны содержать доступы для админа и/или юзера Ceph.
  csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-cephfs
  csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-cephfs
  csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
  csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-cephfs

  # (необязательно) Драйвер может использовать либо ceph-fuse (fuse), 
  # либо ceph kernelclient (kernel).
  # Если не указано, будет использоваться монтирование томов по умолчанию,
  # это определяется поиском ceph-fuse и mount.ceph
  # mounter: kernel
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
  - debug

我们在这里填写一下 簇ID 并适用于 Kubernetes:

kubectl apply -f storageclass.yaml

Проверка

为了进行检查,如前面的示例所示,让我们创建一个 PVC:

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-cephfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: csi-cephfs-sc

并检查 PVC/PV 的存在:

kubectl get pvc
kubectl get pv

如果你想查看 CephFS 中的文件和目录,你可以在某个地方挂载这个文件系统。 例如如下所示。

让我们转到 Ceph 集群节点之一并执行以下操作:

# Точка монтирования
mkdir -p /mnt/cephfs

# Создаём файл с ключом администратора
ceph auth get-key client.admin >/etc/ceph/secret.key

# Добавляем запись в /etc/fstab
# !! Изменяем ip адрес на адрес нашего узла
echo "172.18.8.6:6789:/ /mnt/cephfs ceph name=admin,secretfile=/etc/ceph/secret.key,noatime,_netdev    0       2" >> /etc/fstab

mount /mnt/cephfs

当然,像这样在Ceph节点上安装FS只适合训练目的,这就是我们在我们的程序上所做的 泥浆课程。 我认为没有人会在生产中这样做;意外删除重要文件的风险很高。

最后,让我们检查一下在 CephFS 的情况下如何调整卷大小。 让我们返回 Kubernetes 并编辑 PVC 的清单 - 增加那里的大小,例如,增加到 7Gi。

让我们应用编辑后的文件:

kubectl apply -f pvc.yaml

我们查看挂载的目录,看看配额发生了怎样的变化:

getfattr -n ceph.quota.max_bytes <каталог-с-данными>

要使此命令起作用,您可能需要在系统上安装该软件包 属性.

眼睛害怕,双手都害怕

所有这些咒语和冗长的 YAML 清单表面上看起来很复杂,但实际上,Slurm 的学生很快就掌握了它们的窍门。
在本文中,我们没有深入丛林 - 有相关的官方文档。 如果您对使用 Kubernetes 集群设置 Ceph 存储的详细信息感兴趣,这些链接将会有所帮助:

Kubernetes 使用卷的一般原则
RBD 文档
从Ceph角度整合RBD和Kubernetes
从CSI角度整合RBD和Kubernetes
一般 CephFS 文档
从CSI角度整合CephFS和Kubernetes

在 Slurm 课程上 Kubernetes 基地 您可以更进一步,在 Kubernetes 中部署一个真实的应用程序,该应用程序将使用 CephFS 作为文件存储。 通过 GET/POST 请求,您将能够向 Ceph 传输文件并从 Ceph 接收文件。

如果您对数据存储更感兴趣,请注册 Ceph 的新课程。 当 Beta 测试正在进行时,您可以以折扣价获得该课程,并且您可以影响其内容。

文章作者:Alexander Shvalov,执业工程师 南桥,经过认证的 Kubernetes 管理员、Slurm 课程的作者和开发者。

来源: habr.com