使用 KRBD 在 Kubernetes 上为您的容器提供持久存储

shan

Bring persistent storage for your containers with KRBD on Kubernetes

使用 RBD 设备为您的容器提供持久存储。这项工作由我的同事 Huamin Chen 发起。我想借此机会感谢他与我们一起进行的故障排除会议。为您的容器使用持久卷至关重要,容器可以是短暂的,因为它们是不可变的。如果它们在一个机器上损坏,它们可以在另一个主机上启动,而不会出现任何问题。这里唯一的问题是,我们需要确保与此容器一起的数据无论它去哪里都会跟随它。这正是我们希望通过此实现实现的目标。

先决条件

本文档假定您的 Kubernetes 环境已启动并正在运行。首先在您的主机上安装 Ceph

$ sudo yum install -y ceph-common

W 重要提示:ceph-common 的版本必须 >= 0.87。

设置您的 Ceph 环境

$ sudo docker run -d \
--net=host \
-v /var/lib/ceph:/var/lib/ceph \
-v /etc/ceph:/etc/ceph \
-e MON_IP=192.168.0.1 \
-e CEPH_NETWORK=192.168.0.0/24 \
ceph/demo

Kubernetes 不会假定以下几个操作:

  • RBD 卷创建
  • 此卷上的文件系统

所以我们先做这些

$ sudo rbd create foo -s 1024
$ sudo rbd map foo
/dev/rbd0
$ sudo mkfs.ext4 /dev/rbd0
$ sudo rbd unmap /dev/rbd0

配置 Kubernetes

首先,我们克隆 Kubernetes 存储库以获取一些方便的文件示例

$ git clone https://github.com/GoogleCloudPlatform/kubernetes.git
$ cd kubernetes/examples/rbd

获取您的 ceph.admin 密钥并将其编码为 base64

$ sudo ceph auth get-key client.admin
AQBAMo1VqE1OMhAAVpERPcyQU5pzU6IOJ22x1w==

$ echo "AQBAMo1VqE1OMhAAVpERPcyQU5pzU6IOJ22x1w==" | base64
QVFCQU1vMVZxRTFPTWhBQVZwRVJQY3lRVTVwelU2SU9KMjJ4MXc9PQo=

R 注意:使用 client.admin 密钥不是强制性的,您可以使用任何具有给定池的适当权限的密钥。

使用 base64 密钥编辑您的 ceph-secret.yml

apiVersion: v1
kind: Secret
metadata:
  name: ceph-secret
data:
  key: QVFCQU1vMVZxRTFPTWhBQVZwRVJQY3lRVTVwelU2SU9KMjJ4MXc9PQo=

将您的密钥添加到 Kubernetes

$ kubectl create -f secret/ceph-secret.yaml
$ kubectl get secret
NAME                  TYPE                                  DATA
ceph-secret           Opaque                                1

现在,我们编辑我们的 rbd-with-secret.json pod 文件。此文件描述您的 pod 的内容

{
    "apiVersion": "v1beta3",
    "id": "rbdpd2",
    "kind": "Pod",
    "metadata": {
        "name": "rbd2"
    },
    "spec": {
        "containers": [
            {
                "name": "rbd-rw",
                "image": "kubernetes/pause",
                "volumeMounts": [
                    {
                        "mountPath": "/mnt/rbd",
                        "name": "rbdpd"
                    }
                ]
            }
        ],
        "volumes": [
            {
                "name": "rbdpd",
                "rbd": {
                    "monitors": [
                                                        "192.168.0.1:6789"
                                 ],
                    "pool": "rbd",
                    "image": "foo",
                    "user": "admin",
                    "secretRef": {
                                                  "name": "ceph-secret"
                                         },
                    "fsType": "ext4",
                    "readOnly": true
                }
            }
        ]
    }
}

相关的部分是:

  • mountPath:RBD 镜像挂载到的位置,此挂载点 必须 存在
  • monitors:监控器的地址(您可以拥有任意数量的监控器)
  • pool:用于存储您的镜像的池
  • image:镜像名称
  • secretRef:密钥名称
  • fsType:镜像的文件系统类型

现在是启动您的 pod 的时候了

$ kubectl create -f rbd-with-secret.json
$ kubectl get pods
NAME      READY     REASON    RESTARTS   AGE
rbd2      1/1       Running   0          1m

检查正在运行的容器

$ docker ps
CONTAINER ID        IMAGE                                  COMMAND             CREATED             STATUS              PORTS               NAMES
61e12752d0e9        kubernetes/pause:latest                "/pause"            18 minutes ago      Up 18 minutes                           k8s_rbd-rw.1d89132d_rbd2_default_bd8b2bb0-1c0d-11e5-9dcf-b4b52f63c584_f9954e16
e7b1c2645e8f        gcr.io/google_containers/pause:0.8.0   "/pause"            18 minutes ago      Up 18 minutes                           k8s_POD.e4cc795_rbd2_default_bd8b2bb0-1c0d-11e5-9dcf-b4b52f63c584_ac64e07c
e9dfc079809f        ceph/demo:latest                       "/entrypoint.sh"    3 hours ago         Up 3 hours                              mad_ardinghelli

一切似乎工作正常,让我们检查 Kubernetes 主机上的设备状态

$ sudo rbd showmapped
id pool image snap device
0  rbd  foo   - /dev/rbd0

该镜像已映射,现在我们检查该镜像挂载到哪里

$ mount |grep kube
/dev/rbd0 on /var/lib/kubelet/plugins/kubernetes.io/rbd/rbd/rbd-image-foo type ext4 (ro,relatime,stripe=1024,data=ordered)
/dev/rbd0 on /var/lib/kubelet/pods/bd8b2bb0-1c0d-11e5-9dcf-b4b52f63c584/volumes/kubernetes.io~rbd/rbdpd type ext4 (ro,relatime,stripe=1024,data=ordered)

进一步的工作和已知问题

当前的实现在这里,很高兴看到我们合并了这样的东西。将来更容易跟进这项工作。“v2”将简化操作员的生活,因为他们不需要预先填充 RBD 镜像和文件系统。

目前有一个错误,如果挂载点不存在,pod 创建将失败。这在 Kubernetes 0.20 中已修复。

我希望您能像我一样享受这个:)