在ACK 1.16版本中实现云盘在线扩容

在 K8S 1.16中,云盘数据卷在线扩容已经进入Beta阶段,功能会默认开启;本文描述了在CSI/Flexvolume环境中如何进行云盘的动态扩容步骤:

使用说明:

1. 数据备份

切记:做数据卷扩容前,先对云盘打快照备份,以防扩容过程异常导致数据出现问题;

2. 适用范围:

只有动态存储卷才可以进行数据卷动态扩容,即:配置了StorageClassName的PV才可以;

不支持InlineVolume类型(非PV、PVC方式)云盘数据卷扩容;

普通云盘类型不支持动态扩容,请参考使用手动扩容云盘方案;

StorageClass需要配置为:AllowVolumeExpansion: True,ACK集群默认为 True;

3. 集群添加扩容权限:

给云盘扩容需要为集群的”RAM 角色“添加ResizeDisk权限:

专有集群(CSI插件):

在集群 --> 管理 --> 集群资源 点击”Master RAM 角色“;编辑Ram权限,添加ResizeDisk如下图:

专有集群(Flexvolume插件)、托管集群:

在集群 --> 管理 --> 集群资源 点击”Worker RAM 角色“;编辑Ram权限,添加ResizeDisk如下图:

在ACK 1.16版本中实现云盘在线扩容

4. 插件升级到最新版本:

升级您使用Flexvolume或者CSI Plugin到最新版本;

云盘数据卷卷扩容:

云盘数据卷扩容包括 ”云盘扩容“ 和 ”文件系统扩容“ 两部分,云盘和文件系统都支持应用在线扩容(设备mount到目录状态下扩容),但是从文件系统扩容最佳实践角度,最稳定的扩容方案是:先停止应用层服务,umount挂载目录,再进行数据卷扩容。

基于稳定性需求,提供以下两种扩容的方式:

pod不重启实现数据卷扩容:在负载高IO情况下,有小概率造成文件系统问题;

Pod重启时实现数据卷扩容:应用停止后,扩容更安全;

K8S 从1.16 开始默认实现了为Pod不重启即可以实现数据卷扩容。

1.容器不重启:

假设应用当前状态如下:

# kubectl get pod
web-0         1/1     Running   0          42s
# kubectl exec web-0 df /data
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/vdb        20511312 45080  20449848   1% /data
# kubectl get pvc
NAME             STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS              AGE
disk-ssd-web-0   Bound    d-wz9hpoifm43yn9zie6gl   20Gi       RWO            alicloud-disk-available   57s
# kubectl get pv
NAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM                    STORAGECLASS              REASON   AGE
d-wz9hpoifm43yn9zie6gl   20Gi       RWO            Delete           Bound      default/disk-ssd-web-0   alicloud-disk-available            65s

在符合 ”使用说明“ 的各个条件下,可以通过下面命令进行数据卷扩容(也可以在控制台编辑pvc的size):

# kubectl patch pvc disk-ssd-web-0 -p '{"spec":{"resources":{"requests":{"storage":"30Gi"}}}}'

等待一定时间(一般一分钟以内)后扩容完成,检查状态如下:

# kubectl get pv d-wz9hpoifm43yn9zie6gl
NAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                    STORAGECLASS              REASON   AGE
d-wz9hpoifm43yn9zie6gl   30Gi       RWO            Delete           Bound    default/disk-ssd-web-0   alicloud-disk-available            5m23s
# kubectl get pvc
NAME             STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS              AGE
disk-ssd-web-0   Bound    d-wz9hpoifm43yn9zie6gl   30Gi       RWO            alicloud-disk-available   5m10s
# kubectl exec web-0 df /data
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/vdb        30832548 45036  30771128   1% /data

综上:只需要执行一条命令既可以完成所有扩容操作。

2.容器重启时扩容:

假设应用当前状态如下:

