旧瓶也能装新酒——在AKS使用共享磁盘

  从v1.17开始,k8s启用了CSI的存储驱动,并且按k8s的roadmap,在v1.21要全部换到CSI。Azure上的k8s服务——aks已经开始CSI的preview,并且增加了若干新功能,其中一个重要功能就是支持Azure Shared Disk,可以在多个pod甚至nod上共享一块磁盘。当然,为了避免存储脑裂,需要从应用进行磁盘锁、仲裁、读写控制等。这个功能大大扩展了k8s的使用场景。

  可能很多人都有疑问,k8s本身就支持NFS或SMB的NAS模式,可以直接提供持久化卷的共享,为什么还要支持共享磁盘?原因在于,共享磁盘和NAS从读写操作原理是不一样的。磁盘提供块级(结构化)存储,用户可以自己控制文件系统;而NAS提供的文件级(非结构化)共享。很多场景,例如oracle rac只支持共享磁盘,而无法用NAS存放数据文件。
  下边就通过实际操作暂时如果在aks中使用共享磁盘。

创建aks集群

  目前aks的CSI还在preview阶段,所以需要用cli方式启用并创建集群。

启用CSI

  执行如下命令启用CSI:
az feature register --namespace "Microsoft.ContainerService" --name "EnableAzureDiskFileCSIDriver"
  然后执行如下命令使改动生效:
az provider register -n Microsoft.ContainerService
-w690

  安装支持CSI的cli命令扩展:
az extension add --name aks-preview
az extension update --name aks-preview
-w646

  创建资源组并创建启用CSI的集群:
az group create -n aks-csi-rg -l westus2 -o table
az aks create -g aks-csi-rg -n aks-csi-cluster --network-plugin azure -k 1.18.14 --generate-ssh-keys --aks-custom-headers EnableAzureDiskFileCSIDriver=true -o table
-w961

==注意:参数-k 1.18.14指定k8s版本,必须大于1.17;参数–aks-custom-headers EnableAzureDiskFileCSIDriver=true指定启用CSI驱动==
  为了方便管理,在VS Code里添加此集群:
-w1508

  检查StorageClass,可以看到有CSI驱动:
kubectl get sc
-w970

创建共享磁盘

创建共享磁盘的StorageClass

  创建名为shared-disk-class.yaml的文件,内容如下:

1
2
3
4
5
6
7
8
9
10
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: shared-disk
provisioner: disk.csi.azure.com
parameters:
skuname: Premium_LRS
maxShares: "2"
cachingMode: None
reclaimPolicy: Delete

  这个文件指明如下内容:

  • StorageClass的名字:shared-disk,创建此类型数据卷时要指明此名字
  • 对应的Azure磁盘类型:Premium_LRS,目前shared disk只支持premium disk和ultra disk
  • 最大可以共享主机数量:2
  • 不使用cache,shared disk不允许使用读缓存
  • 回收模式为删除

  通过如下命令应用此配置:
kubectl apply -f shared-disk-class.yaml
-w1552

  再次检查StorageClass,可以看到新建的类型:
-w970

  创建名为shared-disk-pvc.yaml的文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: shared-disk-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 256Gi
volumeMode: Block
storageClassName: shared-disk

  这个文件指明如下内容:

  • pvc的名字:shared-disk-pvc
  • 套用的StorageClass:shared-disk
  • 访问方式:ReadWriteMany,允许多个主机访问,但不能超过StorageClass里定义的maxShares
  • 卷类型:block,这是固定配置
  • 容量:256GiB,低于此容量的磁盘不允许共享(具体可查询shared disk的容量和主机数量关系)

  应用此文件:
kubectl apply -f shared-disk-pvc.yaml
-w1508

  展开集群的存储资源,可以看到新建的pvc,并根据此pvc创建了新的pv:
-w1508

  在Azure Portal的disk里,也可以看到新建的磁盘:

  但因为现在还没有container使用该磁盘,所以没有owner。

使用共享磁盘

  创建一个Deployment,部署两个副本的pod,并将新建卷挂载到pod,由于负载均衡,这两个pod会自动分配到两个node,这样可以验证是否可以共享磁盘。
  Deployment的配置文件shared-disk-deploy.yaml内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: deployment-azuredisk
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
name: deployment-azuredisk
spec:
containers:
- name: deployment-azuredisk
image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
volumeDevices:
- name: azuredisk
devicePath: /dev/sdx
volumes:
- name: azuredisk
persistentVolumeClaim:
claimName: shared-disk-pvc

  这个文件指明如下内容:

  • 声明卷名字:azure-shared-disk,来源是名为shared-disk-pvc的pvc
  • pod内部,将此卷映射到/dev/sdx
  • pod的副本数量为2
  • 使用的image:mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine,这是一个专门镜像,具备ha机制,可以共享磁盘

  执行命令创建deployment:
kubectl apply -f shared-disk-deploy.yaml
-w1552

  在Azure Portal检查磁盘,已经被挂载到两台主机(node):

小结

  CSI驱动为k8s的卷管理提供了更多的高级功能,不仅是共享磁盘,aks也可以原生支持Azure Premium File提供的NFS,预知如何实现,请听下回分解。