目 录CONTENT

文章目录

云原生存储

简中仙
2023-06-15 / 0 评论 / 0 点赞 / 121 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2024-02-07,若内容或图片失效,请留言反馈。 本文如有错误或者侵权的地方,欢迎您批评指正!

这篇学习笔记是基于杜宽老师在51CTO上发布的视频课程制作的。在此,感谢杜宽老师的分享和教学。如有侵权,请及时联系我。版权归原作者所有,未经允许不得转载或使用。

一、什么是StorageClass和CSI

StorageClass:存储类,由K8s管理员创建,用于动态PV的管理,可以链接至不同的后端存储,比如Ceph、GlusterFS等。之后对存储的请求可以指向 StorageClass,然后StorageClass会自动的创建、删除PV。

实现方式:in-tree: 内置于K8s核心代码,对于存储的管理,都需要编写相应的代码。

out-of-tree:由存储厂商提供一个驱动(CSI或Flex Volume),安装到K8s集群,然后StorageClass只需要配置该驱动即可,驱动器会代替StorageClass管理存储。

官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/

二、Rook

Rook是一个自我管理的分布式存储编排系统,它本身并不是存储系统,在存储和k8s之前搭建了一个桥梁,使存储系统的搭建或者维护变得特别简单,Rook将分布式存储系统转变为自我管理、自我扩展、自我修复的存储服务。它让一些存储的操作,比如部署、配置、扩容、升级、迁移、灾难恢复、监视和资源管理变得自动化,无需人工处理。并且Rook支持CSI,可以利用CSI做一些PVC的快照、扩容、克隆等操作。

官网:https://rook.io/

1、Rook架构

image-20230615165451978

Rook由Operator和Cluster两部分组成:

Operator:由一些CRD和一个All in one镜像构成,包含包含启动和监控存储系统的所有功能。主要用于有状态的服务,或者用于比较复杂应用的管理。

Cluster:负责创建CRD对象,指定相关参数,包括ceph镜像、元数据持久化位置、磁盘位置、dashboard等等…

Rook:

  • Agent: 在每个存储节点上运行,用于配置一个FlexVolume插件,和k8s的存储卷进行集成。挂载网络存储、加载存储卷、格式化文件系统。

  • Discover: 用于检测连接到存储节点上的设备。

Ceph:

  • OSD: 直接连接每个集群节点的物理磁盘或者是目录。集群的副本数,高可用性和容错性。

  • Mon: 集群监控,所有集群的节点都会向Mon汇报,他记录了集群的拓扑以及数据存储位置的信息。

  • MDS: 元数据服务器,负责跟踪文件层次结构并存储Ceph元数据。

  • RGW: restful API 接口

  • MGR: 提供额外的监控和界面。

2、部署前提条件

  • K8s集群至少五个节点,每个节点的内存不低于5G,CPU不低于2核
  • 至少有三个存储节点,并且每个节点至少有一个裸盘
  • K8s集群所有的节点时间必须一致
  • k8s 1.21以上版本,快照功能需要单独安装snapshot控制器
  • rook的版本大于1.3,不要使用目录创建集群,要使用单独的裸盘进行创建,也就是创建一个新的磁盘,挂载到宿主机,不进行格式化,直接使用即可。
  • 如果从 Ceph 共享文件系统 (CephFS) 创建 RWX 卷,建议的最低内核版本为4.17。如果内核版本低于 4.17,则不会强制执行请求的 PVC 大小。存储配额只会在较新的内核上实施。

3、部署Rook

1、获取安装源码

git clone --single-branch --branch v1.11.8 https://github.com/rook/rook.git

2、配置更改

# cd rook/deploy/examples

修改Rook CSI镜像地址,原本的地址可能是k8s.io的镜像,但是k8s.io的镜像无法被国内访问,所以需要同步k8s.io的镜像到阿里云镜像仓库或者内网镜像仓库

# vim operator.yaml
110   ROOK_CSI_CEPH_IMAGE: "quay.io/cephcsi/cephcsi:v3.8.0"
111   ROOK_CSI_REGISTRAR_IMAGE: "registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.7.0"
112   ROOK_CSI_RESIZER_IMAGE: "registry.k8s.io/sig-storage/csi-resizer:v1.7.0"
113   ROOK_CSI_PROVISIONER_IMAGE: "registry.k8s.io/sig-storage/csi-provisioner:v3.4.0"
114   ROOK_CSI_SNAPSHOTTER_IMAGE: "registry.k8s.io/sig-storage/csi-snapshotter:v6.2.1"
115   ROOK_CSI_ATTACHER_IMAGE: "registry.k8s.io/sig-storage/csi-attacher:v4.1.0"

还是operator文件,新版本rook默认关闭了自动发现容器的部署,可以找到ROOK_ENABLE_DISCOVERY_DAEMON改成true即可

495   ROOK_ENABLE_DISCOVERY_DAEMON: "true"

如何需要指定部署位置,需要开启污点配置

185   # CSI_PROVISIONER_TOLERATIONS: |
186   #   - effect: NoSchedule
187   #     key: node-role.kubernetes.io/control-plane
188   #     operator: Exists
189   #   - effect: NoExecute
190   #     key: node-role.kubernetes.io/etcd
191   #     operator: Exists
192   # (Optional) CephCSI plugin NodeAffinity (applied to both CephFS and RBD plugin).
193   # CSI_PLUGIN_NODE_AFFINITY: "role=storage-node; storage=rook, ceph"
194   # (Optional) CephCSI plugin tolerations list(applied to both CephFS and RBD plugin).
195   # Put here list of taints you want to tolerate in YAML format.
196   # CSI plugins need to be started on all the nodes where the clients need to mount the storage.
197   # CSI_PLUGIN_TOLERATIONS: |
198   #   - effect: NoSchedule
199   #     key: node-role.kubernetes.io/control-plane
200   #     operator: Exists
201   #   - effect: NoExecute
202   #     key: node-role.kubernetes.io/etcd
203   #     operator: Exists

4、部署rook

kubectl create ns rook-ceph
kubectl create -f crds.yaml -f common.yaml -f operator.yaml

等待operator容器和discover容器启动

# kubectl -n rook-ceph get pod
NAME                                                     READY   STATUS      RESTARTS   AGE
rook-ceph-operator-7c7d8846f4-fsv9f                      1/1     Running     0          25h
rook-discover-qw2ln                                      1/1     Running     0          28h
rook-discover-wf8t7                                      1/1     Running     0          28h
rook-discover-z6dhq                                      1/1     Running     0          28h

三、创建ceph集群

1、配置更改

主要更改的是osd节点所在的位置

# vim cluster.yaml 
24     image: quay.io/ceph/ceph:v17.2.6			# 修改为内网仓库镜像
37   skipUpgradeChecks: false					# 跳过升级(可忽略不改)
72     ssl: false								# dashboard不通过ssl访问
76     enabled: false							# 打开prometheus监控指标
239   storage:
240     useAllNodes: false						# 不使用宿主机所有节点
241     useAllDevices: false					# 不使用宿主机所有磁盘
243     config:
252     nodes:													# 手动指定存储节点及磁盘,注意config和nodes对齐
253     - name: "k8s-master03"
254       devices:
255       - name: "sdb"
     	- name: "k8s-node01"
       	  devices:
          - name: "sdb"
        - name: "k8s-node02"
          devices:
          - name: "sdb"
###
     - name: "k8s-master03"
       devices:
       - name: "sdb"
     - name: "k8s-node01"
       devices:
       - name: "sdb"
     - name: "k8s-node02"
       devices:
       - name: "sdb"
###

img

注意:新版必须采用裸盘,即未格式化的磁盘。其中k8s-master03 k8s-node01 node02有新加的一个磁盘,可以通过lsblk -f查看新添加的磁盘名称。建议最少三个节点,否则后面的试验可能会出现问题

2、创建Ceph集群

kubectl create -f cluster.yaml

创建完成后,可以查看pod的状态

# kubectl -n rook-ceph get pod
NAME                                                     READY   STATUS      RESTARTS   AGE
csi-cephfsplugin-6nwbp                                   3/3     Running     0          25h
csi-cephfsplugin-b7h6k                                   3/3     Running     0          25h
csi-cephfsplugin-provisioner-785798bc8f-78tvr            6/6     Running     0          25h
csi-cephfsplugin-provisioner-785798bc8f-krsdx            6/6     Running     0          25h
csi-rbdplugin-2mmmj                                      3/3     Running     0          25h
csi-rbdplugin-85sbg                                      3/3     Running     0          25h
csi-rbdplugin-provisioner-75cdf8cd6d-ghl8f               6/6     Running     0          25h
csi-rbdplugin-provisioner-75cdf8cd6d-wf6h8               6/6     Running     0          25h
rook-ceph-crashcollector-k8s-master03-64c56d8d8b-9vqrk   1/1     Running     0          28h
rook-ceph-crashcollector-k8s-node01-7fc9b79798-6r2rn     1/1     Running     0          28h
rook-ceph-crashcollector-k8s-node02-6954497cb9-pqll7     1/1     Running     0          28h
rook-ceph-mgr-a-dd4bf8445-scsrt                          1/1     Running     0          25h
rook-ceph-mon-a-856779ddfd-8v7s2                         1/1     Running     0          28h
rook-ceph-mon-b-6c94bddf8c-wb69x                         1/1     Running     0          28h
rook-ceph-mon-c-5659bcb5c9-pjn5f                         1/1     Running     0          28h
rook-ceph-operator-7c7d8846f4-fsv9f                      1/1     Running     0          25h
rook-ceph-osd-0-7c6cdb8546-kkcts                         1/1     Running     0          28h
rook-ceph-osd-1-f8b598d47-qjnwl                          1/1     Running     0          28h
rook-ceph-osd-2-55846dbcd9-jvm62                         1/1     Running     0          28h
rook-ceph-osd-prepare-k8s-master03-h8lt2                 0/1     Completed   0          5h1m
rook-ceph-osd-prepare-k8s-node01-jqz7x                   0/1     Completed   0          5h1m
rook-ceph-osd-prepare-k8s-node02-hm8lc                   0/1     Completed   0          5h1m
rook-discover-qw2ln                                      1/1     Running     0          29h
rook-discover-wf8t7                                      1/1     Running     0          29h
rook-discover-z6dhq                                      1/1     Running     0          29h

需要注意的是,osd-x的容器必须是存在的,且是正常的。如果上述Pod均正常,则认为集群安装成功。

更多配置:https://rook.io/docs/rook/v1.11/CRDs/Cluster/ceph-cluster-crd/

3、安装ceph snapshot控制器

k8s 1.19版本以上需要单独安装snapshot控制器,才能完成pvc的快照功能,所以在此提前安装下,如果是1.19以下版本,不需要单独安装。

snapshot控制器的部署在集群安装时的k8s-ha-install项目中,需要切换到1.20.x分支

cd /root/k8s-ha-install/
git checkout manual-installation-v1.26.x

创建snapshot controller

# kubectl create -f snapshotter/ -n kube-system
# kubectl  get po -n kube-system -l app=snapshot-controller
NAME                    READY   STATUS    RESTARTS   AGE
snapshot-controller-0   1/1     Running   0          27h

具体文档:https://rook.io/docs/rook/v1.11/Storage-Configuration/Ceph-CSI/ceph-csi-snapshot/?h=snapshot

4、安装ceph客户端工具

# kubectl create -f deploy/examples/toolbox.yaml
deployment.apps/rook-ceph-tools created

待容器Running后,即可执行相关命令

# kubectl -n rook-ceph rollout status deploy/rook-ceph-tools
NAME                               READY   STATUS    RESTARTS   AGE
rook-ceph-tools-6f7467bb4d-qzsvg   1/1     Running   0          <invalid>
# kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
# ceph status
  cluster:
    id:     356e0bac-b3e3-4abc-891b-ee6b8a0bc56f
    health: HEALTH_OK
 
  services:
    mon: 3 daemons, quorum a,b,c (age 29h)
    mgr: a(active, since 5h)
    osd: 3 osds: 3 up (since 29h), 3 in (since 29h)
 
  data:
    pools:   1 pools, 1 pgs
    objects: 0 objects, 0 B
    usage:   3.0 GiB used, 57 GiB / 60 GiB avail
    pgs:     1 active+clean
 
# ceph osd status
ID  HOST           USED  AVAIL  WR OPS  WR DATA  RD OPS  RD DATA  STATE      
 0  k8s-node01    1029M  18.9G      0        0       0        0   exists,up  
 1  k8s-master03  1029M  18.9G      0        0       0        0   exists,up  
 2  k8s-node02    1029M  18.9G      0        0       0        0   exists,up  
# ceph df
--- RAW STORAGE ---
CLASS  SIZE    AVAIL   USED    RAW USED  %RAW USED
hdd    60 GiB  57 GiB  17 MiB   3.0 GiB       5.03
TOTAL  60 GiB  57 GiB  17 MiB   3.0 GiB       5.03
 
--- POOLS ---
POOL                   ID  STORED  OBJECTS  USED  %USED  MAX AVAIL
device_health_metrics   1     0 B        0   0 B      0     18 GiB
# ceph config set mon auth_allow_insecure_global_id_reclaim false			# 解决警告

警告解决:https://docs.ceph.com/en/octopus/rados/operations/health-checks/

