阿里云容器服务 Kubernetes 使用动态云盘的方式
2020-12-18 本文已影响0人
awker
动态云盘的使用场景
没有购买云盘,在应用部署时自动购买云盘的情况。
动态云盘的使用方式:
方式一:手动创建 PVC,在 PVC 中声明 StorageClass。
方式二:部署应用时通过 volumeClaimTemplates 使用 StorageClass 自动创建 PV。
方式一:手动创建 PVC,在 PVC 中声明 StorageClass
使用步骤为:
- 创建 StorageClass。
- 创建 PVC,会自动创建 PC 和 云盘。
- 创建应用,应用通过 persistentVolumeClaim 使用 PVC。
1、创建 StorageClass,查看到已有的 StorageClass 已经可以满足要求,所以不用创建 StorageClass。
// 查看创建的 StorageClass。
# kubectl get storageclass -o wide
NAME PROVISIONER AGE
alicloud-disk-available alicloud/disk 13d
alicloud-disk-common alicloud/disk 13d
alicloud-disk-efficiency alicloud/disk 13d
alicloud-disk-ssd alicloud/disk 13d
// 这里使用了 StorageClass 的缩写形式。所有资源名的缩写形式可参考:https://kubernetes.io/zh/docs/reference/kubectl/overview/#%E8%B5%84%E6%BA%90%E7%B1%BB%E5%9E%8B 。
# kubectl get sc alicloud-disk-ssd -o yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{},"name":"alicloud-disk-ssd"},"parameters":{"type":"cloud_ssd"},"provisioner":"alicloud/disk"}
creationTimestamp: "2020-12-04T10:09:23Z"
name: alicloud-disk-ssd # StorageClass 的名称为 alicloud-disk-ssd ,很重要的值。后续可以通过 StorageClass 创建 PV 和 PVC。
resourceVersion: "1010"
selfLink: /apis/storage.k8s.io/v1/storageclasses/alicloud-disk-ssd
uid: c86ad236-3618-11eb-848c-00163e01064f
parameters:
type: cloud_ssd # 自动创建云盘的类型,支持 cloud、cloud_efficiency、cloud_ssd、available。
provisioner: alicloud/disk # 动态云盘配置为 alicloud/disk,标识使用 provisioner 插件自动创建阿里云云盘。
reclaimPolicy: Delete # 云盘的回收策略。支持 Delete 和 Retain,默认情况为 Delete。如果配置为 Delete,删除 PVC 时,云盘会一起删除,云盘上的数据不可恢复。
volumeBindingMode: Immediate
storageclass 详细说明参考:https://help.aliyun.com/document_detail/128558.html
- alicloud-disk-common:自动创建普通云盘。
- alicloud-disk-efficiency:自动创建高效云盘。
- alicloud-disk-ssd:自动创建 SSD 云盘。
- alicloud-disk-available:提供高可用选项,先尝试自动创建高效云盘;如果相应可用区的高效云盘资源售尽,再尝试自动创建 SSD 云盘,如果该可用区的 SSD 云盘也售尽,则尝试自动创建普通云盘。
2. 创建 PVC,名称为 storageclass-pvc-pv-ssd。
# vim storageclass-pvc-pv-ssd.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
# PVC 的名称为 storageclass-pvc-pv-ssd, 应用会使用这个 PVC 名称。
name: storageclass-pvc-pv-ssd
spec:
# 参考:https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/#access-modes
# ReadWriteOnce -- 卷可以被一个 Pod 以读写方式挂载;ReadWriteMany -- 卷可以被多个 Pod 以读写方式挂载;ReadOnlyMany -- 卷可以被多个 Pod 以只读方式挂载。
accessModes:
- ReadWriteOnce
# 使用自动创建 SSD 云盘的 storageclass 。
storageClassName: alicloud-disk-ssd
resources:
requests:
# 申请创建的 SSD 云盘大小为 20Gi。
storage: 20Gi
// 执行 kubectl 创建 PVC ,会自动创建 PV 和 SSD 云盘。
# kubectl create -f storageclass-pvc-pv-ssd.yaml
persistentvolumeclaim/storageclass-pvc-pv-ssd created
// 查看创建的 PVC。
# kubectl get pvc storageclass-pvc-pv-ssd -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
storageclass-pvc-pv-ssd Bound d-a0z01d87c2i29txknmn3 20Gi RWO alicloud-disk-ssd 56s
// 查看创建的 PV 和 SSD 云盘,d-a0z01d87c2i29txknmn3 既是 PV 的名称,又是云盘的 ID。
# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
d-a0z01d87c2i29txknmn3 20Gi RWO Delete Bound default/storageclass-pvc-pv-ssd alicloud-disk-ssd 115s
3. 创建应用,应用通过 persistentVolumeClaim 使用 PVC。
# vim nginx-pvc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-pvc
labels:
app: nginx-pvc
spec:
# replicas: 1
# Deployment nginx-pvc 使用的标签为 app: nginx-example。
selector:
matchLabels:
app: nginx-example
template:
metadata:
# Pod 的标签为 app: nginx-example。
labels:
app: nginx-example
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
# 使用存储卷 disk-ssd-pvc。
- name: disk-ssd-pvc
# 挂载在 Pod 的目录为 /data。
mountPath: "/data"
volumes:
# 存储卷的名称为 disk-ssd-pvc。
- name: disk-ssd-pvc
persistentVolumeClaim:
# 使用创建的 PVC。
claimName: storageclass-pvc-pv-ssd
// 执行 kubectl 创建 Deployment。
# kubectl create -f nginx-pvc.yaml
deployment.apps/nginx-pvc created
// 查看创建的 Deployment。
# kubectl get deploy -o wide --show-labels
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR LABELS
nginx-pvc 1/1 1 1 3m29s nginx nginx app=nginx-example app=nginx-pvc
// 查看通过 Deployment 创建的 Pod。
# kubectl get pod -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
nginx-pvc-7d87475fbd-lx5x6 1/1 Running 0 5m27s 172.20.2.3 cn-shanghai-cf-d01.i-a0z01nzs2pkled5iikc9 <none> <none> app=nginx-example,pod-template-hash=7d87475fbd
// 测试销毁现有的 Pod,Deployment 重新生成新的 Pod 后,数据是否还会存在。
// 创建一个测试文件 test.txt。
# kubectl exec nginx-pvc-7d87475fbd-lx5x6 -- touch /data/test.txt
# kubectl exec nginx-pvc-7d87475fbd-lx5x6 -- ls -l /data
total 16
drwx------ 2 root root 16384 Dec 18 09:38 lost+found
-rw-r--r-- 1 root root 0 Dec 18 09:50 test.txt
// 测试销毁现有的 Pod。
# kubectl delete pod nginx-pvc-7d87475fbd-lx5x6
pod "nginx-pvc-7d87475fbd-lx5x6" deleted
# kubectl get pod -o wide --show-labels
nginx-pvc-7d87475fbd-42ntt 1/1 Running 0 53s 172.20.2.4 cn-shanghai-cf-d01.i-a0z01nzs2pkled5iikc9 <none> <none> app=nginx-example,pod-template-hash=7d87475fbd
// 可知,销毁现有的 Pod ,Deployment 重新生成新的 Pod 后,Pod PVC 的数据还存在。
# kubectl exec nginx-pvc-7d87475fbd-42ntt -- ls -l /data
total 16
drwx------ 2 root root 16384 Dec 18 09:38 lost+found
-rw-r--r-- 1 root root 0 Dec 18 09:50 test.txt
方式二:部署应用时通过 StorageClass 自动创建 PV。
使用步骤为:
- 创建 StorageClass。
- 部署应用时通过 volumeClaimTemplates 使用 StorageClass 自动创建 PV、 PVC 和 云盘。
1、创建 StorageClass,查看到已有的 StorageClass 已经可以满足要求,所以不用创建 StorageClass。
# kubectl get storageclass -o wide
NAME PROVISIONER AGE
alicloud-disk-available alicloud/disk 13d
alicloud-disk-common alicloud/disk 13d
alicloud-disk-efficiency alicloud/disk 13d
alicloud-disk-ssd alicloud/disk 13d
2、部署应用时通过 volumeClaimTemplates 使用 StorageClass 自动创建 PV、 PVC 和 云盘。
// 注意:PVC 的名称有要求,不能使用大写字母,不然报下面错误:
// a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.',
// and must start and end with an alphanumeric character (e.g. 'example.com',
// regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')
# vim nginx-storageclass-pvc-pv-ssd.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx-service
spec:
ports:
- port: 80
name: web
# Statefulset 的 Service 必须是 headless 模式。
clusterIP: None
selector:
# Service nginx-service 选择标签为 app: nginx-example-volumeClaimTemplates 的 Pod。
app: nginx-example-volumeClaimTemplates
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
# StatefulSet metadata.name 用来生成有规律的 Pod 名称和主机名。不是用来给 Service 标签选择器来选择的。
name: nginx-ssd
labels:
app: nginx-ssd
spec:
# serviceName 会和每个 Pod 的 /etc/hosts 记录有关系,
# 比如 nginx-ssd-1.nginx-example-vct.default.svc.cluster.local,
# 就由 metadata.name(nginx-ssd-1,有序后缀是 StatefulSet 添加的) 、spec.serviceName(nginx-example-vct)、命名空间 NAMESPACE(default)、服务类型(svc)、集群域名(cluster.local)组成
serviceName: nginx-example-vct
replicas: 3
# StatefulSet nginx-ssd 选择标签为 app: nginx-example-volumeClaimTemplates 的 template,创建 Pod 副本。
selector:
matchLabels:
app: nginx-example-volumeClaimTemplates
template:
metadata:
# 此 template Pod 的标签为 app: nginx-example-volumeClaimTemplates。
labels:
app: nginx-example-volumeClaimTemplates
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
# 使用 PVC disk-ssd-vct,由 storageClassName 动态创建。
- name: disk-ssd-vct
# 挂载在 Pod 的目录为 /data。
mountPath: "/data"
volumeClaimTemplates:
- metadata:
name: disk-ssd-vct
spec:
# https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/#access-modes
# ReadWriteOnce -- 卷可以被一个 Pod 以读写方式挂载;ReadWriteMany -- 卷可以被多个 Pod 以读写方式挂载;ReadOnlyMany -- 卷可以被多个 Pod 以只读方式挂载。
accessModes: [ "ReadWriteOnce" ]
# 使用自动创建 SSD 云盘的 storageclass 。
storageClassName: "alicloud-disk-ssd"
resources:
requests:
# 申请创建的 SSD 云盘大小为 20Gi。
storage: 20Gi
// 执行 kubectl 创建 Service 和 StatefulSet。
# kubectl create -f nginx-storageclass-pvc-pv-ssd.yaml
service/nginx-service created
statefulset.apps/nginx-ssd created
// 查看创建的 Service 。
# kubectl get svc -o wide --show-labels
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR LABELS
nginx-service ClusterIP None <none> 80/TCP 17s app=nginx-example-volumeClaimTemplates app=nginx-service
// 查看创建的 StatefulSet
# kubectl get sts -o wide --show-labels
NAME READY AGE CONTAINERS IMAGES LABELS
nginx-ssd 3/3 55s nginx nginx app=nginx-ssd
// 查看通过 StatefulSet 创建的 Pod,Pod name 命名规则是 StatefulSet 的 metadata.name 加上数字从 0 开始递增。
# kubectl get pod -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
nginx-ssd-0 1/1 Running 0 83s 172.20.2.5 cn-shanghai-cf-d01.i-a0z01nzs2pkled5iikc9 <none> <none> app=nginx-example-volumeClaimTemplates,controller-revision-hash=nginx-ssd-79dc75fb7d,statefulset.kubernetes.io/pod-name=nginx-ssd-0
nginx-ssd-1 1/1 Running 0 66s 172.20.1.68 cn-shanghai-cf-d01.i-a0z01nzs2pkenajfz769 <none> <none> app=nginx-example-volumeClaimTemplates,controller-revision-hash=nginx-ssd-79dc75fb7d,statefulset.kubernetes.io/pod-name=nginx-ssd-1
nginx-ssd-2 1/1 Running 0 56s 172.20.1.9 cn-shanghai-cf-d01.i-a0z01nzs2pkenajfz76a <none> <none> app=nginx-example-volumeClaimTemplates,controller-revision-hash=nginx-ssd-79dc75fb7d,statefulset.kubernetes.io/pod-name=nginx-ssd-2
// 查看通过 StorageClass 自动创建 PV。
# kubectl get pv -o wide --show-labels
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE LABELS
d-a0z01d87c2i2avf5so6e 20Gi RWO Delete Bound default/disk-ssd-vct-nginx-ssd-0 alicloud-disk-ssd 3m4s failure-domain.beta.kubernetes.io/region=cn-shanghai-cf-d01,failure-domain.beta.kubernetes.io/zone=cn-shanghai-cf-am15001-a
d-a0z01d87c2i2avf5so6f 20Gi RWO Delete Bound default/disk-ssd-vct-nginx-ssd-1 alicloud-disk-ssd 2m54s failure-domain.beta.kubernetes.io/region=cn-shanghai-cf-d01,failure-domain.beta.kubernetes.io/zone=cn-shanghai-cf-am15001-a
d-a0z01nzs2pklun5nzlnp 20Gi RWO Delete Bound default/disk-ssd-vct-nginx-ssd-2 alicloud-disk-ssd 2m34s failure-domain.beta.kubernetes.io/region=cn-shanghai-cf-d01,failure-domain.beta.kubernetes.io/zone=cn-shanghai-cf-am15001-a
// 查看通过 StorageClass 自动创建 PV 和 云盘。
[root@cnszyf02001 example]# kubectl get pvc -o wide --show-labels
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE LABELS
disk-ssd-vct-nginx-ssd-0 Bound d-a0z01d87c2i2avf5so6e 20Gi RWO alicloud-disk-ssd 3m43s app=nginx-example-volumeClaimTemplates
disk-ssd-vct-nginx-ssd-1 Bound d-a0z01d87c2i2avf5so6f 20Gi RWO alicloud-disk-ssd 3m18s app=nginx-example-volumeClaimTemplates
disk-ssd-vct-nginx-ssd-2 Bound d-a0z01nzs2pklun5nzlnp 20Gi RWO alicloud-disk-ssd 3m7s app=nginx-example-volumeClaimTemplates
// 测试销毁现有的 Pod ,StatefulSet 重新生成新的 Pod 后,数据是否还会存在。以及 主机名、Pod 名称、Pod IP 是否改变。
// 创建一个测试文件 sts.txt。
# kubectl exec nginx-ssd-1 -- touch /data/sts.txt
# kubectl exec nginx-ssd-1 -- ls -l /data
total 16
drwx------ 2 root root 16384 Dec 18 10:38 lost+found
-rw-r--r-- 1 root root 0 Dec 18 11:42 sts.txt
// 查看 Pod 主机名、Pod 名称、Pod IP。--> 结合 kubectl get pod 的结果,可知 Pod 主机名为 nginx-ssd-1,Pod 名称为 nginx-ssd-1, Pod IP 为 172.20.1.68。
# kubectl exec nginx-ssd-1 -- hostname
nginx-ssd-1
// 测试销毁现有的 Pod 。
# kubectl delete pod nginx-ssd-1
pod "nginx-ssd-1" deleted
// 可知,销毁现有的 Pod ,StatefulSet 重新生成新的 Pod 后,数据还会存在、主机名、Pod 名称不变。但是,Pod IP 是会改变的。
# kubectl get pod nginx-ssd-1 -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
nginx-ssd-1 1/1 Running 0 79s 172.20.1.69 cn-shanghai-cf-d01.i-a0z01nzs2pkenajfz769 <none> <none> app=nginx-example-volumeClaimTemplates,controller-revision-hash=nginx-ssd-79dc75fb7d,statefulset.kubernetes.io/pod-name=nginx-ssd-1
# kubectl exec nginx-ssd-1 -- ls -l /data
total 16
drwx------ 2 root root 16384 Dec 18 10:38 lost+found
-rw-r--r-- 1 root root 0 Dec 18 11:42 sts.txt
# kubectl exec nginx-ssd-1 -- hostname
nginx-ssd-1
参考: