Ceph集群上操作:

创建存储池pool:

ceph osd pool create rbddata 64 64

启用存储池:

ceph osd pool application enable rbddata rbd

初始化存储池:

rbd pool init -p rbddata

创建镜像:

rbd create rbddata/myimg --size 2Gi

查看镜像:

rbd ls -p rbddata -l

创建在k8s上使用的Ceph用户:注意用户名和配置文件的命名规律,下面创建的用户为k8s,这个文件是要分发给k8s的各个节点的,同时一起分发的还有配置文件ceph.conf。

ceph auth get-or-create client.k8s mon 'allow r' osd 'allow * pool=rbddata' > /etc/ceph/ceph.client.k8s.keyring

使用k8s账号查看镜像:

rbd --user=k8s ls -p rbddata -l



k8s集群上的操作:

ceph.repo

[Ceph]
name=Ceph packages for $basearch
baseurl=https://mirrors.aliyun.com/ceph/rpm-mimic/el7/$basearch
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc
 
[Ceph-noarch]
name=Ceph noarch packages
baseurl=https://mirrors.aliyun.com/ceph/rpm-mimic/el7/noarch
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc
 
[ceph-source]
name=Ceph source packages
baseurl=https://mirrors.aliyun.com/ceph/rpm-mimic/el7/SRPMS
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc

准备工作:

ansible k8s -m copy -a 'src=/root/ceph.repo dest=/etc/yum.repos.d/'
ansible k8s -m yum -a 'name=ceph-common'
ansible k8s -m copy -a 'src=/root/ceph.client.k8s.keyring dest=/etc/ceph/'
ansible k8s -m copy -a 'src=/root/ceph.conf dest=/etc/ceph/'
ansible k8s -m command -a 'rbd --user=k8s ls -p rbddata'



Pod使用rbd:

k8s调用keyring文件来使用Ceph中的镜像文件:

apiVersion: v1
kind: Pod
metadata: 
  name: pod-with-rbd-vol
spec:
  containers:
  - name: busybox
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","sleep 360000"]
    volumeMounts:
    - name: rbdpod
      mountPath: /data
  volumes:
  - name: rbdpod
    rbd:
      # 以列表形式给出监控节点的地址,可以是IP或可解析的主机名
      monitors:
      - '192.168.1.60:6789'
      - '192.168.1.61:6789'
      - '192.168.1.62:6789'
      pool: rbddata # 指定使用的存储池
      image: myimg # 指定存储池中的镜像文件
      fsType: ext4 # 自动格式化为指定的文件系统
      readOnly: false # 是否只读
      user: k8s # 连入ceph集群的用户
      keyring: /etc/ceph/ceph.client.k8s.keyring # 对应user的keyring文件路径

报错如下:

RBD image feature set mismatch. You can disable features unsupported by the kernel with "rbd feature disable rbddata/myimg object-map fast-diff deep-flatten".

查看当前的特性features一栏:

]# rbd info rbddata/myimg
rbd image 'myimg':
	size 2 GiB in 512 objects
	order 22 (4 MiB objects)
	id: 2cf6e6b8b4567
	block_name_prefix: rbd_data.2cf6e6b8b4567
	format: 2
	features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
	op_features: 
	flags: 
	create_timestamp: Sun Feb  2 02:45:12 2020

关闭不支持的特性:

rbd feature disable rbddata/myimg object-map fast-diff deep-flatten

再次查看feature:

]# rbd info rbddata/myimg
rbd image 'myimg':
	size 2 GiB in 512 objects
	order 22 (4 MiB objects)
	id: 2cf6e6b8b4567
	block_name_prefix: rbd_data.2cf6e6b8b4567
	format: 2
	features: layering, exclusive-lock
	op_features: 
	flags: 
	create_timestamp: Sun Feb  2 02:45:12 2020

进入Pod使用mount命令可以看到已近挂载。

]# kubectl exec -it pod-with-rbd-vol mount | grep data
/dev/rbd0 on /data type ext4 (rw,relatime,stripe=1024,data=ordered)

查看Pod运行的节点:

kubectl get pods -o wide
NAME               READY   STATUS    RESTARTS   AGE     IP            NODE         NOMINATED NODE   READINESS GATES
pod-with-rbd-vol   1/1     Running   0          8m18s   10.244.0.15   k8s-node01   <none>           <none>

查看当前挂载的rbd设备:这个设备是被Pod直接使用。

[root@k8s-node01 ~]# rbd showmapped 
id pool    image snap device    
0  rbddata myimg -    /dev/rbd0



Secret方式:将keyring文件保存为k8s上的secret资源,Pod直接调用secret资源来访问rbd,这样就不用在每个节点复制keyring文件了。

rbd镜像不允许多路访问,所以需要创建一个新的镜像拱这个Pod的使用:

rbd create rbddata/myimg2 --size 1Gi

查看rbd镜像:

]# rbd ls -p rbddata -l
NAME    SIZE PARENT FMT PROT LOCK 
myimg  2 GiB          2      excl 
myimg2 1 GiB          2

禁用掉不支持的特性:

rbd feature disable rbddata/myimg2 object-map fast-diff deep-flatten

获取keyring中的key:

        获取到的key要进行base64编码后才能被secret资源使用,这个命令获取的key就是keyring文件中的key。

]# ceph auth print-key client.k8s | base64
QVFEcWdEWmVRVnBUTWhBQUF5ZStjaXFORThpclhnTFFxdVNySmc9PQ==

创建secret和pod资源:

apiVersion: v1
kind: Secret
metadata:
  name: ceph-k8s-secret