5、Ceph dashboard

1、暴露服务

默认情况下,ceph dashboard是无法直接访问的,可以创建一个nodePort类型的Service暴露服务

# kubectl create -f deploy/examples/dashboard-external-https.yaml

保存退出后,会创建一个端口,然后通过https://192.168.99.110:31176即可访问该dashboard

# kubectl -n rook-ceph get service
NAME                                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
rook-ceph-mgr                           ClusterIP   10.108.111.192   <none>        9283/TCP         4h
rook-ceph-mgr-dashboard                 ClusterIP   10.110.113.240   <none>        8443/TCP         4h
rook-ceph-mgr-dashboard-external-https  NodePort    10.101.209.6     <none>        8443:31176/TCP   4h

img

2、登录

账号为admin,查看密码

kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo

image-20230615171621768

四、ceph块存储的使用

块存储一般用于一个Pod挂载一块存储使用,相当于一个服务器新挂了一个盘,只给一个应用使用。

参考文档:https://rook.io/docs/rook/v1.11/Storage-Configuration/Block-Storage-RBD/block-storage/

1、创建StorageClass和ceph的存储池

# pwd
/root/rook/deploy/examples/csi/rbd
# vim storageclass.yaml
apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: replicapool
  namespace: rook-ceph 		# namespace:cluster
spec:
  failureDomain: host
  replicated:
    size: 3					# 生产环境最少为3,且要小于等于osd的数量
    requireSafeReplicaSize: true
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-ceph-block
# Change "rook-ceph" provisioner prefix to match the operator namespace if needed
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
  clusterID: rook-ceph # namespace:cluster
  pool: replicapool
  
  imageFormat: "2"
  imageFeatures: layering
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph # namespace:cluster
  csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph # namespace:cluster
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
  csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph # namespace:cluster  
  csi.storage.k8s.io/fstype: ext4  							# 创建文件类型
  
allowVolumeExpansion: true									# 是否允许扩容
reclaimPolicy: Delete										# PV回收策略

创建StorageClass和存储池

# kubectl create -f deploy/examples/csi/rbd/storageclass.yaml
cephblockpool.ceph.rook.io/replicapool created
storageclass.storage.k8s.io/rook-ceph-block created

查看创建的cephblockpool和storageClass(StorageClass没有namespace隔离性)

# kubectl  get cephblockpool -n rook-ceph
NAME          AGE
replicapool   39s
# kubectl  get sc 
NAME              PROVISIONER                  RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
rook-ceph-block   rook-ceph.rbd.csi.ceph.com   Delete          Immediate           true                   107s

此时可以在ceph dashboard查看到该Pool,如果没有显示说明没有创建成功

img

2、挂载测试

创建一个MySQL服务

# pwd
/root/rook/deploy/examples
# kubectl create -f mysql.yaml
service/wordpress-mysql created
persistentvolumeclaim/mysql-pv-claim created
deployment.apps/wordpress-mysql created

该文件有一段pvc的配置

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app: wordpress
spec:
  storageClassName: rook-ceph-block
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi      

pvc会连接刚才创建的storageClass,然后动态创建pv,然后连接到ceph创建对应的存储

之后创建pvc只需要指定storageClassName为刚才创建的StorageClass名称即可连接到rook的ceph。如果是statefulset,只需要将volumeTemplateClaim里面的Claim名称改为StorageClass名称即可动态创建Pod,具体请听视频。

其中MySQL deployment的volumes配置挂载了该pvc

    spec:
      containers:
        - image: mysql:5.6
          name: mysql
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: changeme
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - name: mysql-persistent-storage
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-persistent-storage
          persistentVolumeClaim:
            claimName: mysql-pv-claim

claimName为pvc的名称

因为MySQL的数据不能多个MySQL实例连接同一个存储,所以一般只能用块存储。相当于新加了一块盘给MySQL使用。

创建完成后可以查看创建的pvc和pv

# kubectl get pv 
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS      REASON   AGE
pvc-1843c13e-09cb-46c6-9dd8-5f54a834681b   20Gi       RWO            Delete           Bound    default/mysql-pv-claim   rook-ceph-block            65m
# kubectl get pvc
NAME               STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
mysql-pv-claim     Bound     pvc-1843c13e-09cb-46c6-9dd8-5f54a834681b   20Gi       RWO            rook-ceph-block   66m

此时在ceph dashboard上面也可以查看到对应的image

img

3、StatefulSet volumeClaimTemplates动态存储

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx 
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:						# 创建带有固定标识符的存储
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "rook-ceph-block"
      resources:
        requests:
          storage: 1Gi

五、共享文件系统的使用

共享文件系统一般用于多个Pod共享一个存储

官方文档:https://rook.io/docs/rook/v1.11/Storage-Configuration/Shared-Filesystem-CephFS/filesystem-storage/

1、创建共享类型的文件系统

通过为CephFilesystemCRD中的元数据池,数据池和元数据服务器指定所需的设置来创建文件系统

# pwd
/root/rook/deploy/examples
# kubectl  create -f filesystem.yaml 
cephfilesystem.ceph.rook.io/myfs created
# vim filesystem.yaml
apiVersion: ceph.rook.io/v1
kind: CephFilesystem
metadata:
  name: myfs
  namespace: rook-ceph
spec:
  metadataPool:
    replicated:
      size: 3
  dataPools:
    - name: replicated
      replicated:
        size: 3
  preserveFilesystemOnDelete: true
  metadataServer:
    activeCount: 1
    activeStandby: true

创建完成后会启动mds容器,需要等待启动后才可进行创建pv

# kubectl -n rook-ceph get pod -l app=rook-ceph-mds
NAME                                      READY     STATUS    RESTARTS   AGE
rook-ceph-mds-myfs-7d59fdfcf4-h8kw9       1/1       Running   0          12s
rook-ceph-mds-myfs-7d59fdfcf4-kgkjp       1/1       Running   0          12s

也可以在ceph dashboard上面查看状态

img

2、创建共享类型文件系统的StorageClass

# pwd
/root/rook/deploy/examples/csi/cephfs
# kubectl create -f storageclass.yaml 
storageclass.storage.k8s.io/rook-cephfs created

之后将pvc的storageClassName设置成rook-cephfs即可创建共享文件类型的存储,类似于NFS,可以给多个Pod共享数据

3、挂载测试

# pwd
/root/rook/deploy/examples/csi/cephfs
# ls
kube-registry.yaml  pod-ephemeral.yaml  pod.yaml  pvc-clone.yaml  pvc-restore.yaml  pvc.yaml  snapshotclass.yaml  snapshot.yaml  storageclass-ec.yaml  storageclass.yaml
# kubectl create -f kube-registry.yaml 
persistentvolumeclaim/cephfs-pvc created
deployment.apps/kube-registry created

