使用云盘CDS
当前 CDS 磁盘支持以 FlexVolume 和 CSI 形式(要求集群k8s版本≥1.11)在集群中挂载。FlexVolume 形式支持直接在 Pod 中以 volume 方式挂载,CSI 形式挂载需要创建 PV 和 PVC 存储资源后,再将 PVC 挂载到 Pod 中。两种挂载方案都可以满足容器内特定数据持久化的需求,两者详细的区别请参考 kubernetes 官方文档:
准备工作
用户做好以下准备,才能在容器中挂载 CDS 实例:
- 注册百度账号,并完成实名认证;
- 创建一个 CCE K8S 集群。
注意:集群节点所处地域和可用区相同的 CDS 磁盘已创建,CDS 磁盘状态为未挂载。
创建容器集群
- 创建一个容器集群,操作步骤参考创建集群。
- 下载命令行客户端 kubectl,并连接集群,操作步骤参考[通过kubectl连接Kubernetes集群](CCE/操作指南/集群管理/通过 kubectl 连接集群.md)。
操作指南
通过 PV/PVC 方式挂载
1. 安装 CSI CDS 插件
- 依次选择:容器引擎 CCE -> Helm 模版 -> 百度云模版
- 通过模版名称
cce-csi-cds-plugin
搜索模版
- 点击安装并填写相应的参数
参数说明
- 实例名称:插件实例名称,例:bos;
- 部署集群:选择需要部署 BOS CSI 插件的集群;
- 命名空间:管理实例的 helm 元数据的命名空间,例:kube-system;
- kubernetets 版本:填写实际部署集群的版本,目前支持:1.18、1.16、1.13;
- nodes:如果部署集群的节点的时候,指定了 kubelet 的数据目录,需要填写具体使用的数据目录到该列表,否则保持默认即可;
- StorageClass: 模版默认会创建一个名称为 cds-ph1 的 StorageClass,如不需要可从参数 yaml 中删除,后续可自行在集群中创建;
2. 将 CDS 挂载到 Pod 中
通过PV/PVC方式使用CDS,具体分为两种方式:
- 静态挂载:需要用户提前在百度智能云中创建好CDS(操作方法参考CDS文档),然后通过CDS的volume id在集群中创建PV和PVC资源。
- 动态挂载:用户在集群中声明PVC时,自动创建出CDS磁盘并且动态关联至PV。
静态挂载的方式需要用户提供的CDS磁盘处于未挂载状态,并且确保填入正确的volume id。动态挂载在部分场景下可能会更加方便,但是需要注意动态挂载时将会自动创建CDS磁盘并且计费,动态创建的CDS将会随着用户删除PVC时被联动删除(需要将对应storageClass的reclaimPolicy参数设置为delete),但是如果用户在没有删除PVC的情况下直接删除了CCE集群,则需要手动对这些CDS进行处理。
静态挂载
创建PV/PVC
使用kubectl,执行 kubectl create -f pv-cds.yaml
完成PV的创建
对应的pv-cds.yaml文件如下所示:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-cds
namespace: "default"
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 5Gi
csi:
driver: "csi-cdsplugin"
volumeHandle: "v-xxxx"
persistentVolumeReclaimPolicy: Retain
注意: yaml中volumeHandle字段对应的是cds volume id(短 id)
创建PV后,输入kubectl get pv可以看见一个available状态的PV,如下所示:
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-cds 5Gi RWO Retain Available 22s
建立一个能够与该PV绑定的PVC
使用kubectl,执行 kubectl create -f pvc-cds.yaml
完成PVC的创建
对应的pvc-cds.yaml文件如下所示:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cds-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
绑定前,PVC为pending状态
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
cds-pvc Pending 2s
绑定后,PV和PVC状态变为Bound
$ 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
有关PV和PVC的更多设置和字段说明,见k8s官方文档
创建POD
在Pod spec内指定相应的PVC名称即可,使用kubectl,执行 kubectl create -f demo-cds-rc.yaml
完成rc的创建
对应的demo-cds-rc.yaml文件如下所示:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: web-server-rs
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创建后,可以读写容器内的/cds-volume路径来访问相应的cds存储上的内容。
由于创建PV和PVC时只支持accessModes为ReadWriteOnce,该PVC可以被一节点上的Pod挂载读写。
释放PV/PVC
完成存储资源的使用后,可以释放PVC和PV资源,使用以下命令可以释放PVC
$ kubectl delete -f pvc-cds.yaml
释放PVC后,原来与之绑定的PV状态会变为Release,如下所示:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-cds 5Gi RWO Retain Released default/csi-cds-pvc 4m
输入以下指令释放PV资源
$ kubectl delete -f pv-cds.yaml
动态挂载
创建 StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: hp1 #名字可以自定义
provisioner: csi-cdsplugin
parameters:
dynamicVolume: "true" #需要为 true 才会自动创建 volume
cdsSizeInGB: "40" #storageClass 能创建的单个 CDS size 限制
paymentTiming: "Postpaid" #Prepaid or Postpaid
storageType: "hp1" #支持std1 hp1 ssd
reservationLength: "3" #Prepaid 模式下需要填写
zone: "xxx" #参数可选
reclaimPolicy: Delete #支持 Delete、Retain 默认值为 Delete
StorageClass 参数说明:
cdsSizeInGB
cds 创建磁盘有限制: hp1: 5~32765GB std1: 5~32765GB ssd:50~32765GB cdsSizeInGB用于设置 StorageClass 创建的 cds 的最大值, PVC 中设置值需要小于这个值
zone
对于机器都在同一个 Zone 的情况,可以通过指定 StorageClass 里的 Zone,保证 cds 在指定的 Zone 创建。 集群中节点所在可用区可以通过
kubectl get nodes --show-labels
查看failure-domain.beta.kubernetes.io/zone
标签的值确定。 如: 可用区 A 的机器对应为 zoneA 可用区 B 的机器对应为 zoneBpaymentTiming
用于设置付费方式是:预付费 or 后付费
reservationLength
磁盘的保留时间,预付费模式下需要填写,单位为月
创建 PVC
在 PVC Spec 中指定上面创建的 StorageClass 名称,则在创建PVC时,会自动生成相应的PV进行绑定。
使用kubectl,执行 kubectl create -f csi-pvc-cds.yaml
完成PVC的创建。
假设创建的StorageClass名称为hp1,对应的 csi-pvc-cds.yaml 文件如下所示:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: csi-pvc-cds
spec:
accessModes:
- ReadWriteOnce
storageClassName: hp1
resources:
requests:
storage: 5Gi
PVC参数说明: PVC 中 resource request的 storge,对于不同StorageClass中不同storageType有相关限制。 std1: 5~32765GB hp1: 5~32765GB ssd:50~32765GB 同时 PVC中申请的磁盘大小应该<= StorageClass 中cdsSizeInGB
创建PVC后,可以看见相应的PV自动创建,PVC状态变为Bound,即PVC已经与新创建的PV绑定。
$ kubectl create -f csi-pvc-cds.yaml
persistentvolumeclaim "csi-pvc-cds" created
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
csi-pvc-cds Bound pvc-1ab36e4d1d2711e9 5Gi RWX hp1 4s
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-1ab36e4d1d2711e9 5Gi RWX Delete Bound default/csi-pvc-cds hp1 7s
在Pod内挂载PVC
在Pod spec内指定相应的PVC名称即可,使用kubectl,执行 kubectl create -f dynamic-cds-pod.yaml
完成资源的创建。对应的dynamic-cds-pod.yaml文件如下所示:
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存储上的内容。
释放PVC时动态销毁绑定PV
删除PVC时,与之绑定的动态PV是否会被自动删除由自定义的 StorageClass 中 reclaimPolicy 决定;reclaimPolicy 支持 Delete、Retain 默认值为 Delete。
- Delete:删除 PVC 会自动删除 PV,并且动态申请的 CDS 会被自动释放
- Retain:删除 PVC 时 PV 状态会变成 Released,不会自动删除 PV,对应自动创建的 CDS 需要到 CDS console上手动释放
$ kubectl delete pvc csi-pvc-cds
persistentvolumeclaim "csi-pvc-cds" deleted
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
pvc-1ab36e4d1d2711e9 40Gi RWO Retain Released default/csi-pvc-cds hp1 3m
在 StatefuleSet 里通过 claimTemple 批量使用 pvc 的场景,需要前置步骤为创建 StorageClass
以 sts-claim.yaml为例
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
创建 sts-claim.yaml,同时会自动创建 PVC:
$ kubectl apply -f sts-claim.yaml
$ 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
(1)StorageClass指定zone方式
目前 cds不支持跨可用区,如果cce集群中有多个可用区的机器,动态创建cds需要通过设置StorageClass中zone字段和NodeSelector等指定可用区实现;使用已有cds,指定NodeSelector需要使用的可用区可实现。
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可用区。
1)多可用区集群使用 cds例子
StorageClass-Multi-Zone-Temple.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cds-ssd-new
provisioner: csi-cdsplugin
parameters:
dynamicVolume: "true"
cdsSizeInGB: "40"
paymentTiming: "Postpaid"
storageType: "hp1"
reservationLength: "3"
zone: "zoneA"
reclaimPolicy: Delete
Sts-Multi-Zone-Temple.yaml
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:
nodeSelector:
failure-domain.beta.kubernetes.io/zone: "zoneA"
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: csi-cds-ssd-new
(2)设置 StorageClass的Volume Binding Mode 通过指定WaitForFirstConsumer和配置PersistentVolume 的模式来解决此问题,指定绑定模式为WaitForFirstConsumer,K8S会先进行调度 Pod,随后创建 CDS。
1)使用示例
StorageClass-WaitForFirstConsumer-Temple.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cds
provisioner: csi-cdsplugin
volumeBindingMode: WaitForFirstConsumer
parameters:
dynamicVolume: "true"
cdsSizeInGB: "40"
paymentTiming: "Postpaid"
storageType: "hp1"
reclaimPolicy: Delete
Sts-WaitForFirstConsumer-Temple.yaml
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
注意:
- 如果需要销毁 cce集群并且使用了本文中的 csi-provisioner 同时 storageClass中reclaimPolicy设置为 Delete,请先 delete pvc,否则可能会存在cds 无法自动释放。
- 多可用区集群使用cds,如果同时设置了WaitForFirstConsumer和 zone,zone 将会被覆盖。
在单个Pod中挂载多块CDS
注意:
- 在Pod Spec的volumes字段中,每块CDS只能被声明一次。
- 在Pod Spec的volumeMounts字段中,每块CDS对应的volume可以被引用多次。
- 对于Deployment/ReplicaSet等资源,replicas域只能设置为1。
下面的示例 cds-multi-mount-example.yaml
将文件中声明的四块CDS磁盘分别挂载到Pod mysql-nginx内的my-nginx和my-mysql两个容器的相应路径下,其中test-data和test-data-2两个volume对应的CDS为两个容器共享,而nginx-data和db-data两个volume对应的CDS分别只挂载在各自容器中。
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-nginx
spec:
replicas: 1
selector:
matchLabels:
app: mysql-nginx
template:
metadata:
name: mysql-nginx
labels:
app: mysql-nginx
spec:
containers:
- name: my-nginx
image: nginx
volumeMounts:
- name: nginx-data
mountPath: /nginx-data
- name: test-data
mountPath: /test-data
- name: test-data-2
mountPath: /test-data-2
ports:
- containerPort: 80
- name: my-mysql
image: mysql:5.7
volumeMounts:
- name: db-data
mountPath: /db-data
- name: test-data
mountPath: /test-data
- name: test-data-2
mountPath: /test-data-2
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: M6jshva8hTXAGnin
volumes:
- name: db-data
flexVolume:
driver: "baidubce/cds"
fsType: "ext4"
options:
volumeID: "v-Hd8MUXA7"
- name: nginx-data
flexVolume:
driver: "baidubce/cds"
fsType: "ext4"
options:
volumeID: "v-OWEHtlSI"
- name: test-data
flexVolume:
driver: "baidubce/cds"
fsType: "ext4"
options:
volumeID: "v-9PhGVoMu"
- name: test-data-2
flexVolume:
driver: "baidubce/cds"
fsType: "ext4"
options:
volumeID: "v-SxjD482V"
flexVolume字段说明:
- fsType:CDS磁盘的文件系统,如果是新建的CDS磁盘,将会自动格式化该CDS磁盘为该文件系统
- volumeID:CDS磁盘ID,您可以从百度智能云控制台的页面获取
使用 kubectl create -f cds-multi-mount-example.yaml
创建相应的资源,相应的CDS磁盘将会被挂载到文件中声明的各个目录下。Pod在集群内发生漂移时,这些CDS磁盘将会跟随Pod一同迁移。
通过FlexVolume方式挂载
注意:
- CDS 同一时间只能挂载在一台bcc实例上。
- CDS 同一时间只能被一个Pod声明使用。
- 对于 Deployment/ReplicaSet 等资源,replicas 域只能设置为1。
1. 安装 CDS FlexVolume 插件
将如下内容保存为 cds-flexVolume.yaml ,执行 kubectl create -f cds-flexVolume.yaml
安装 cds flexVolume 插件。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: cds-flex-volume-ds
namespace: kube-system
spec:
selector:
matchLabels:
app: cds-flex-volume-ds
template:
metadata:
name: cds-flex-volume-ds
labels:
app: cds-flex-volume-ds
spec:
hostNetwork: true
priorityClassName: system-node-critical
nodeSelector:
beta.kubernetes.io/os: linux
containers:
- image: hub.baidubce.com/jpaas-public/cds-flex-volume:latest
imagePullPolicy: Always
name: cds-flex-volume-ds
resources:
requests:
cpu: 20m
memory: 20Mi
limits:
cpu: 200m
memory: 200Mi
securityContext:
privileged: true
volumeMounts:
- name: flexvolume-mount
mountPath: /flexmnt
- name: log-volume
mountPath: /log-volume
volumes:
- name: flexvolume-mount
hostPath:
path: /usr/libexec/kubernetes/kubelet-plugins/volume/exec
- name: log-volume
hostPath:
path: /var/log
等待对应的 Pod 处于 Running 状态后,插件安装完成。
2. 将 CDS 磁盘挂载到 Pod 中
安装 CDS flexVolume 插件后,下面的示例 cds-example.yaml 将文件中声明的 CDS 磁盘挂载到 Pod 内 my-nginx 容器的 /data 路径下。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 1
selector:
matchLabels:
app: my-nginx
template:
metadata:
name: my-nginx
labels:
app: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
volumeMounts:
- name: cds-data
mountPath: /data
ports:
- containerPort: 80
volumes:
- name: cds-data
flexVolume:
driver: "baidubce/cds"
fsType: "ext4"
options:
volumeID: "v-hTXAGtin"
flexVolume字段说明:
- fsType:CDS磁盘的文件系统,如果是新建的CDS磁盘,将会自动格式化该CDS磁盘为该文件系统
- volumeID:CDS磁盘ID,您可以从百度智能云控制台的页面获取
使用 kubectl create -f cds-example.yaml
创建相应的资源,相应的CDS磁盘将会被挂载到my-nginx容器内的/data目录下。Pod在集群内发生漂移时,该CDS磁盘将会跟随Pod一同迁移。