# kubectl get pod
web-0         1/1     Running   0          42s
# kubectl exec web-0 df /data
/dev/vdb        20511312 45080  20449848   1% /data
# kubectl get pvc
disk-ssd-web-0   Bound    d-wz9g2j5qbo37r2lamkg4   20Gi       RWO            alicloud-disk-available   7m4s
# kubectl get pv d-wz9g2j5qbo37r2lamkg4
d-wz9g2j5qbo37r2lamkg4   20Gi       RWO            Delete           Bound    default/disk-ssd-web-0   alicloud-disk-available            7m18s

1)对于Flexvolume插件挂载的云盘:

查看pv的调度信息:

# kubectl get pv d-wz9g2j5qbo37r2lamkg4  -oyaml | grep failure-domain.beta.kubernetes.io/zone
failure-domain.beta.kubernetes.io/zone: cn-shenzhen-e

修改调度信息label,在zone后面添加字段,促使这个pv关联的pod不可调度(例如:把原来的cn-shenzhen-e 改为 cn-shenzhen-e-nozone):

# kubectl label pv d-wz9g2j5qbo37r2lamkg4 failure-domain.beta.kubernetes.io/zone=cn-shenzhen-e-nozone --overwrite
persistentvolume/d-wz9g2j5qbo37r2lamkg4 labeled

重启Pod,由于修改了调度信息,pod会暂时pending:

# kubectl delete pod web-0
# kubectl get pod
web-0   0/1     Pending   0          27s

执行数据卷扩容命令:

# kubectl patch pvc disk-ssd-web-0 -p '{"spec":{"resources":{"requests":{"storage":"30Gi"}}}}'

将pv的调度信息label改回去,促使pod启动完成(把 cn-shenzhen-e-nozone 改为起初的 cn-shenzhen-e):

# kubectl label pv d-wz9g2j5qbo37r2lamkg4 failure-domain.beta.kubernetes.io/zone=cn-shenzhen-e --overwrite
persistentvolume/d-wz9g2j5qbo37r2lamkg4 labeled

这时整个扩容步骤结束,可以等待一定时间(一般1分钟内)后检查扩容是否符合预期;

# kubectl get pod
web-0   1/1     Running   0          3m23s
# kubectl get pvc
disk-ssd-web-0   Bound    d-wz9g2j5qbo37r2lamkg4   30Gi       RWO            alicloud-disk-available   17m
# kubectl get pv d-wz9g2j5qbo37r2lamkg4
d-wz9g2j5qbo37r2lamkg4   30Gi       RWO            Delete           Bound    default/disk-ssd-web-0   alicloud-disk-available            17m
# kubectl exec web-0 df /data
/dev/vdb        30832548 45036  30771128   1% /data

2)CSI插件挂载的云盘:

向pv中添加调度labels,其value值为一个不存在对应zone的随意字符串,命令如下:

# kubectl label pv d-wz9g2j5qbo37r2lamkg4 failure-domain.beta.kubernetes.io/zone=cn-nozone
persistentvolume/d-wz9g2j5qbo37r2lamkg4 labeled

重启Pod,由于修改了调度信息,pod会暂时pending:

# kubectl delete pod web-0
# kubectl get pod
web-0   0/1     Pending   0          27s

执行数据卷扩容命令:

# kubectl patch pvc disk-ssd-web-0 -p '{"spec":{"resources":{"requests":{"storage":"30Gi"}}}}'

将pv的调度信息label删除,促织pod启动完成:

# kubectl label pv d-wz9g2j5qbo37r2lamkg4 failure-domain.beta.kubernetes.io/zone-
persistentvolume/d-wz9g2j5qbo37r2lamkg4 labeled

这时整个扩容步骤结束,可以等待一定时间(一般1分钟内)后检查扩容是否符合预期;

# kubectl get pod
web-0   1/1     Running   0          3m23s
# kubectl get pvc
disk-ssd-web-0   Bound    d-wz9g2j5qbo37r2lamkg4   30Gi       RWO            alicloud-disk-available   17m
# kubectl get pv d-wz9g2j5qbo37r2lamkg4
d-wz9g2j5qbo37r2lamkg4   30Gi       RWO            Delete           Bound    default/disk-ssd-web-0   alicloud-disk-available            17m
# kubectl exec web-0 df /data
/dev/vdb        30832548 45036  30771128   1% /data