查看创建的pvc和pod

# kubectl get po -n kube-system -l k8s-app=kube-registry
NAME                             READY   STATUS    RESTARTS   AGE
kube-registry-66d4c7bf47-46bpq   1/1     Running   0          34s
kube-registry-66d4c7bf47-jp88x   1/1     Running   0          34s
kube-registry-66d4c7bf47-xdtpx   1/1     Running   0          34s
# kubectl  get pvc -n kube-system
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
cephfs-pvc   Bound    pvc-0149518a-7346-4d16-9030-97b2f9b8e9d2   1Gi        RWX            rook-cephfs    100s

该文件的pvc配置,用于连接ceph创建存储

apiVersion: v1
kind: Persistent VolumeClaim
metadata:
  name: cephfs-pvc
  namespace: kube-system
spec :
  accessModes:
  - ReadiriteMany
  resources:
	requests:
      storage: 1G
  storageClassName: rook-cephfs

然后在deployment的volumes配置添加了该pvc,并将其挂载到了/var/lib/registry

image-20230615173824368

注意claimName为pvc的名称。

此时一共创建了三个Pod,这三个Pod共用了一个存储,挂载到了/var/lib/registry,该目录三个容器共享数据。

4、Nginx挂载测试

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  selector:
    app: nginx
  type: ClusterIP
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nginx-share-pvc
spec:
  storageClassName: rook-cephfs 
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment 
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      containers:
      - name: nginx
        image: nginx 
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
      volumes:
        - name: www
          persistentVolumeClaim:
            claimName: nginx-share-pvc

六、PVC扩容

文件共享类型的PVC扩容需要k8s 1.15+

块存储类型的PVC扩容需要k8s 1.16+

PVC扩容需要开启ExpandCSIVolumes,新版本的k8s已经默认打开了这个功能,可以查看自己的k8s版本是否已经默认打开了该功能:

# kube-apiserver -h |grep ExpandCSIVolumes 
                                                     ExpandCSIVolumes=true|false (BETA - default=true)

如果default为true就不需要打开此功能,如果default为false,需要开启该功能。

1、扩容文件共享型PVC

找到刚才创建的文件共享型StorageClass,将allowVolumeExpansion设置为true(新版rook默认为true,如果不为true更改后执行kubectl replace即可)

image-20230615174028733

找到之前创建的pvc

# kubectl  get pvc -n kube-system
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
cephfs-pvc   Bound    pvc-0149518a-7346-4d16-9030-97b2f9b8e9d2   1Gi        RWX            rook-cephfs    44m
# kubectl  edit pvc cephfs-pvc -n kube-system

将大小修改为2Gi,之前是1Gi

image-20230615174049355

保存退出

# kubectl  edit pvc cephfs-pvc -n kube-system
persistentvolumeclaim/cephfs-pvc edited

查看PV和PVC的大小

# kubectl  get pvc -n kube-system
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
cephfs-pvc   Bound    pvc-0149518a-7346-4d16-9030-97b2f9b8e9d2   2Gi        RWX            rook-cephfs    46m
# kubectl  get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS      REASON   AGE
pvc-0149518a-7346-4d16-9030-97b2f9b8e9d2   2Gi        RWX            Delete           Bound    kube-system/cephfs-pvc   rook-cephfs                47m
pvc-fd8b9860-c0d4-4797-8e1d-1fab880bc9fc   2Gi        RWO            Delete           Bound    default/mysql-pv-claim   rook-ceph-block            64m

查看容器内是否已经完成扩容

# kubectl  exec -ti kube-registry-66d4c7bf47-46bpq -n kube-system -- df -Th | grep "/var/lib/registry"
                     ceph            2.0G         0      2.0G   0% /var/lib/registry

同样的步骤可以扩容到3G

image-20230615174137717

2、扩容块存储

扩容步骤类似,找到PVC,直接edit即可

# kubectl  edit pvc mysql-pv-claim
persistentvolumeclaim/mysql-pv-claim edited
# kubectl  get pvc
NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
mysql-pv-claim   Bound    pvc-fd8b9860-c0d4-4797-8e1d-1fab880bc9fc   2Gi        RWO            rook-ceph-block   70m

可以看到此时pvc并没有扩容,但是pv已经扩容

# kubectl  get pv  | grep  default/mysql-pv-claim
pvc-fd8b9860-c0d4-4797-8e1d-1fab880bc9fc   3Gi        RWO            Delete           Bound    default/mysql-pv-claim   rook-ceph-block            75m

也可以看到ceph dashboard的image也完成了扩容,但是pvc和pod里面的状态会有延迟,大概等待5-10分钟后,即可完成扩容

image-20230615174305027

七、PVC快照

注意:PVC快照功能需要k8s 1.17+

1、块存储快照

1、创建snapshotClass

# pwd
/root/rook/deploy/examples/csi/rbd
# kubectl create -f snapshotclass.yaml 
volumesnapshotclass.snapshot.storage.k8s.io/csi-rbdplugin-snapclass created

2、创建快照

首先在之前创建的MySQL容器里创建一个文件夹,并创建一个文件

# kubectl  get po 
NAME                               READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-m5gj5             1/1     Running   1          3d4h
wordpress-mysql-6965fc8cc8-6wt6j   1/1     Running   0          86m
# kubectl  exec -ti wordpress-mysql-6965fc8cc8-6wt6j   -- bash
root@wordpress-mysql-6965fc8cc8-6wt6j:/# ls
bin  boot  dev	docker-entrypoint-initdb.d  entrypoint.sh  etc	home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@wordpress-mysql-6965fc8cc8-6wt6j:/# cd /var/lib/mysql
root@wordpress-mysql-6965fc8cc8-6wt6j:/var/lib/mysql# ls
auto.cnf  ib_logfile0  ib_logfile1  ibdata1  lost+found  mysql	performance_schema
root@wordpress-mysql-6965fc8cc8-6wt6j:/var/lib/mysql# mkdir test_snapshot
root@wordpress-mysql-6965fc8cc8-6wt6j:/var/lib/mysql# ls
auto.cnf  ib_logfile0  ib_logfile1  ibdata1  lost+found  mysql	performance_schema  test_snapshot
root@wordpress-mysql-6965fc8cc8-6wt6j:/var/lib/mysql# echo "test for snapshot" > test_snapshot/1.txt
root@wordpress-mysql-6965fc8cc8-6wt6j:/var/lib/mysql# cat test_snapshot/1.txt 
test for snapshot

修改snapshot.yaml文件的source pvc为创建的MySQL pvc

image-20230615174434339

创建快照及查看状态