type: "kubernetes.io/rbd" # 这种资源类型只能手动创建
data:
  key: QVFEcWdEWmVRVnBUTWhBQUF5ZStjaXFORThpclhnTFFxdVNySmc9PQ==
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-rbd-vol-v2
spec:
  containers:
  - name: busybox
    image: busybox:1.28
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","sleep 36000"]
    volumeMounts:
    - name: rbdpod
      mountPath: /data
  volumes:
  - name: rbdpod
    rbd:
      monitors:
      - 'ceph01:6789'
      - 'ceph02:6789'
      - 'ceph03:6789'
      pool: rbddata
      image: myimg2
      fsType: ext4
      readOnly: false
      user: k8s
      keyring: /etc/ceph/ceph.client.k8s.keyring

查看是否挂载:

]# kubectl exec -it pod-with-rbd-vol-v2 mount | grep data
/dev/rbd1 on /data type ext4 (rw,relatime,stripe=1024,data=ordered)

到运行Pod的节点查看挂载的设备:

[root@k8s-node01 ~]# rbd showmapped 
id pool    image  snap device    
0  rbddata myimg  -    /dev/rbd0 
1  rbddata myimg2 -    /dev/rbd1



StorageClass动态存储券供给:

        k8s要在ceph里做一些管理工作需要admin权限,admin的secret是被controller-manager使用的,Pod使用的是普通账号。

创建controller-manager使用的admin账户的Secret的key:这个key给ceph-admin-secret使用

]# ceph auth print-key client.admin | base64
QVFBNkx6VmViRXF2THhBQW82SDRUbGNYUHZsOFYvZWVhUmJXRGc9PQ==

创建Pod使用的key:这个key给ceph-user-secret使用

]# ceph auth print-key client.k8s | base64
QVFBSnJqZGVTeE1ITGhBQU1EVEUvYWxMaUduR0lGYXhBVmFnUnc9PQ==

storageclass.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: ceph-admin-secret # admin的key信息
  namespace: kube-system # 放在了kube-system名称空间中
data:
  key: QVFBNkx6VmViRXF2THhBQW82SDRUbGNYUHZsOFYvZWVhUmJXRGc9PQ==
type: kubernetes.io/rbd
---
apiVersion: v1
kind: Secret
metadata:
  name: ceph-k8s-secret # 普通用户Pod使用的key信息
  namespace: default # 放在默认名称空间中
data:
  key: QVFBSnJqZGVTeE1ITGhBQU1EVEUvYWxMaUduR0lGYXhBVmFnUnc9PQ==
type: kubernetes.io/rbd
---
apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
  name: rbd-dynamic
  annotations:
    # 是否将此存储类设为默认存储类,创建pvc时会默认使用此存储类,如果不需要设为默认则删除此行
    storageclass.beta.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/rbd # 存储类设备的供给方为rbd
reclaimPolicy: Retain # 回收策略,默认为Delete
parameters: # 连入ceph存储的信息
  monitors: ceph01:6789,ceph02:6789,ceph03:6789 # monitors的几个节点
  adminId: admin # 管理员用户名
  adminSecretName: ceph-admin-secret # 管理员的secret资源名称
  adminSecretNamespace: kube-system # 管理员secret资源的名称空间
  pool: rbddata # 使用哪个存储池来动态创建image
  userId: k8s # 使用那个用户来访问image资源
  userSecretName: ceph-k8s-secret # 对应userId的secret资源名称

查看创建的存储类:

]# kubectl get sc
NAME                    PROVISIONER         AGE
rbd-dynamic (default)   kubernetes.io/rbd   36m

创建pvc来测试动态创建pv:存储类会动态接入ceph集群到存储池中动态创建image,在动态创建k8s上的pv

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-claim
spec:
  storageClassName: rbd-dynamic # 向此存储类来动态申请pv
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

查看创建的pv和pvc:

]# kubectl get pv,pvc
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
persistentvolume/pvc-324fd8cd-4de1-4ac1-b1e8-ae2611ec2336   2Gi        RWO            Retain           Bound    default/rbd-claim   rbd-dynamic             4m8s

NAME                              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/rbd-claim   Bound    pvc-324fd8cd-4de1-4ac1-b1e8-ae2611ec2336   2Gi        RWO            rbd-dynamic    4m8s

注意:如果回收策略为默认的Delete,那么删除pvc的时候pv也会一同删除,ceph上的image也会一同删除。

在ceph集群上可以看到动态创建的image:

]# rbd ls -p rbddata -l
NAME                                                         SIZE PARENT FMT PROT LOCK 
kubernetes-dynamic-pvc-c8ba57ab-6a4f-4776-9271-3552d21fd7c0 2 GiB          2
myimg                                                       2 GiB          2
myimg2                                                      1 GiB          2


Cephfs作为存储:官方示例

https://github.com/kubernetes/examples/tree/master/volumes/cephfs/

示例:

apiVersion: v1
kind: Pod
metadata:
  name: cephfs
spec:
  containers:
  - name: cephfs-rw
    image: kubernetes/pause
    volumeMounts:
    - mountPath: "/mnt/cephfs"
      name: cephfs
  volumes:
  - name: cephfs
    cephfs:
      monitors:
      - 10.16.154.78:6789
      - 10.16.154.82:6789
      - 10.16.154.83:6789
      # by default the path is /, but you can override and mount a specific path of the filesystem by using the path attribute
      # path: /some/path/in/side/cephfs
      user: admin
      secretFile: "/etc/ceph/admin.secret"
      readOnly: true