使用云盘CDS
容器引擎CCE支持通过创建PV/PVC,并为工作负载挂载数据卷方式使用百度智能云磁盘CDS。本文将介绍如何在集群中动态和静态挂载云磁盘。
使用限制
- 集群Kubernetes版本需大于或等于1.16。
- 挂载CDS的Pod只能在支持挂载云磁盘的节点上启动。
前提条件
- 集群已安装块存储组件,更多信息请见CCE CSI CDS Plugin 说明。
操作步骤
通过PV/PVC方式使用CDS,具体分为两种方式:
- 静态挂载:需要用户提前在百度智能云中创建好CDS(操作方法参考CDS文档),然后通过CDS的volume id在集群中创建PV和PVC资源。
- 动态挂载:用户在集群中声明PVC时,自动创建出CDS磁盘并且动态关联至PV。
静态挂载的方式需要用户提供的CDS磁盘未被分区且处于未挂载状态,并且确保填入正确的磁盘ID。动态挂载在部分场景下可能会更加方便,但是需要注意动态挂载时将会自动创建CDS磁盘并且计费,动态创建的CDS将会随着用户删除PVC时被联动删除(需要将对应storageClass的reclaimPolicy参数设置为delete),但是如果用户在没有删除PVC的情况下直接删除了CCE集群,则需要手动对这些CDS进行处理。
动态挂载块存储
1. 创建存储类StorageClass
集群管理员可使用StorageClass为集群定义不同的存储类型。您可通过StorageClass配合PVC动态创建需要的存储资源。
本文介绍通过Kubectl方式创建并行文件存储PFS类型的StorageClass,自定义并行文件存储使用所需的模板。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: hp1 #StorageClass名称
provisioner: csi-cdsplugin
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
parameters:
paymentTiming: "Postpaid" #付费方式,Prepaid 表示预付费,Postpaid 表示后付费
storageType: "hp1" #磁盘类型,支持cloud_hp1, hp1, hdd
reservationLength: "3" #续费周期,预付费模式下需要填写,单位为“月”
reclaimPolicy: Delete #支持 Delete(删除 PVC 会自动删除 PV,并且动态申请的 CDS 会被自动释放)、Retain(删除 PVC 时 PV 状态会变成 Released,不会自动删除 PV,对应自动创建的 CDS 需要到 CDS console上手动释放),默认值为 Delete
说明
- storageType 用于设置动态创建的 CDS 盘的类型,支持:cloud_hp1 (通用型SSD),hp1 (高性能云磁盘),hdd (通用型HDD),更多信息请见创建CDS云盘
- 如果集群中存在使用动态方式挂载CDS的Pod,且对应StorageClass中reclaimPolicy设置为Delete,这部分CDS在集群删除集群时默认会保留,如果需要一同删除请在删除集群前手动停止相关Pod并删除对应PVC。
2. 创建持久卷声明PVC
注意storageClassName需要指定为上述部署storageClass时填写的storageClass名称。
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: csi-pvc-cds
spec:
accessModes:
- ReadWriteOnce
storageClassName: hp1
resources:
requests:
storage: 5Gi # 指定PVC存储空间大小
说明
不同的磁盘类型,存储大小不同,如hp1: 5~32765GB,cloud_hp1: 50~32765GB,hdd:5~32765GB
3. 检查PVC状态为Bound
$ kubectl get pvc csi-pvc-cds
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
csi-pvc-cds Bound pvc-1ab36e4d1d2711e9 50Gi RWX hp1 4s
说明
如果指定了volumeBindingMode为
WaitForFirstConsumer
,则PVC此时处于Pending状态,会等待第一个挂载该PVC的Pod被创建后才进入PV创建和绑定流程。
4. 在Pod中挂载PVC
Pod和PVC需要在同一个namespace下。
apiVersion: v1
kind: Pod
metadata:
name: test-pvc-pod
labels:
app: test-pvc-pod
spec:
containers:
- name: test-pvc-pod
image: nginx
volumeMounts:
- name: cds-pvc
mountPath: "/cds-volume"
volumes:
- name: cds-pvc
persistentVolumeClaim:
claimName: csi-pvc-cds
Pod创建后,可以读写容器内的/cds-volume路径来访问相应的cds存储上的内容。
静态挂载块存储
1. 创建持久卷PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-cds
namespace: "default"
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 5Gi
csi:
driver: "csi-cdsplugin"
volumeHandle: "v-xxxx" # 指定挂载的磁盘,格式为磁盘ID
fsType: "ext4"
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: failure-domain.beta.kubernetes.io/zone
operator: In
values:
- zoneA
persistentVolumeReclaimPolicy: Retain
说明
- fsType不填写时默认值为ext4。Filesystem模式下,若fsType与cds中实际文件系统类型不匹配,将导致挂载失败;若cds中尚无文件系统,则挂载时自动格式化cds为fsType指定的文件系统。
- nodeAffinity中需要指定cds所在可用区,保证挂载该cds的pod只会被调度到与cds磁盘同可用区的node上。
2. 创建持久卷声明PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cds-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
3. 检查PVC状态为Bound,并且与对应的PV绑定
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-cds 5Gi RWO Retain Bound default/csi-cds-pvc 4s
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
csi-cds-pvc Bound pv-cds 5Gi RWO 36s
4. 在Pod中挂载PVC
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server-deployment
labels:
test: ws
spec:
replicas: 1
selector:
matchLabels:
se: ws
template:
metadata:
labels:
se: ws
name: web-server
spec:
containers:
- name: web-server
image: nginx
volumeMounts:
- mountPath: /var/lib/www/html
name: csi-cds-pvc
volumes:
- name: csi-cds-pvc
persistentVolumeClaim:
claimName: csi-cds-pvc
Pod创建后,可以读写容器内的/var/lib/www/html路径来访问相应的cds存储上的内容。
由于创建PV和PVC时只支持accessModes为ReadWriteOnce,该PVC可以被一节点上的Pod挂载读写。
应用场景
在 StatefuleSet 里通过 claimTemple 批量使用 PVC
-
创建2副本StatefuleSet并指定volumeClaimTemplates,需要提前创建好相应 StorageClass:
apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: 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" ] resources: requests: storage: 5Gi storageClassName: hp1
-
查看 Pod 以及自动创建的 PVC。
$ kubectl get pod NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 3m web-1 1/1 Running 0 2m
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE www-web-0 Bound pvc-a1e885701d2f11e9 5Gi RWO hp1 6m www-web-1 Bound pvc-c91edb891d2f11e9 5Gi RWO hp1 5m
多可用区集群挂载CDS
目前CDS不支持跨可用区,如果CCE集群中有多个可用区的机器,动态挂载的方式可以通过设置StorageClass的Volume Binding Mode为WaitForFirstConsumer来自动根据Pod被调度节点所处的可用区创建CDS磁盘,或者通过设置StorageClass中allowedTopologies字段或Pod的节点亲和属性来指定可用区;使用已有CDS时,须指定PV的nodeAffinity参数实现可用区亲和性。
CCE集群默认会为集群节点打上可用区标签:
$ kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
192.168.80.15 Ready <none> 13d v1.8.12 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=BCC,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=bj,failure-domain.beta.kubernetes.io/zone=zoneC,kubernetes.io/hostname=192.168.80.15
其中 failure-domain.beta.kubernetes.io/zone=zoneC 标签说明该集群节点处于C可用区。
方式一:设置StorageClass的Volume Binding Mode
通过指定volumeBindingMode为WaitForFirstConsumer来解决此问题。指定绑定模式为WaitForFirstConsumer时,先进行Pod的调度,随后根据调度结果对应的可用区创建CDS。
使用示例
-
创建StorageClass指定
volumeBindingMode
为WaitForFirstConsumer
。apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: csi-cds provisioner: csi-cdsplugin allowVolumeExpansion: true volumeBindingMode: WaitForFirstConsumer parameters: paymentTiming: "Postpaid" storageType: "hp1" reclaimPolicy: Delete
-
在StatefulSet中通过claimTemple使用 PVC:
apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: serviceName: "nginx" replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: 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" ] resources: requests: storage: 5Gi storageClassName: csi-cds
方式二:通过StorageClass的allowedTopologies字段强制指定zone
-
创建StorageClass并配置
allowedTopologies
为 参数。apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: hp1-zonec provisioner: csi-cdsplugin parameters: paymentTiming: "Postpaid" storageType: "hp1" reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer allowedTopologies: - matchLabelExpressions: - key: failure-domain.beta.kubernetes.io/zone values: - zoneC
-
在StatefulSet中通过claimTemple使用 PVC:
apiVersion: apps/v1 kind: StatefulSet metadata: name: sts-multi-zone spec: serviceName: "nginx" replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: 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" ] resources: requests: storage: 40Gi storageClassName: hp1-zonec
扩容 CDS PV
扩容CDS PV需要集群Kubernetes版本为1.16及以上,同时只针对动态创建的CDS PV生效。
-
创建storageClass并添加
allowVolumeExpansion: true
配置apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: hp1 allowVolumeExpansion: true #允许磁盘扩容 ...
-
修改与PV绑定的PVC中
spec.resources.requests
中的磁盘容量为目标容量,触发扩容kind: PersistentVolumeClaim apiVersion: v1 metadata: name: csi-pvc-cds spec: accessModes: - ReadWriteOnce storageClassName: hp1 resources: requests: storage: 8Gi #修改为目标磁盘大小
-
默认情况下CDS CSI插件仅支持离线扩容,即需要在PVC未被Pod挂载时才会执行实际扩容动作。完成PVC容量request修改后,如果此时该PVC未被任何Pod挂载,则会触发CDS磁盘扩容操作,否则会等待挂载该PVC的Pod停止后才开始扩容。具体扩容进度可以通过
kubectl describe pvc <pvcName>
查看对应的Events了解。
说明
如果需要在PVC被Pod挂载状态下进行在线扩容,可以通过
kubectl -n kube-system edit deployment csi-cdsplugin-controller-server
,给csi-cdsplugin
容器的添加启动参数--enable-online-expansion`,来启用在线扩容功能。但需要特别注意的是,同时进行磁盘读写和磁盘扩容可能导致数据损坏,非必要场景不建议开启在线扩容功能。