# kubectl  create -f snapshot.yaml 
volumesnapshot.snapshot.storage.k8s.io/rbd-pvc-snapshot created
# kubectl get volumesnapshotclass
NAME                      DRIVER                       DELETIONPOLICY   AGE
csi-rbdplugin-snapclass   rook-ceph.rbd.csi.ceph.com   Delete           8m37s
# kubectl get volumesnapshot
NAME               READYTOUSE   SOURCEPVC        SOURCESNAPSHOTCONTENT   RESTORESIZE   SNAPSHOTCLASS             SNAPSHOTCONTENT                                    CREATIONTIME   AGE
rbd-pvc-snapshot   true         mysql-pv-claim                           3Gi           csi-rbdplugin-snapclass   snapcontent-715c2841-d1ba-493a-9eb9-52178df3c2e6   <invalid>      <invalid>

3、指定快照创建PVC

如果想要创建一个具有某个数据的PVC,可以从某个快照恢复

# cat pvc-restore.yaml 
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc-restore
spec:
  storageClassName: rook-ceph-block
  dataSource:
    name: rbd-pvc-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi
# kubectl create -f pvc-restore.yaml 
persistentvolumeclaim/rbd-pvc-restore created

注意:dataSource为快照名称,storageClassName为新建pvc的storageClass,storage的大小不能低于原pvc的大小

# kubectl create -f pvc-restore.yaml 
persistentvolumeclaim/rbd-pvc-restore created
# kubectl get pvc
NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
mysql-pv-claim    Bound    pvc-fd8b9860-c0d4-4797-8e1d-1fab880bc9fc   3Gi        RWO            rook-ceph-block   95m
rbd-pvc-restore   Bound    pvc-d86a7535-2331-4fef-ae93-c570c8d3f9e7   3Gi        RWO            rook-ceph-block   2s

4、数据校验

创建一个容器,挂载该PVC,查看是否含有之前的文件

# cat restore-check-snapshot-rbd.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: check-snapshot-restore
spec:
  selector:
    matchLabels:
      app: check 
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: check 
    spec:
      containers:
      - image: alpine:3.8
        name: check
        command:
        - sh
        - -c
        - sleep 36000
        volumeMounts:
        - name: check-mysql-persistent-storage
          mountPath: /mnt
      volumes:
      - name: check-mysql-persistent-storage
        persistentVolumeClaim:
          claimName: rbd-pvc-restore 
# kubectl  create -f restore-check-snapshot-rbd.yaml 
deployment.apps/check-snapshot-restore created

查看数据是否存在

# kubectl  get po
NAME                                      READY   STATUS    RESTARTS   AGE
check-snapshot-restore-64b85c5f88-zvr62   1/1     Running   0          97s
nginx-6799fc88d8-m5gj5                    1/1     Running   1          3d5h
wordpress-mysql-6965fc8cc8-6wt6j          1/1     Running   0          104m
You have new mail in /var/spool/mail/root
# kubectl  exec -ti check-snapshot-restore-64b85c5f88-zvr62  -- ls
bin    etc    lib    mnt    root   sbin   sys    usr
dev    home   media  proc   run    srv    tmp    var
# kubectl  exec -ti check-snapshot-restore-64b85c5f88-zvr62  -- ls /mnt
auto.cnf            ibdata1             performance_schema
ib_logfile0         lost+found          test_snapshot
ib_logfile1         mysql
# kubectl  exec -ti check-snapshot-restore-64b85c5f88-zvr62  -- ls /mnt/test_snapshot
1.txt
# kubectl  exec -ti check-snapshot-restore-64b85c5f88-zvr62  -- cat /mnt/test_snapshot/1.txt
test for snapshot

测试无误后清理数据(snapshotclass可以不删除,后期创建rbd快照直接用该snapshotclass即可)

# kubectl  delete -f restore-check-snapshot-rbd.yaml -f pvc-restore.yaml -f snapshot.yaml 
deployment.apps "check-snapshot-restore" deleted
persistentvolumeclaim "rbd-pvc-restore" deleted
volumesnapshot.snapshot.storage.k8s.io "rbd-pvc-snapshot" deleted

2、文件共享型快照

1、创建snapshotClass

# pwd
/root/rook/deploy/examples/csi/cephfs
# kubectl create -f snapshotclass.yaml 

3、快照回滚

# pwd
/root/rook/deploy/examples/csi/cephfs
# kubectl create -f pvc-restore.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: cephfs-pvc-restore
spec:
  storageClassName: rook-cephfs				# 与pv的名称一致
  dataSource:
    name: cephfs-pvc-snapshot				# 快照名称
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi							# 不能小于需要恢复pv的大小

八、PVC克隆

# pwd
/root/rook/deploy/examples/csi/rbd
# cat pvc-clone.yaml 
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc-clone
spec:
  storageClassName: rook-ceph-block
  dataSource:
    name: mysql-pv-claim
    kind: PersistentVolumeClaim
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 3Gi     
# kubectl create -f pvc-clone.yaml 
persistentvolumeclaim/rbd-pvc-clone created
# kubectl  get pvc
NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
mysql-pv-claim   Bound    pvc-fd8b9860-c0d4-4797-8e1d-1fab880bc9fc   3Gi        RWO            rook-ceph-block   110m
rbd-pvc-clone    Bound    pvc-6dda14c9-9d98-41e6-9d92-9d4ea382c614   3Gi        RWO            rook-ceph-block   4s

需要注意的是pvc-clone.yaml的dataSource的name是被克隆的pvc名称,在此是mysql-pv-claim,storageClassName为新建pvc的storageClass名称,storage不能小于之前pvc的大小

九、测试数据清理

如果Rook要继续使用,可以只清理创建的deploy、pod、pvc即可。之后可以直接投入使用

数据清理步骤:

1、首先清理挂载了PVC和Pod,可能需要清理单独创建的Pod和Deployment或者是其他的高级资源

kubectl get pod 
kubectl delete pod pod名

2、之后清理PVC,清理掉所有通过ceph StorageClass创建的PVC后,最好检查下PV是否被清理

kubectl get pvc
kubectl delete pvc pvc名

3、之后清理快照

kubectl get volumesnapshot
kubectl delete volumesnapshot XXXXXXXX

4、之后清理创建的Pool,包括块存储和文件存储

kubectl delete -n rook-ceph cephblockpool replicapool
kubectl delete storageclass rook-ceph-block
kubectl delete -f csi/cephfs/kube-registry.yaml
kubectl delete storageclass csi-cephfs

5、清理StorageClass:

kubectl get sc
kubectl delete sc rook-ceph-block  rook-cephfs

6、清理Ceph集群:

kubectl -n rook-ceph patch cephcluster rook-ceph --type merge -p '{"spec":{"cleanupPolicy":{"confirmation":"yes-really-destroy-data"}}}'
kubectl -n rook-ceph delete cephcluster rook-ceph
kubectl -n rook-ceph get cephcluster

