Kuberentes集群添加腾讯云CBS为默认存储
前言
目前公司已经将有状态服务部署在 Kubernetes
集群中,所以对存储能力的需求也越来越强烈。由于我们使用的是灵雀云的产品,部署在腾讯云上所以这里我们使用腾讯云的 CBS
做存储,腾讯自己有自己的开源 CSI
插件来对接 CBS
。
kubernetes-csi-tencentcloud
kubernetes-csi-tencentcloud
是腾讯云 Cloud Block Storage
服务的一个满足 CSI 标准实现的插件。这个插件可以让你在 Kubernetes 上使用 Cloud Block Storage。
特性
- Static Provisioning - 为一个已有的CBS盘创建PV,并在容器中使用PVC来使用它
- Dynamic Provisioning - 在容器需要使用时,根据PVC去创建CBS盘
- specify zone - 指定要在哪个zone创建CBS盘
allowedTopologies
- topology key是topology.com.tencent.cloud.csi.cbs/zone
.diskZone
inStorageClass.parameters
-diskZone
中配置的zone优先级最高. 之后才是allowedTopologies
中的zone
- Topology-Aware - pod被调度完以后,在相应node所在zone创建CBS盘. 如果同时
diskZone
已配置,优先diskZone
- specify zone - 指定要在哪个zone创建CBS盘
- Volume Snapshot - 磁盘快照
- Volume Resizing - 磁盘扩容
- Volume Attach Limit - 单节点最大能attach的CBS盘数量.(每个节点最大可attach 20块CBS盘)
在 Kubernetes 上安装
注意:
在讲述前置要求之前,对于各组件设置参数启动项有些要注意的地方:
- 有些feature gates在GA以后的版本不能再被显式设置,否则可能导致报错。实际上这些feature gates在beta版本开始则无需添加。下表整理了涉及到feature gates的beta版本的表格,在给kubelet、master/controllermanager、scheduler设置启动参数时,可以基于此来做取舍.(举例:KubeletPluginsWatcher在1.12及以上版本则无须添加)
特性 | 默认值 | 阶段 | 起始 | 直到 |
---|---|---|---|---|
VolumeSnapshotDataSource |
true |
Beta | 1.17 | - |
CSINodeInfo |
true |
Beta | 1.14 | 1.16 |
CSIDriverRegistry |
true |
Beta | 1.14 | 1.17 |
KubeletPluginsWatcher |
true |
Beta | 1.12 | 1.12 |
VolumeScheduling |
true |
Beta | 1.10 | 1.12 |
ExpandCSIVolumes |
true |
Beta | 1.16 | - |
前置要求:
- Kubernetes v1.13.x及以上
- kube-apiserver 和 kubelet 的
--allow-privileged
flag 都要设置为 true (针对 v1.15.x 及以上版本, kubelet 默认设置--allow-privileged
为 true,如果仍然显式设置,则会报错 ) - 所有节点的 kubelet 需要添加的启动项为:
--feature-gates=VolumeSnapshotDataSource=true,CSINodeInfo=true,CSIDriverRegistry=true,KubeletPluginsWatcher=true
- apiserver/controller-manager:
--feature-gates=VolumeSnapshotDataSource=true,CSINodeInfo=true,CSIDriverRegistry=true
- scheduler:
--feature-gates=VolumeSnapshotDataSource=true,CSINodeInfo=true,CSIDriverRegistry=true,VolumeScheduling=true
Clone 仓库
注: kubernetes-csi-tencentcloud
中包括 CBS CSI, CFS CSI 与 COSFS CSI。这里我就只用CBS块存储了。其他两个也用过,感觉用起来还是不太适合。
1 |
|
使用腾讯云 API Credential 创建 kubernetes secret:
注: 如果是自建集群,必须创建;而如果是TKE集群环境,可以不创建该secret,driver中默认会根据TKE_QCSRole获取临时秘钥。
1 |
|
创建rbac
创建attacher,provisioner,plugin需要的rbac:
1 |
|
创建controller,node和plugin
Kubernetes v1.18.x及以上版本创建controller plugin和node plugin
1 |
|
Kubernetes v1.18.x以下版本创建controller plugin和node plugin
1 |
|
组件说明
CBS-CSI 组件在集群内部署后,包含以下组件:
- DaemonSet:每个 Node 提供一个 DaemonSet,简称为 NodePlugin。由 CBS-CSI Driver 和 node-driver-registrar 两个容器组成,负责向节点注册 Driver,并提供挂载能力。
- StatefulSet 和 Deployment:简称为 Controller。由 Driver 和多个 Sidecar(external-provisioner、external-attacher、external-resizer、external-snapshotter、snapshot-controller)一起构成,提供创删卷、attach、detach、扩容、快照等能力。
简单测试验证
1 |
|
StorageClass 支持的参数
Note:可以参考示例
- 如果您集群中的节点存在多个可用区,那么您可以开启cbs存储卷的拓扑感知调度,需要在storageclass中添加
volumeBindingMode: WaitForFirstConsumer
,如deploy/examples/storageclass-topology.yaml,否则可能会出现cbs存储卷因跨可用区而挂载失败。 - diskType: 代表要创建的 cbs 盘的类型;值为
CLOUD_PREMIUM
代表创建高性能云盘,值为CLOUD_SSD
代表创建 ssd 云盘,值为CLOUD_HSSD
代表创建增强型SSD云盘, - diskChargeType: 代表云盘的付费类型;值为
PREPAID
代表预付费,值为POSTPAID_BY_HOUR
代表按量付费,需要注意的是,当值为PREPAID
的时候需要指定额外的参数 - diskChargeTypePrepaidPeriod:代表购买云盘的时长,当付费类型为
PREPAID
时需要指定,可选的值包括1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 24, 36
,单位为月 - diskChargePrepaidRenewFlag: 代表云盘的自动续费策略,当付费类型为
PREPAID
时需要指定,值为NOTIFY_AND_AUTO_RENEW
代表通知过期且自动续费,值为NOTIFY_AND_MANUAL_RENEW
代表通知过期不自动续费,值为DISABLE_NOTIFY_AND_MANUAL_RENEW
代表不通知过期不自动续费 - encrypt: 代表云盘是否加密,当指定此参数时,唯一可选的值为
ENCRYPT
- disktags: 可以给云盘加tag。形式如
a:b,c:d
- throughputperformance: 对hssd/tssd盘,如果需要达到最大性能,可以填入额外性能。具体取值参见https://cloud.tencent.com/document/product/362/51896
- cdcid: 独占集群ID
不同类型云盘的大小限制
云盘大小仅支持 10 的倍数(如: 100, 110, 120)
- 高性能云硬盘提供最小 10 GB 到最大 32000 GB 的规格选择。
- SSD云硬盘提供最小 20 GB 到最大 32000 GB 的规格选择,单块 SSD 云硬盘最高可提供 26000 随机读写IOPS、260MB/s吞吐量的存储性能。
- 增强型SSD云硬盘提供最小 20 GB 到最大 32000 GB 的规格选择,单盘最高可提供 100000 随机读写IOPS、1000MB/s吞吐量的存储性能。
通过 CBS-CSI 避免云硬盘跨可用区挂载
操作场景
云硬盘不支持跨可用区挂载到节点,在跨可用区的集群环境中,推荐通过 CBS-CSI 拓扑感知特性来避免跨可用区挂载问题。
实现原理
拓扑感知调度需要多个 Kubernetes 组件配合完成,包括 Scheduler、PV controller、external-provisioner。具体流程如下:
- PV controller 观察 PVC 对象,检查 Storageclass 的 VolumeBindingMode 是否为 WaitForFirstConsumer,如是,则不会立即处理该 PVC 的创建事件,等待 Scheduler 处理。
- Scheduler 调度 Pod 后,会将 nodeName 以 annotation 的方式加入到 PVC 对象上
volume.kubernetes.io/selected-node: 10.0.0.72
。 - PV controller 获取到 PVC 对象的更新事件后,将开始处理 annotation(
volume.kubernetes.io/selected-node
),根据 nodeName 获取 Node 对象,传入到 external-provisioner 中。 - external-provisioner 根据传过来的 Node 对象的 label 获取可用区(
failure-domain.beta.kubernetes.io/zone
)后在对应可用区创建 PV,达到和 Pod 相同可用区的效果,避免云硬盘和 Node 在不同可用区而无法挂载问题。
前提条件
操作步骤
使用以下 YAML,在 Storageclass 中设置 volumeBindingMode 为 WaitForFirstConsumer。示例如下:
1 |
|
CBS-CSI 和 In-Tree 组件均支持该操作。
在线扩容云硬盘
操作场景
TKE 支持在线扩容 PV、对应的云硬盘及文件系统,即不需要重启 Pod 即可完成扩容。为确保文件系统的稳定性,建议在云硬盘文件系统处于未挂载状态时进行操作。
前提条件
操作步骤
创建允许扩容的 StorageClass
使用以下 YAML 创建允许扩容的 StorageClass,在 Storageclass 中设置 allowVolumeExpansion
为 true
。示例如下:
1 |
|
在线扩容
提供以下两种扩容方式:
扩容方式 | 说明 |
---|---|
重启 Pod 的情况下在线扩容 | 待扩容的云硬盘文件系统未被挂载,能够避免扩容出错以及方式2存在的问题。推荐使用该方式进行扩容。 |
不重启 Pod 的情况下在线扩容 | 在节点上挂载着待扩容的云硬盘文件系统,如果存在 I/O 进程,将可能出现文件系统扩容错误。 |
重启Pod情况下在线扩容
1.执行以下命令,确认扩容前 PV 和文件系统状态。示例如下,PV 和文件系统大小均为30G:
1 |
|
2.执行以下命令,为 PV 对象打上一个非法 zone 标签,旨在下一步重启 Pod 后,使 Pod 无法调度到某个节点上。示例如下:
1 |
|
3.执行以下命令重启 Pod,重启后由于 Pod 对应的 PV 的标签表明的是非法 zone,Pod 将处于 Pending 状态。示例如下:
1 |
|
4.执行以下命令,修改 PVC 对象中的容量,将容量扩容至40G。示例如下:
1 |
|
注意:扩容后的PVC对象容量的大小必须为10的倍数,不同云硬盘类型所支持的存储容量规格可参考说明 创建云硬盘。
5.执行以下命令,去除 PV 对象之前打上的标签, 标签去除之后 Pod 即可调度成功。示例如下:
1 |
|
6.执行以下命令,可以查看到 Pod 状态为 Running、对应的 PV 和文件系统扩容成功,从30G扩容到40G。示例如下:
1 |
|
不重启Pod情况下在线扩容
1.执行以下命令,确认扩容前 PV 和文件系统状态。示例如下,PV 和文件系统大小均为20G:
1 |
|
2.执行以下命令,修改 PVC 对象中的容量,将容量扩容至30G。示例如下:
1 |
|
扩容后的PVC对象容量的大小必须为10的倍数,不同硬盘类型所支持的存储容量规格可参考说明 创建云硬盘。
3.执行以下命令,可以查看到 PV 和文件系统已扩容至30G。示例如下:
1 |
|