带有Ceph RBD的Kubernetes的持久存储
如何使用Ceph RBD进行Kubernetes动态持久卷供应?
Kubernetes(K8S)是一种用于自动化部署,扩展和管理Docker应用程序的开源系统。
在Kubernetes中部署有状态应用程序时的关键要求之一是数据持久性。
在本教程中,我们将查看如何在kubernetes上创建存储类,这些存储类使用RBD(Ceph块设备)从外部Ceph群集提供持久卷。
Ceph块设备是瘦的,可调整大小的,并在Ceph集群中划分的多个OSD中的数据。
Ceph阻止设备利用RadoS功能,例如快照,复制和一致性。
Ceph的Rados块设备(RBD)使用内核模块或者Librbd库与OSD交互。
在开始此练习之前,我们应该有一个工作的外部Ceph集群。
使用Ceph的大多数Kubernetes部署将涉及使用车。
本教程假定我们拥有一个部署的Ceph Ansible,Ceph部署或者手动部署的Ceph存储群集。
第1步:在Kubernetes上部署Ceph Profisioner
登录Kubernetes群集,并创建一个列表文件,用于部署RBD Provisioner,这是Kubernetes 1.5+的无树动态配置文件。
$vim ceph-rbd-provisioner.yml
将以下内容添加到文件中。
注意我们的部署使用RBAC,因此我们将在创建服务帐户和部署Ceph RBD Provisioner之前创建群集角色和绑定。
-- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: rbd-provisioner namespace: kube-system rules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["create", "update", "patch"] - apiGroups: [""] resources: ["services"] resourceNames: ["kube-dns","coredns"] verbs: ["list", "get"] - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"] -- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: rbd-provisioner namespace: kube-system subjects: - kind: ServiceAccount name: rbd-provisioner namespace: kube-system roleRef: kind: ClusterRole name: rbd-provisioner apiGroup: rbac.authorization.k8s.io -- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: rbd-provisioner namespace: kube-system rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get"] - apiGroups: [""] resources: ["endpoints"] verbs: ["get", "list", "watch", "create", "update", "patch"] -- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: rbd-provisioner namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: rbd-provisioner subjects: - kind: ServiceAccount name: rbd-provisioner namespace: kube-system -- apiVersion: apps/v1 kind: Deployment metadata: name: rbd-provisioner namespace: kube-system spec: replicas: 1 selector: matchLabels: app: rbd-provisioner strategy: type: Recreate template: metadata: labels: app: rbd-provisioner spec: containers: - name: rbd-provisioner image: "quay.io/external_storage/rbd-provisioner:latest" env: - name: PROVISIONER_NAME value: ceph.com/rbd serviceAccount: rbd-provisioner
应用文件以创建资源。
$kubectl apply -f ceph-rbd-provisioner.yml clusterrole.rbac.authorization.k8s.io/rbd-provisioner created clusterrolebinding.rbac.authorization.k8s.io/rbd-provisioner created role.rbac.authorization.k8s.io/rbd-provisioner created rolebinding.rbac.authorization.k8s.io/rbd-provisioner created deployment.apps/rbd-provisioner created
确认RBD卷配置器POD正在运行。
$kubectl get pods -l app=rbd-provisioner -n kube-system NAME READY STATUS RESTARTS AGE rbd-provisioner-75b85f85bd-p9b8c 1/1 Running 0 3m45s
第2步:获取Ceph Admin密钥并在Kubernetes上创建秘密
登录Ceph群集并获取rbd配置程序使用的管理员密钥。
$sudo ceph auth get-key client.admin
保存由上面的命令打印出来的管理员用户键的值。
我们将在Kubernetes中添加密钥作为秘密。
$kubectl create secret generic ceph-admin-secret \ --type="kubernetes.io/rbd" \ --from-literal=key='<key-value>' \ --namespace=kube-system
其中<key-value>是ceph admin键。
我们可以使用以下命令确认创建。
$kubectl get secrets ceph-admin-secret -n kube-system NAME TYPE DATA AGE ceph-admin-secret kubernetes.io/rbd 1 5m
第3步:为Kubernetes和客户端键创建Ceph池
接下来是为Kubernetes创建一个新的Cepho池。
$sudo ceph ceph osd pool create <pool-name> <pg-number> # Example $sudo ceph ceph osd pool create k8s 100
有关更多详细信息,请选中我们的教程:在Ceph存储群集中创建一个池
然后创建一个新的客户端密钥,可以访问创建的池。
$sudo ceph auth add client.kube mon 'allow r' osd 'allow rwx pool=<pool-name>' # Example $sudo ceph auth add client.kube mon 'allow r' osd 'allow rwx pool=k8s'
其中k8s是ceph中创建的池的名称。
然后,我们可以将池与应用程序关联并初始化。
sudo ceph osd pool application enable <pool-name> rbd sudo rbd pool init <pool-name>
获取ceph上的客户端密钥。
$sudo ceph auth get-key client.kube
在Kubernetes上创建客户机密
kubectl create secret generic ceph-k8s-secret \ --type="kubernetes.io/rbd" \ --from-literal=key='<key-value>' \ --namespace=kube-system
其中<key-value>是Ceph客户端密钥。
第4步:创建RBD存储类
StorageClass提供了一种方法来描述我们在Kubernetes中提供的"类别"的存储空间。
我们将创建一个名为Ceph-RBD的StorageClass。
$vim ceph-rbd-sc.yml
要添加到文件中的内容:
-- kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: ceph-rbd provisioner: ceph.com/rbd parameters: monitors: 10.10.10.11:6789, 10.10.10.12:6789, 10.10.10.13:6789 pool: k8s-uat adminId: admin adminSecretNamespace: kube-system adminSecretName: ceph-admin-secret userId: kube userSecretNamespace: kube-system userSecretName: ceph-k8s-secret imageFormat: "2" imageFeatures: layering
其中:Ceph-RBD是要创建的StorageClass的名称.10.10.10.11,10.10.10.12和10.10.10.13是Ceph监视器的IP地址。
我们可以用命令列出它们:
$sudo ceph -s cluster: id: 7795990b-7c8c-43f4-b648-d284ef2a0aba health: HEALTH_OK services: mon: 3 daemons, quorum cephmon01,cephmon02,cephmon03 (age 32h) mgr: cephmon01(active, since 30h), standbys: cephmon02 mds: cephfs:1 {0=cephmon01=up:active} 1 up:standby osd: 9 osds: 9 up (since 32h), 9 in (since 32h) rgw: 3 daemons active (cephmon01, cephmon02, cephmon03) data: pools: 8 pools, 618 pgs objects: 250 objects, 76 KiB usage: 9.6 GiB used, 2.6 TiB/2.6 TiB avail pgs: 618 active+clean
在使用正确的Ceph监视器的正确值修改文件后,应用配置:
$kubectl apply -f ceph-rbd-sc.yml storageclass.storage.k8s.io/ceph-rbd created
列表可用StorageClasses:
kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE ceph-rbd ceph.com/rbd Delete Immediate false 17s cephfs ceph.com/cephfs Delete Immediate false 18d
第5步:在Kubernetes上创建测试索赔和POD
要确认一切正常工作,让我们创建一个测试持久卷索赔。
$vim ceph-rbd-claim.yml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: ceph-rbd-claim1 spec: accessModes: - ReadWriteOnce storageClassName: ceph-rbd resources: requests: storage: 1Gi
应用列表文件以创建索赔。
$kubectl apply -f ceph-rbd-claim.yml persistentvolumeclaim/ceph-rbd-claim1 created
如果它成功绑定,则应显示绑定状态。
$kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE ceph-rbd-claim1 Bound pvc-c6f4399d-43cf-4fc1-ba14-cc22f5c85304 1Gi RWO ceph-rbd 43s
很好!..我们可以在Ceph RBD后端创建动态持久卷声明。
请注意,我们在索赔之前,我们不必手动创建持久卷。
多么酷啊?
..
然后,我们可以使用我们创建的索赔部署测试Pod。
首先创建一个文件以保存数据:
$vim rbd-test-pod.yaml
添加:
-- kind: Pod apiVersion: v1 metadata: name: rbd-test-pod spec: containers: - name: rbd-test-pod image: busybox command: - "/bin/sh" args: - "-c" - "touch /mnt/RBD-SUCCESS && exit 0 || exit 1" volumeMounts: - name: pvc mountPath: "/mnt" restartPolicy: "Never" volumes: - name: pvc persistentVolumeClaim: claimName: ceph-rbd-claim1
创建Pods:
$kubectl apply -f rbd-test-pod.yaml pod/rbd-test-pod created
如果我们描述了POD,我们将看到卷的成功附件。
$kubectl describe pod rbd-test-pod ..... vents: Type Reason Age From Message ---- ------ ---- ---- ------ Normal Scheduled <unknown> default-scheduler Successfully assigned default/rbd-test-pod to rke-worker-02 Normal SuccessfulAttachVolume 3s attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-c6f4399d-43cf-4fc1-ba14-cc22f5c85304"