7、删除Rook资源:

kubectl delete -f operator.yaml
kubectl delete -f common.yaml
kubectl delete -f crds.yaml

8、如果卡住需要参考Rook的troubleshooting

for CRD in $(kubectl get crd -n rook-ceph | awk '/ceph.rook.io/ {print $1}'); do
    kubectl get -n rook-ceph "$CRD" -o name | \
    xargs -I {} kubectl patch -n rook-ceph {} --type merge -p '{"metadata":{"finalizers": []}}'
done

9、清理数据目录和磁盘

参考链接:https://rook.io/docs/rook/v1.11/Storage-Configuration/ceph-teardown/#delete-the-data-on-hosts

十、K8S连接外部Ceph集群

1、使⽤Ceph-CSI为默认storageClass

1、cephCSI存储配置

ceph存储由外部提供,以下步骤在ceph上操作,⽬的是为kubenetes访问ceph使⽤

1、ceph新建cephpool
ceph osd pool create kubernetes 64 64  
pool 'kubernetes' created
2、创建一个名字为client.k8s的用户,且只能使用指定的pool(kubernetes)
# ceph auth get-or-create client.k8s mon 'allow r' osd 'allow class-read object_prefix rbd_children,allow rwx pool=kubernetes'
[client.k8s]
        key = AQD+pg9gjreqMRAAtwq4dQnwX0kX4Vx6TueAJQ==

查看ceph信息

记录fsid的信息(集群ID)a.

mon_host信息(Ceph监视器),暂时只⽀持V1,参考⽂档

# cat ceph.conf
[global]
fsid = 6553e7de-1b81-454c-a381-40fdsaFfas9 # 重点 
mon_initial_members = uic_sh_gw, uic_sh_stack03, uic_sh_stack04, uic_sh_stack05, 
uic_sh_stack06
mon_host = 10.10.160.2,10.10.160.3,10.10.160.4,10.10.160.5,10.10.160.6  #重点 
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx

2、部署Ceph-CSI

1、ceph-csi下载

git clone --depth 1 --branch v3.1.0 https://gitclone.com/github.com/ceph/ceph-csi

2、修改ConfigMap信息

修改访问Ceph集群配置,进⼊⽬录(/root/ceph-csi/deploy/rbd/kubernetes)

# pwd
/root/ceph-csi/deploy/rbd/kubernetes
# ll
total 44
-rw-r--r-- 1 root root  317 Jan 18 12:43 csi-config-map.yaml
-rw-r--r-- 1 root root 1689 Jan 18 12:53 csi-nodeplugin-psp.yaml
-rw-r--r-- 1 root root  881 Jan 18 12:53 csi-nodeplugin-rbac.yaml
-rw-r--r-- 1 root root 1315 Jan 18 12:53 csi-provisioner-psp.yaml
-rw-r--r-- 1 root root 3131 Jan 18 12:53 csi-provisioner-rbac.yaml
-rw-r--r-- 1 root root 5502 Jan 18 13:08 csi-rbdplugin-provisioner.yaml
-rw-r--r-- 1 root root 5857 Jan 18 18:21 csi-rbdplugin.yaml
-rw-r--r-- 1 root root  161 Jan 18 17:19 csi-rbd-secret.yaml #⾃⼰⽣成的secret 
-rw-r--r-- 1 root root  706 Jan 18 13:21 storageclass.yaml  #⾃⼰⽣成的动态存储

修改ConfigMap的信息,

使⽤configmap将服务的clusterID等信息录⼊到集群(namespace)中

# vim csi-config-map.yaml 
apiVersion: v1
kind: ConfigMap
data:
  config.json: |-
    [
      {
        "clusterID": "081dc49f-2525-4aaa-a56d-89d641cef302",  # ceph mon dump获取
        "monitors": [
          "192.168.1.129:6789",
          "192.168.1.130:6789",
          "192.168.1.131:6789"
        ]
      }
    ]
metadata:
  name: ceph-csi-config
# kubectl apply -f csi-config-map.yaml 
configmap/ceph-csi-config created
# kubectl get cm ceph-csi-config 
NAME              DATA   AGE
ceph-csi-config   1      19s

3、创建ceph-CSI的namespace空间

ceph-CSI单独使⽤的ns资源

kubectl create ns ceph-csi
kubectl -n ceph-csi apply -f csi-config-map.yaml

4、生成ceph用户(k8s)密钥

新建secret⽂件,将ceph创建的k8s的⽤⼾名和密码⽣成secret

# cat csi-rbd-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: csi-rbd-secret
  namespace: ceph-csi
stringData:
  userID: k8s  # ceph集群创建的username    # 这里用admin的要不然下面会报错!!!!!!!!!!!!!
  userKey: AQD+pg9gjreqMRAAtwq4dQnwX0kX4Vx6TueAJQ== # 这个key不需要base64加密!!!!!!!!!!!!!!!!!

⽣成secret

# kubectl apply -f  csi-rbd-secret.yaml    
secret/csi-rbd-secret created
# kubectl get secret csi-rbd-secret 
NAME             TYPE     DATA   AGE
csi-rbd-secret   Opaque   2      14s

3、RBAC权限配置

1、更改默认配置的namespace

将所有配置清单中的 namespace 改成 ceph-csi

sed -i "s/namespace: default/namespace: ceph-csi/g" $(grep -rl "namespace: default" ./)
sed -i -e "/^kind: ServiceAccount/{N;N;a\  namespace: ceph-csi  # 输⼊到这⾥的时候
需要按⼀下回⻋键,在下⼀⾏继续输⼊ 
  }" $(egrep -rl "^kind: ServiceAccount" ./)

2、创建 ServiceAccount 和RBACClusterRole/ClusterRoleBinding资源对象

kubectl create -f csi-provisioner-rbac.yaml
kubectl create -f csi-nodeplugin-rbac.yaml

3、创建PodSecurityPolicy

kubectl create -f csi-provisioner-psp.yaml
kubectl create -f csi-nodeplugin-psp.yaml

4、CSIsidecar和RBDCSIdriver

CSIsidecar:⽤来简化开发和部署,⽤来监控KubernetesAPI,针对CSI容器触发⼀些适当的操作,根据需求更新API,⼀般配合CSiDrive去使⽤

1、创建ceph csi供应器和节点插件

# vim csi-rbdplugin-provisioner.yaml
kind: Service
apiVersion: v1
metadata:
  name: csi-rbdplugin-provisioner
  labels:
    app: csi-metrics
spec:
  selector:
    app: csi-rbdplugin-provisioner
  ports:
    - name: http-metrics
      port: 8080
      protocol: TCP
      targetPort: 8680

