使用 KRBD 在 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 中已修复。
我希望您能像我一样享受这个:)