与Ceph RBD关联,实现Kubernetes持久化存储

Posted DBAplus社群

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了与Ceph RBD关联,实现Kubernetes持久化存储相关的知识,希望对你有一定的参考价值。


团队介绍

360运维开发团队作为一支技术导向型团队,为HULK云平台在容器化、微服务、AIOPS、自动化运维等领域积累了丰富经验。更多技术好文欢迎访问团队技术博客:www.opsdev.cn


笔者最近在调研Kubernetes持久化存储,准备写一两篇关于这方面的文章,一是作为记录,二是可以给需要的同学作为一个参考。


Kubernetes存储的应用场景


Kubernetes中对于存储的使用主要集中在以下几个方面:


  • 服务配置文件读取、密钥管理等;

  • 服务的存储状态、数据存取等;

  • 不同服务或应用程序之间共享数据。


Kubernetes持久化概念


Kubernetes使用两种API资源来管理存储,分别是PersistentVolume和PersistentVolumeClaim,下面分别介绍下这两种资源的概念:


PersistentVolume(简称PV):由管理员设置的存储,它是集群的一部分。就像节点(Node)是集群中的资源一样,PV也是集群中的资源。它包含存储类型,存储大小和访问模式。它的生命周期独立于Pod,例如当使用它的Pod销毁时对PV没有影响。


PersistentVolumeClaim(简称PVC): 是用户存储的请求,它和Pod类似。Pod消耗Node资源,PVC消耗PV资源。Pod可以请求特定级别的资源(CPU和MEM)。PVC可以请求特定大小和访问模式的PV。


Kubernetes可以使用三种方式来访问存储资源:


  • 直接访问


该种方式移植性比较差,可扩展能力差,把Volume的基本信息完全暴露给用户,有安全隐患。

与Ceph RBD关联,实现Kubernetes持久化存储


  • 静态PV


集群管理员创建一些PV。它们带有可供集群用户使用的实际存储的细节,之后便可用于PVC消费。


注意: 这种方式请求的PVC必须要与管理员创建的PV保持一致,如:存储大小和访问模式,否则不会将PVC绑定到PV上。


与Ceph RBD关联,实现Kubernetes持久化存储


  • 动态PV


当管理员创建的静态PV都不匹配用户的PVC时,集群可以使用动态的为PVC创建卷,此配置基于StorageClass。


PVC请求存储类(StorageClass),且管理员必须要创建并配置该StorageClass,该StorageClass才能进行动态的创建。

与Ceph RBD关联,实现Kubernetes持久化存储

Kubernetes数据持久化demo


好了,上面已经对Kubernetes持久化要用的概念进行了介绍,但是这些只是基本的概念,如果想要系统的了解请看官方文档。


在实验前,你需要有一个可以使用的Kubernetes和Ceph集群,这里不介绍这两个集群的搭建了。 进行实验前最好先看下官方文档persistent-volumeshttps://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistent-volumes)


实验环境


Kubernetes集群版本:1.9.0 

Ceph集群版本:10.2.10


安装Ceph-common包


在Kubernetes集群的所有Node上安装Ceph-common包,具体的操作指令如下:


# yum install -y ceph-common


静态PV


  • 创建Ceph secret


在Ceph mon节点运行ceph auth get-key client.admin命令获取admin的key。定义一个Ceph secret文件。


apiVersion: v1

kind: Secret

metadata:

   name: ceph-secret

data:

   key: QVFBOFF2SlZheUJQRVJBQWgvS2cwT1laQUhPQno3akZwekxxdGc9PQ==


注意:文件中的key需要在Ceph mon节点使用ceph auth get-key client.admin | base64命令对获取的key进行base64。


保存定义的文件,如ceph-secret.yaml,之后创建一个secret:


# kubectl create -f ceph-secret.yaml 

secret "ceph-secret" created


  • 创建Persistent Volume


创建一个PV对象,使用下面文件的定义:


apiVersion: v1

kind: PersistentVolume

metadata:

   name: ceph-pv 

spec:

   capacity:

      storage: 2Gi 

   accessModes:

      - ReadWriteOnce 

   rbd: 

     monitors: 

         - mon-hosts:6789

     pool: rbd 

     image: ceph-image

     user: admin

     secretRef:

       name: ceph-secret 

     fsType: ext4 

     readOnly: false

  persistentVolumeReclaimPolicy: Recycle


