Kubernetes采用CGroup實現容器的資源隔離。CGroup V2統一了訪問資源的路徑,支持Pod級別的資源監控、網絡重定向,同時在跨多資源協調上具備更強的資源隔離能力。本文介紹如何使用ack-image-builder工具構建CGroup V2的自定義鏡像,并在ACK控制臺使用自定義鏡像創建CGroup V2節點。
背景信息
CGroup
Kubernetes采用CGroup實現容器的資源隔離。CGroup分為V1和V2版本,V2版本提供了更一致的體驗和更豐富的功能。主要特性如下。
統一了訪問資源的路徑,各種資源處于統一路徑下。
新增PSI等功能特性。
支持CGroup級別的eBPF掛載,可以實現Pod級別的資源監控、網絡重定向等。
在跨多資源協調上具備更強的資源隔離能力。
統一地管理各種類型的內存分配,例如網絡內存、Kernel內存等。
支持異步資源變化的統計,例如通過Page Cache的Write-back統計實現異步IO的限制。
Kubernetes在1.18版本中支持CGroup V2,進入Alpha階段,在1.22版本中進入Beta階段,在1.25中進入GA。更多信息,請參見About cgroup v2。
ack-image-builder
ack-image-builder是阿里云推出的一款鏡像構建工具,旨在通過簡易的方式自動化構建鏡像。利用ack-image-builder可以構建出CGroup V2的系統鏡像,方便您在ACK集群中添加CGroup V2的節點。關于ack-image-builder,請參見ack-image-builder。
ack-image-builder基于開源工具HashiCorp Packer開發,HashiCorp Packer提供默認配置模板和校驗腳本。關于HashiCorp Packer,請參見HashiCorp Packer。
使用限制
限制項 | 說明 |
操作系統 | 目前僅Alibaba Cloud Linux 3支持CGroup V2。所以僅支持使用Alibaba Cloud Linux 3作為基礎鏡像來構建支持CGroup V2的自定義鏡像。 |
運行時 | 僅支持containerd運行時。 |
Kubernetes | 1.28及以上版本。 |
應用或組件 | 如果集群上運行的應用或者組件依賴于CGroup,請確保它們與CGroup V2兼容。
|
注意事項
如果使用Java的應用,建議采用JDK 11.0.16或者JDK 15之后的版本,以便與CGroup V2兼容。更多信息,請參見JDK-8230305。
前提條件
已前往配額平臺申請使用自定義鏡像。
操作步驟
使用ack-image-builder創建Kubernetes集群自定義節點鏡像的步驟如下。
安裝Packer。
執行如下命令,下載CGroup V2的配置模板。
git clone https://github.com/AliyunContainerService/ack-image-builder.git cd ack-image-builder
構建CGroup V2的節點自定義鏡像。
執行如下命令,導入AccessKey信息用于創建構建鏡像過程中的臨時資源。
export ALICLOUD_ACCESS_KEY=XXXXXX export ALICLOUD_SECRET_KEY=XXXXXX
執行如下命令,制作自定義鏡像。
packer build -var cgroup_mode=CGROUP_MODE_V2 examples/ack-aliyunlinux3.json
其中
cgroup_mode
的參數為鏡像采用的CGroup模式,默認為CGROUP_MODE_V1
。此處指定為CGROUP_MODE_V2
,構建出的自定義鏡像采用CGroup V2的CGroup模式。salicloud-ecs output will be in this color. ==> alicloud-ecs: Prevalidating source region and copied regions... ==> alicloud-ecs: Prevalidating image name... alicloud-ecs: Found image ID: aliyun_3_x64_20G_alibase_20221102.vhd ==> alicloud-ecs: Creating temporary keypair: xxxxxx ==> alicloud-ecs: Creating vpc... alicloud-ecs: Created vpc: xxxxxx ==> alicloud-ecs: Creating vswitch... alicloud-ecs: Created vswitch: xxxxxx ==> alicloud-ecs: Creating security group... alicloud-ecs: Created security group: xxxxxx ==> alicloud-ecs: Creating instance... alicloud-ecs: Created instance: xxxxxx ==> alicloud-ecs: Allocating eip... alicloud-ecs: Allocated eip: xxxxxx alicloud-ecs: Attach keypair xxxxxx to instance: xxxxxx ==> alicloud-ecs: Starting instance: xxxxxx ==> alicloud-ecs: Using ssh communicator to connect: xx.xx.xx.xx ==> alicloud-ecs: Waiting for SSH to become available... ==> alicloud-ecs: Connected to SSH! ...... ==> alicloud-ecs: Provisioning with shell script: scripts/set-cgroupv2.sh alicloud-ecs: CGROUP_MODE_V2 alicloud-ecs: set cgroup mode to CGROUP_MODE_V2 ...... ==> alicloud-ecs: Stopping instance: xxxxxx ==> alicloud-ecs: Waiting instance stopped: xxxxxx ==> alicloud-ecs: Creating image: test_image1564110199 alicloud-ecs: Detach keypair xxxxxx from instance: xxxxxxx ==> alicloud-ecs: Cleaning up 'EIP' ==> alicloud-ecs: Cleaning up 'instance' ==> alicloud-ecs: Cleaning up 'security group' ==> alicloud-ecs: Cleaning up 'vSwitch' ==> alicloud-ecs: Cleaning up 'VPC' ==> alicloud-ecs: Deleting temporary keypair... Build 'alicloud-ecs' finished. ==> Builds finished. The artifacts of successful builds are: --> alicloud-ecs: Alicloud images were created: cn-hangzhou: m-xxxxxxxxxxxxxxxxx
其中
scripts/set-cgroupv2.sh
為設置CGroup版本,m-xxxxxxxxxxxxxxxxx
為自定義鏡像ID。
采用CGroup V2鏡像創建集群。
下文以創建ACK集群Pro版為例。
登錄集群節點,執行如下命令查看CGroup類型。驗證集群中的節點是否采用了CGroup V2。
df -T /sys/fs/cgroup
預期結果:
Filesystem Type 1K-blocks Used Available Use% Mounted on cgroup2 cgroup2 0 0 0 - /sys/fs/cgroup
表示集群中的節點采用了CGroup V2。
CGroup V2常用使用場景
使用CGroup V2限制容器IO速度
"CGroup V1"對異步的"blockio"統計不準確,導致容器的IO的統計和限制通常大大小于實際應用IO的量。
而在"CGroup V2"中會同時將這部分異步的IO統計到正確容器中,所以我們可以采用"CGroup V2"來限制容器的IO。
限制方式:
通過將對應的磁盤的I/O限制寫入到容器的"CGroupV2"的"io.max"限制文件中達到限制容器IO的效果。
詳細配置內容參考鏈接。
示例:
在容器啟動時,我們對容器的"CGroupV2"做IO的限制,隨后啟動"dd"命令來驗證限制后整體io被控制在限制的帶寬值:
apiVersion: v1
kind: Pod
metadata:
name: write-file-pod
spec:
restartPolicy: Never
containers:
- name: dd-container
image: alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3
command:
- bash
- -c
- "yum install -y sysstat; \
echo '253:0 wbps=10485760' > /sys/fs/cgroup$(cat /proc/1/cgroup | awk -F ':' '{print $3}')/io.max; \
dd if=/dev/zero of=/writefile bs=100M count=10 & iostat -dh 1 30;"
securityContext:
privileged: true
# 其中 "echo '253:0 wbps=10485760' > /sys/fs/cgroup/.../io.max"為io限制配置
# "253:0" 為磁盤的設備id,可以根據實際環境中寫入的磁盤設備調整
# "wbps" 是磁盤寫入帶寬限制, 10485760=10MB/s
將如上Pod部署到集群中后,查看Pod日志可以看到磁盤的IO被限制到配置的10MB/s。
# kubectl logs write-file-pod -f
....
tps kB_read/s kB_wrtn/s kB_read kB_wrtn Device
91.00 0.0k 10.8M 0.0k 10.8M vda
tps kB_read/s kB_wrtn/s kB_read kB_wrtn Device
88.00 0.0k 9.6M 0.0k 9.6M vda