---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: csi-rbdplugin-provisioner
spec:
  replicas: 3
  selector:
    matchLabels:
      app: csi-rbdplugin-provisioner
  template:
    metadata:
      labels:
        app: csi-rbdplugin-provisioner
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - csi-rbdplugin-provisioner
              topologyKey: "kubernetes.io/hostname"
      serviceAccount: rbd-csi-provisioner
      containers:
        - name: csi-provisioner
          image: k8s.gcr.io/sig-storage/csi-provisioner:v2.0.4
          args:
            - "--csi-address=$(ADDRESS)"
            - "--v=5"
            - "--timeout=150s"
            - "--retry-interval-start=500ms"
            - "--leader-election=true"
            #  set it to true to use topology based provisioning
            - "--feature-gates=Topology=false"
            # if fstype is not specified in storageclass, ext4 is default
            - "--default-fstype=ext4"
            - "--extra-create-metadata=true"
          env:
            - name: ADDRESS
              value: unix:///csi/csi-provisioner.sock
          imagePullPolicy: "IfNotPresent"
          volumeMounts:
            - name: socket-dir
              mountPath: /csi
        - name: csi-snapshotter
          image: k8s.gcr.io/sig-storage/csi-snapshotter:v3.0.2
          args:
            - "--csi-address=$(ADDRESS)"
            - "--v=5"
            - "--timeout=150s"
            - "--leader-election=true"
          env:
            - name: ADDRESS
              value: unix:///csi/csi-provisioner.sock
          imagePullPolicy: "IfNotPresent"
          securityContext:
            privileged: true
          volumeMounts:
            - name: socket-dir
              mountPath: /csi
        - name: csi-attacher
          image: k8s.gcr.io/sig-storage/csi-attacher:v3.0.2
          args:
            - "--v=5"
            - "--csi-address=$(ADDRESS)"
            - "--leader-election=true"
            - "--retry-interval-start=500ms"
          env:
            - name: ADDRESS
              value: /csi/csi-provisioner.sock
          imagePullPolicy: "IfNotPresent"
          volumeMounts:
            - name: socket-dir
              mountPath: /csi
        - name: csi-resizer
          image: k8s.gcr.io/sig-storage/csi-resizer:v1.0.1
          args:
            - "--csi-address=$(ADDRESS)"
            - "--v=5"
            - "--timeout=150s"
            - "--leader-election"
            - "--retry-interval-start=500ms"
            - "--handle-volume-inuse-error=false"
          env:
            - name: ADDRESS
              value: unix:///csi/csi-provisioner.sock
          imagePullPolicy: "IfNotPresent"
          volumeMounts:
            - name: socket-dir
              mountPath: /csi
        - name: csi-rbdplugin
          securityContext:
            privileged: true
            capabilities:
              add: ["SYS_ADMIN"]
          # for stable functionality replace canary with latest release version
          image: quay.io/cephcsi/cephcsi:canary
          args:
            - "--nodeid=$(NODE_ID)"
            - "--type=rbd"
            - "--controllerserver=true"
            - "--endpoint=$(CSI_ENDPOINT)"
            - "--v=5"
            - "--drivername=rbd.csi.ceph.com"
            - "--pidlimit=-1"
            - "--rbdhardmaxclonedepth=8"
            - "--rbdsoftmaxclonedepth=4"
          env:
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: NODE_ID
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            # - name: POD_NAMESPACE
            #   valueFrom:
            #     fieldRef:
            #       fieldPath: spec.namespace
            # - name: KMS_CONFIGMAP_NAME
            #   value: encryptionConfig
            - name: CSI_ENDPOINT
              value: unix:///csi/csi-provisioner.sock
          imagePullPolicy: "IfNotPresent"
          volumeMounts:
            - name: socket-dir
              mountPath: /csi
            - mountPath: /dev
              name: host-dev
            - mountPath: /sys
              name: host-sys
            - mountPath: /lib/modules
              name: lib-modules
              readOnly: true
            - name: ceph-csi-config
              mountPath: /etc/ceph-csi-config/
            - name: ceph-csi-encryption-kms-config
              mountPath: /etc/ceph-csi-encryption-kms-config/
            - name: keys-tmp-dir
              mountPath: /tmp/csi/keys
        - name: csi-rbdplugin-controller
          securityContext:
            privileged: true
            capabilities:
              add: ["SYS_ADMIN"]
          # for stable functionality replace canary with latest release version
          image: quay.io/cephcsi/cephcsi:canary
          args:
            - "--type=controller"
            - "--v=5"
            - "--drivername=rbd.csi.ceph.com"
            - "--drivernamespace=$(DRIVER_NAMESPACE)"
          env:
            - name: DRIVER_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          imagePullPolicy: "IfNotPresent"
          volumeMounts:
            - name: ceph-csi-config
              mountPath: /etc/ceph-csi-config/
            - name: keys-tmp-dir
              mountPath: /tmp/csi/keys
        - name: liveness-prometheus
          image: quay.io/cephcsi/cephcsi:canary
          args:
            - "--type=liveness"
            - "--endpoint=$(CSI_ENDPOINT)"
            - "--metricsport=8680"
            - "--metricspath=/metrics"
            - "--polltime=60s"
            - "--timeout=3s"
          env:
            - name: CSI_ENDPOINT
              value: unix:///csi/csi-provisioner.sock
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
          volumeMounts:
            - name: socket-dir
              mountPath: /csi
          imagePullPolicy: "IfNotPresent"
      volumes:
        - name: host-dev
          hostPath:
            path: /dev
        - name: host-sys
          hostPath:
            path: /sys
        - name: lib-modules
          hostPath:
            path: /lib/modules
        - name: socket-dir
          emptyDir: {
            medium: "Memory"
          }
        - name: ceph-csi-config
          configMap:
            name: ceph-csi-config
        - name: ceph-csi-encryption-kms-config
          configMap:
            name: ceph-csi-encryption-kms-config
        - name: keys-tmp-dir
          emptyDir: {
            medium: "Memory"
          }
