CSI学习笔记-02: 扩容和监控
文章目录
1. CSI 卷扩容
CSI 卷扩容主要通过 external-resizer 、 kubelet 以及以下 RPC 接口实现:
- ControllerExpandVolume:由 ControllerServer 实现,external-resizer 调用
- NodeExpandVolume:由 NodeServer 实现,kubelet 调用(PS:只有在卷绑定到容器时会调用该接口)
整个扩容流程非常清晰:
- external-resizer 通过监听 PVC 的容量变化,判断 PVC 和 PV 的容量大小,决定是否进行扩容;
- external-resizer 调用 ControllerExpandVolume 接口执行扩容操作;
- external-resizer 根据 ControllerExpandVolume 返回的结果,更新 PV 容量(spec.capacity.storage 字段)
- external-resizer 根据 ControllerExpandVolume 返回的信息( NodeExpansionRequired ),为 PVC 添加 Conditions (FileSystemResizePending)
- 当volume处于挂载状态时,kubelet 检查 PVC 对应 Conditions(FileSystemResizePending),并调用 NodeExpandVolume
- 修改 pvc 容量 (status.capacity.storage 字段)
如果 volume 是离线状态的并且 NodeExpansionRequired 为 true,那么扩容会一直处于 pending 状态(FileSystemResizePending conditions 一直存在),直到 pvc 被使用。
2. Liveness Probe
通过 kubernetes-csi/livenessprobe 实现探针,该容器通过 RPC 调用 Probe() 接口。
Probe() 接口在 Identity Service 服务中实现:
|
|
上述返回的异常错误码:
- FAILED_PRECONDITION:表示插件未处于健康/就绪状态或者依赖的组件不健康。
LivenessProbe 容器只是提供 RPC 接口到 HTTPS 接口的转换。
由于 CSI pod 本身不是通过 Service 对外提供服务的,因此 Probe 返回异常或者 False 业务对 CSI RPC 的调用仍是在进行的,通过探针实际上无法起到隔离作用。
3. 卷健康检查
1. KEP-1432: Volume Health Monitor
KEP-1432 中描述了 CSI 卷健康检查功能的概要设计,包括以下内容:
- 设计只包含卷状态信息收集,发现故障后自动恢复的功能没有在设计考虑中。
- external-health-monitor-controller 容器调用 ListVolumes/ControllerGetVolume 接口,获取 Volume Condition 信息
- Kubelet 负责调用 NodeGetVolumeStats 接口,负责采集卷的使用信息/Volume Condition 信息,并提供 VolumeStats metrics API 。
CSI 中关于健康检查的接口包括以下三个:
Interface | Service | Capacity | 备注 |
---|---|---|---|
ListVolumes | ControllerService | LIST_VOLUMES/VOLUME_CONDITION/LIST_VOLUMES_PUBLISHED_NODES | 分页返回所有卷信息 |
ControllerGetVolume | ControllerService | GET_VOLUME/VOLUME_CONDITION/LIST_VOLUMES_PUBLISHED_NODES | 返回指定卷的信息 |
NodeGetVolumeStats | NodeService | GET_VOLUME_STATS/VOLUME_CONDITION | 返回指定卷 Condition 信息和容量使用情况 |
上述三个接口中,ListVolumes 和 ControllerGetVolume 被 external-health-monitor-controller 服务调用,可以只实现其中一个。
2. external-health-monitor 项目
external-health-monitor 项目是 Kubernetes 1.19 版本中引入的,该项目中包含以下两个边车容器:
- external-health-monitor-controller:调用 ListVolumes/ControllerGetVolume 接口,检查所有 bound 状态的 csi 卷。
- external-health-monitor-agent:调用 NodeGetVolumeStats 接口,检查绑定到 pod 的 csi 卷。
上述容器中,controller 主要用于检查存储设备上卷的状态,agent 部署在所有 node 上用于检测 csi 卷到指定节点的连接状态。 controller 还会 watch node 状态,当 node 故障时,如果节点上 pod 使用了对应 PVC 会发出相应 event。
external-health-monitor 容器会根据 csi 接口中返回的 VolumeCondition 判断卷的状态是否符合预期。 当卷的状态异常时创建一条 VolumeConditionAbnormal 类型的 event,当卷从异常状态恢复时创建一条 VolumeConditionNormal 类型的 event。
3.Kubelet 采集 volume 使用率
Kubelet 会通过 csi.socket 调用 NodeGetVolumeStats 接口,相关代码在 “pkg/volume/csi/csiDriverClient.go” 的 NodeGetVolumeStats 函数中,主要用于获取对应的 metrics 信息。
Kubelet 调用 NodeGetVolumeStats 时不会在 NodeGetVolumeStatsRequest 中填充 stagingtargetpath 参数。
Kubernetes 1.21 之后的版本添加了 CSIVolumeHealth 特性,开启这个特性后 Kubelet 会将 NodeGetVolumeStats 接口中获取的 VolumeCondition 信息,更新到 metrics 中。
CSIVolumeHealth 特性取代了 external-health-monitor-agent 容器的部分职责,因此官方建议在高版本的 k8s 中可以不部署该容器。
PS:external-health-monitor-agent容器会创建event,我没有部署高版本 k8s 验证 kubelet 是否同样创建 event.
通过 kubectl get --raw "/api/v1/nodes/<node>/proxy/metrics"
可以看到对于被挂载到 Pod 上的卷,有以下六个指标:
|
|
以上输出是在1.20.11的版本中,并没有 volume condition 指标
参考
文章作者 yoaz
上次更新 2022-04-18
许可协议 MIT