注意: 我们这里直接使用了Ceph默认的pool rbd,由于文件中使用了Ceph-image,所以需要在Ceph集群中创建该镜像。rbd create ceph-image -s 128


保存定义的PV文件,如Ceph-pv.yaml,并创建一个PV:


# kubectl create -f ceph-pv.yaml

persistentvolume "ceph-pv" created


查看PV的状态是否正常,如果获取的状态是Available则说明该PV处于可用状态,并且没有被PVC绑定。


与Ceph RBD关联,实现Kubernetes持久化存储


  • 创建Persistent Volume Claim


PVC需要指定访问模式和存储的大小,当前只支持这两个属性,一个PVC绑定到一个PV上。一旦PV被绑定到PVC上就不能被其它的PVC所绑定。它们是一对一的关系。但是多个Pod可以使用同一个PVC进行卷的挂载。


PVC的定义文件如下:

kind: PersistentVolumeClaim

apiVersion: v1

metadata:

  name: ceph-claim

spec:

  accessModes:

    - ReadWriteOnce

  resources:

    requests:

      storage: 2Gi


保存定义的文件,并基于该文件创建PVC,并检查其状态,如果状态为Bound则说明该PVC已经绑定到PV,如果状态为Pending或Failed则表示PVC绑定PV失败,可用通过查看PVC事件或者Kubernetes各个组件日志进行错误排查。


#  kubectl create -f task-claim.yaml

persistentvolumeclaim "ceph-claim" created

与Ceph RBD关联,实现Kubernetes持久化存储


  • 创建Pod


定义一个Pod,在Pod里面启动一个container,并使用PVC去挂载Ceph RBD卷为读写模式。


apiVersion: v1

kind: Pod

metadata:

   name: ceph-pod2           

spec:

   containers:

   - name: ceph-busybox

     image: busybox          

     command: ["sleep", "60000"]

     volumeMounts:

     - name: ceph-vol1       

       mountPath: /usr/share/busybox 

       readOnly: false

   volumes:

   - name: ceph-vol1         

     persistentVolumeClaim:

       claimName: ceph-claim


保存Pod的定义文件,如: ceph-pod.yaml,并创建该Pod。之后查看Pod的状态,如果Running则表示卷挂载成功,Pod正常运行。 这样便可以做个简单的操作,进行到该Pod的容器中,向/usr/share/busybox 目录写入一些数据,之后删除该Pod,再创建一个新的Pod,看之前的数据是否还存在。


#kubectl create -f ceph-pod.yaml 

pod "ceph-pod2" created


与Ceph RBD关联,实现Kubernetes持久化存储


动态PV


  • 创建RBD pool


虽然Ceph提供了默认的pool rbd,但是建议创建一个新的pool为Kubernetes持久化使用,在Ceph的monitors节点创建一个名为kube的pool。


# ceph osd pool create kube 1024

# ceph auth get-or-create client.kube mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=kube' -o ceph.client.kube.keyring


  • 创建Ceph secret


与静态创建的Ceph-secret是同一个,这里就不重复创建。


  • 创建Kube用户的Ceph secret


在Ceph monitors节点运行命令ceph auth get-key client.kube获取kube用户的key,并对该用户key进行base64用于下面的文件。


apiVersion: v1

kind: Secret

metadata:

  name: ceph-kube-secret

  namespace: default

data:

  key: QVFCbEV4OVpmaGJtQ0JBQW55d2Z0NHZtcS96cE42SW1JVUQvekE9PQ== 

type:

  kubernetes.io/rbd


保存定义的Ceph secret文件,如ceph-kube-secret.yaml。执行如下命令创建secret:


# kubectl create -f ceph-kube-secret.yaml 

secret "ceph-kube-secret" created


查看secret是否创建成功。

与Ceph RBD关联,实现Kubernetes持久化存储


  • 创建动态RBD StorageClass


在创建StorageClass资源前,先介绍下StorageClass的概念:StorageClass 为管理员提供了描述存储 class 的方法。不同的 class 可能会映射到不同的服务质量等级或备份策略,或由群集管理员确定的任意策略。 Kubernetes 本身不清楚各种 class 代表的什么。这个概念在其他存储系统中有时被称为“配置文件”。StorageClass不仅仅使用与ceph RBD还可以用于Cinder,NFS,Glusterfs等等。


好了,下面我们来创一个动态的storage class。定义文件如下:


kind: StorageClass