# vim csi-rbdplugin.yaml
kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: csi-rbdplugin
spec:
  selector:
    matchLabels:
      app: csi-rbdplugin
  template:
    metadata:
      labels:
        app: csi-rbdplugin
    spec:
      serviceAccount: rbd-csi-nodeplugin
      hostNetwork: true
      hostPID: true
      # to use e.g. Rook orchestrated cluster, and mons' FQDN is
      # resolved through k8s service, set dns policy to cluster first
      dnsPolicy: ClusterFirstWithHostNet
      containers:
        - name: driver-registrar
          # This is necessary only for systems with SELinux, where
          # non-privileged sidecar containers cannot access unix domain socket
          # created by privileged CSI driver container.
          securityContext:
            privileged: true
          image: k8s.gcr.io/sig-storage/csi-node-driver-registrar:v2.0.1
          args:
            - "--v=5"
            - "--csi-address=/csi/csi.sock"
            - "--kubelet-registration-path=/var/lib/kubelet/plugins/rbd.csi.ceph.com/csi.sock"
          env:
            - name: KUBE_NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
          volumeMounts:
            - name: socket-dir
              mountPath: /csi
            - name: registration-dir
              mountPath: /registration
        - name: csi-rbdplugin
          securityContext:
            privileged: true
            capabilities:
              add: ["SYS_ADMIN"]
            allowPrivilegeEscalation: true
          # for stable functionality replace canary with latest release version
          image: quay.io/cephcsi/cephcsi:canary
          args:
            - "--nodeid=$(NODE_ID)"
            - "--type=rbd"
            - "--nodeserver=true"
            - "--endpoint=$(CSI_ENDPOINT)"
            - "--v=5"
            - "--drivername=rbd.csi.ceph.com"
            # If topology based provisioning is desired, configure required
            # node labels representing the nodes topology domain
            # and pass the label names below, for CSI to consume and advertise
            # its equivalent topology domain
            # - "--domainlabels=failure-domain/region,failure-domain/zone"
          env:
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: NODE_ID
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            # - name: POD_NAMESPACE
            #   valueFrom:
            #     fieldRef:
            #       fieldPath: spec.namespace
            # - name: KMS_CONFIGMAP_NAME
            #   value: encryptionConfig
            - name: CSI_ENDPOINT
              value: unix:///csi/csi.sock
          imagePullPolicy: "IfNotPresent"
          volumeMounts:
            - name: socket-dir
              mountPath: /csi
            - mountPath: /dev
              name: host-dev
            - mountPath: /sys
              name: host-sys
            - mountPath: /run/mount
              name: host-mount
            - mountPath: /lib/modules
              name: lib-modules
              readOnly: true
            - name: ceph-csi-config
              mountPath: /etc/ceph-csi-config/
            - name: ceph-csi-encryption-kms-config
              mountPath: /etc/ceph-csi-encryption-kms-config/
            - name: plugin-dir
              mountPath: /var/lib/kubelet/plugins
              mountPropagation: "Bidirectional"
            - name: mountpoint-dir
              mountPath: /var/lib/kubelet/pods
              mountPropagation: "Bidirectional"
            - name: keys-tmp-dir
              mountPath: /tmp/csi/keys
        - name: liveness-prometheus
          securityContext:
            privileged: true
          image: quay.io/cephcsi/cephcsi:canary
          args:
            - "--type=liveness"
            - "--endpoint=$(CSI_ENDPOINT)"
            - "--metricsport=8680"
            - "--metricspath=/metrics"
            - "--polltime=60s"
            - "--timeout=3s"
          env:
            - name: CSI_ENDPOINT
              value: unix:///csi/csi.sock
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
          volumeMounts:
            - name: socket-dir
              mountPath: /csi
          imagePullPolicy: "IfNotPresent"
      volumes:
        - name: socket-dir
          hostPath:
            path: /var/lib/kubelet/plugins/rbd.csi.ceph.com
            type: DirectoryOrCreate
        - name: plugin-dir
          hostPath:
            path: /var/lib/kubelet/plugins
            type: Directory
        - name: mountpoint-dir
          hostPath:
            path: /var/lib/kubelet/pods
            type: DirectoryOrCreate
        - name: registration-dir
          hostPath:
            path: /var/lib/kubelet/plugins_registry/
            type: Directory
        - name: host-dev
          hostPath:
            path: /dev
        - name: host-sys
          hostPath:
            path: /sys
        - name: host-mount
          hostPath:
            path: /run/mount
        - name: lib-modules
          hostPath:
            path: /lib/modules
        - name: ceph-csi-config
          configMap:
            name: ceph-csi-config
        - name: ceph-csi-encryption-kms-config
          configMap:
            name: ceph-csi-encryption-kms-config
        - name: keys-tmp-dir
          emptyDir: {
            medium: "Memory"
          }
---
# This is a service to expose the liveness metrics
apiVersion: v1
kind: Service
metadata:
  name: csi-metrics-rbdplugin
  labels:
    app: csi-metrics
spec:
  ports:
    - name: http-metrics
      port: 8080
      protocol: TCP
      targetPort: 8680
  selector:
    app: csi-rbdplugin
# kubectl apply -f csi-rbdplugin-provisioner.yaml -f csi-rbdplugin.yaml    

2、部署Sidecar容器

包括 external-provisioner 、 external-attacher 、 csi-resizer 和 csi-rbdplugin

kubectl -n ceph-csi create -f csi-rbdplugin-provisioner.yaml

3、部署RBDCSIDriver容器

kubectl -n ceph-csi create -f csi-rbdplugin.yaml

查看部署信息

kubectl get pod -n ceph-csi

4、创建Storageclass

clusterID:对应的fsid(ceph)。

imageFeatures:这是磁盘映像⽂件的特征,需要 uname -r 查看集群系统内核所⽀持的特性,centos7可以⽤layering

# cat csi-rbd-sc.yaml    
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-rbd-sc
provisioner: rbd.csi.ceph.com   # 驱动
parameters:
   clusterID: b9127830-b0cc-4e34-aa47-9d1a2e9949a8  # ceph集群id(ceph -s 查看)
   pool: kubernetes             # 访问的pool name
   csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret  # 默认是这些个名字
   csi.storage.k8s.io/provisioner-secret-namespace: default    # 默认在default namespace
   csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
   csi.storage.k8s.io/node-stage-secret-namespace: default
reclaimPolicy: Delete
mountOptions:
   - discard

创建storageClass

# kubectl apply -f csi-rbd-sc.yaml 
storageclass.storage.k8s.io/csi-rbd-sc created
# kubectl get storageclass.storage.k8s.io/csi-rbd-sc
NAME         PROVISIONER        RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
csi-rbd-sc   rbd.csi.ceph.com   Delete          Immediate           false                  17s

设置成默认存储(可选)

kubectl patch storageclass csi-rbd-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
# kubectl get StorageClass
NAME                   PROVISIONER        RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
csi-rbd-sc (default)   rbd.csi.ceph.com   Delete          Immediate           true                   25h

验证:PVC

使用官方PVCyaml,创建pvc资源

cd /root/ceph-csi/examples/rbd
kubectl apply -f pvc.yaml

查看:STATUS显⽰Bound表示成功

# kubectl get pvc
NAME      STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
rbd-pvc   Bound    pvc-7f79cfc7-46ee-4dc9-9bc3-c3f1ab98002b   1Gi        RWO     csi-rbd-sc     21h
0

评论区