metadata:

  name: dynamic

  annotations:

     storageclass.beta.kubernetes.io/is-default-class: "true"

provisioner: kubernetes.io/rbd

parameters:

  monitors: 10.139.206.209:6789

  adminId: admin

  adminSecretName: ceph-secret

  adminSecretNamespace: kube-system

  pool: kube

  userId: kube

  userSecretName: ceph-kube-secret

  fsType: ext4

  imageFormat: "1"


保存文件,并创建storage class。


# kubectl create -f rbd-storage-class.yaml 

storageclass "dynamic" created


检查storage class是否创建成功。

与Ceph RBD关联,实现Kubernetes持久化存储

  • 创建Persistent Volume Claim


具体的描述细节请看创建静态PV时,对PVC的描述,或查看官方文档。现在我们直接定义PVC文件。


kind: PersistentVolumeClaim

apiVersion: v1

metadata:

   name: ceph-claim

spec:

   accessModes:

     rs ReadOnlyMany

   resources:

     requests:

       storage: 1Gi


保存定义的文件,并创建该PVC。


# kubectl create -f static-ceph-pvc.yaml 

persistentvolumeclaim "ceph-claim" created


检查PVC是否创建成功,并查看PVC的状态,如果PVC的状态为Bound则表示已经绑定到PV了。


这里详细的说下,在Kubernetes中一个指定访问模式和存储大小的PVC只能绑定到指定访问权限和存储大小的PV上,但是这样需要集群管理员手动的创建PV,就很麻烦。


为了减少管理员的工作,管理员可以创建一个storageclass的资源,当指定规格的PVC请求的时候,StorageClass会动态的给该PVC提供一个PV。 


我们查看下该PVC是否被该StorageClass绑定一个符合需求的PV上。我们执行下面的命令:


与Ceph RBD关联,实现Kubernetes持久化存储


我们看到ceph-claim这个PVC已经绑定到了pvc-c32aca7e-38cd-11e8-af69-f0921c10a7bc这个PV,而该PV是由名为dynamic的storageclass动态创建的。


  • 创建Pod


我们定义一个Pod来将刚刚创建的PVC挂载到该Pod的容器中去。我们定义的Pod的文件内容如下:


apiVersion: v1

kind: Pod

metadata:

   name: static-ceph-pod2

spec:

   containers:

   - name: ceph-busybox

     image: busybox

     command: ["sleep", "60000"]

     volumeMounts:

     - name: ceph-vol1

       mountPath: /usr/share/busybox

       readOnly: false

   volumes:

   - name: ceph-vol1

     persistentVolumeClaim:

       claimName: ceph-claim


保存定义Pod的文件,我们创建一个Pod:

与Ceph RBD关联,实现Kubernetes持久化存储

ok,我们已经成功的将该PVC挂载到了Pod中的容器中。


总结


好了,到此为止,我们已经介绍了如何将Kubernetes与Ceph RBD关联起来,实现将被 Kubernetes编排的服务数据持久化。我们分别对静态PV和动态PV分别进行了实验,但是Ceph RBD也有自己的缺点。


在说明Ceph RBD缺点之前,先介绍下PV的访问模式,PV支持三种访问模式:


  • ReadWriteOnce——该卷可以被单个节点以读/写模式挂载

  • ReadOnlyMany——该卷可以被多个节点以只读模式挂载

  • ReadWriteMany——该卷可以被多个节点以读/写模式挂载


但是Ceph RBD只能进行单节点读写或多节点读,不能进行多节点读写,如下图所示:


与Ceph RBD关联,实现Kubernetes持久化存储


但是有的业务可能需要多节点读写的功能,正好Cephfs解决了这个问题,下篇文章笔者会介绍下Cephfs如何与Kubernetes结合实现数据持久化存储。


参考链接:

https://www.kubernetes.org.cn/3462.html

https://kubernetes.io/docs/concepts/storage/persistent-volumes/

https://github.com/kubernetes-incubator/external-storage/tree/master/ceph/rbd/examples



近期热文



最新活动

以上是关于与Ceph RBD关联,实现Kubernetes持久化存储的主要内容,如果未能解决你的问题,请参考以下文章

ceph rbd 找回 pvc

kubeadm k8s配置 ceph rbd存储 类型storageClass

Statefulset+storageclass+ceph

ceph--Ceph RBD 接口和工具

k8s通过rbd使用ceph,pvc在线扩容

KubeSphere使用rbd-csi创建快照