ack-koordinator提供對Pod內存參數動態修改的能力,可以在不重啟Pod的情況下,修改CPU、內存、磁盤IO等單機隔離參數。本文介紹如何使用ack-koordinator動態修改Pod資源參數。
前提條件
已通過kubectl連接Kubernetes集群。具體操作,請參見獲取集群KubeConfig并通過kubectl工具連接集群。
已安裝ack-koordinator組件(原ack-slo-manager),且版本≥0.5.0。關于安裝ack-koordinator的具體操作,請參見ack-koordinator(ack-slo-manager)。
說明ack-koordinator適配了原resource-controller組件的所有功能,如果您正在使用resource-controller,請您先卸載resource-controller,再安裝ack-koordinator。卸載組件的具體操作,請參見卸載resource-controller。
費用說明
ack-koordinator組件本身的安裝和使用是免費的,不過需要注意的是,在以下場景中可能產生額外的費用:
ack-koordinator是非托管組件,安裝后將占用Worker節點資源。您可以在安裝組件時配置各模塊的資源申請量。
ack-koordinator默認會將資源畫像、精細化調度等功能的監控指標以Prometheus的格式對外透出。若您配置組件時開啟了ACK-Koordinator開啟Prometheus監控指標選項并使用了阿里云Prometheus服務,這些指標將被視為自定義指標并產生相應費用。具體費用取決于您的集群規模和應用數量等因素。建議您在啟用此功能前,仔細閱讀阿里云Prometheus的計費概述,了解自定義指標的收費策略。您可以通過資源消耗統計功能,監控和管理您的資源使用情況。
背景信息
根據目前Kubernetes的設計規范,在Pod運行過程中如果需要臨時修改容器參數,只能更新PodSpec后重新提交,這種方式會觸發Pod刪除重建。ack-koordinator提供動態修改Pod資源參數功能,可以在不重啟Pod的前提下對參數進行臨時修改。
使用場景
動態修改Pod資源參數功能適用于臨時性的調整,例如當Pod內存使用率逐漸升高,為避免觸發OOM(Out Of Memory)Killer,希望在不重啟Pod的前提下提高內存的Limit。對于正式的常規性運維操作,強烈建議您使用CPU Burst性能優化策略、CPU拓撲感知調度、資源畫像等功能。
修改內存限制參數
您可以通過Cgroup動態修改容器的內存限制,具體操作步驟如下。
修改內存限制參數的功能僅支持K8s 1.22及更早版本,其他資源參數的修改不受K8s版本限制。
對于常規調整CPU Limit的場景,強烈建議您使用CPU Burst性能優化策略功能,可以自動調整Pod的CPU資源彈性。更多信息,請參見CPU Burst性能優化策略。若您仍需要臨時調整CPU Limit的能力,請參考從resource-controller遷移至ack-koordinator。
使用以下YAML內容,創建pod-demo.yaml文件。
apiVersion: v1 kind: Pod metadata: name: pod-demo spec: containers: - name: pod-demo image: polinux/stress resources: requests: cpu: 1 memory: "50Mi" limits: cpu: 1 memory: "1Gi" #內存限制值為1 GB。 command: ["stress"] args: ["--vm", "1", "--vm-bytes", "256M", "-c", "2", "--vm-hang", "1"]
執行以下命令,將pod-demo部署到集群中。
kubectl apply -f pod-demo.yaml
執行以下命令,查看當前容器的初始內存限制值。
#具體路徑可根據Pod的UID以及Container的ID拼接得到。 cat /sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podaf44b779_41d8_43d5_a0d8_8a7a0b17****.slice/memory.limit_in_bytes
預期輸出:
#對應為1 GB,即1*1024*1024*1024=1073741824。 1073741824
由預期輸出得到,當前容器的初始內存限制值為1 GB,與步驟1的
spec.containers.resources.limits.memory
描述一致。使用以下YAML內容,創建cgroups-sample.yaml文件。
文件中指定了需要動態修改容器的內存限制值。
apiVersion: resources.alibabacloud.com/v1alpha1 kind: Cgroups metadata: name: cgroups-sample spec: pod: name: pod-demo namespace: default containers: - name: pod-demo memory: 5Gi #指定Pod的內存限制值為5 GB。
執行以下命令,將cgroups-sample部署到集群中。
kubectl apply -f cgroups-sample.yaml
執行以下命令,查看修改后容器的內存限制值。
#具體路徑可根據Pod的UID以及Container的ID拼接得到。 cat /sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podaf44b779_41d8_43d5_a0d8_8a7a0b17****.slice/memory.limit_in_bytes
預期輸出:
#對應為5 GB,即5*1024*1024*1024=5368709120 5368709120
由預期輸出得到,容器的內存限制值為5 GB,與步驟4的
spec.pod.containers.memory
描述一致。執行以下命令,查看Pod運行情況。
kubectl describe pod pod-demo
預期輸出:
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 13m default-scheduler Successfully assigned default/pod-demo to cn-zhangjiakou.192.168.3.238 Normal Pulling 13m kubelet, cn-zhangjiakou.192.168.3.238 Pulling image "polinux/stress" Normal Pulled 13m kubelet, cn-zhangjiakou.192.168.3.238 Successfully pulled image "polinux/stress"
由預期輸出得到,
Events
中不存在Pod重啟的相關信息,Pod運行正常。
修改CPU綁定范圍
綁定范圍是指Pod可使用的具體CPU編號,您可以通過Cgroups為Pod指定CPU的綁定范圍。修改Pod的CPU綁定范圍的具體操作如下。
對于常規的CPU綁定場景,強烈建議您使用CPU拓撲感知調度功能,為CPU敏感型的工作負載提供更好的性能。更多信息,請參見CPU拓撲感知調度。
使用以下YAML內容,創建pod-cpuset-demo.yaml文件。
apiVersion: v1 kind: Pod metadata: name: pod-cpuset-demo spec: containers: - name: pod-cpuset-demo image: polinux/stress resources: requests: memory: "50Mi" limits: memory: "1000Mi" cpu: 0.5 command: ["stress"] args: ["--vm", "1", "--vm-bytes", "556M", "-c", "2", "--vm-hang", "1"]
執行以下命令,將pod-cpuset-demo部署到集群中。
kubectl apply -f pod-cpuset-demo.yaml
執行以下命令,查看當前容器的CPU核心綁定情況。
cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf9b79bee_eb2a_4b67_befe_51c270f8****.slice/cri-containerd-aba883f8b3ae696e99c3a920a578e3649fa957c51522f3fb00ca943dc2c7****.scope/cpuset.cpus
預期輸出:
0-31
由預期輸出得到,未綁定CPU前,可使用的CPU編號范圍為0~31,表示CPU目前沒有約束。
使用以下YAML內容,創建cgroups-sample-cpusetpod.yaml文件。
文件中指定了CPU的綁定信息。
apiVersion: resources.alibabacloud.com/v1alpha1 kind: Cgroups metadata: name: cgroups-sample-cpusetpod spec: pod: name: pod-cpuset-demo namespace: default containers: - name: pod-cpuset-demo cpuset-cpus: 2-3 #將Pod綁定到CPU2和CPU3上。
執行以下命令,將cgroups-sample-cpusetpod部署到集群中。
kubectl apply -f cgroups-sample-cpusetpod.yaml
執行以下命令,查看當前容器修改后的CPU核心綁定情況。
#實際路徑可根據Pod的UID以及Container的ID拼接得到。 cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-podf9b79bee_eb2a_4b67_befe_51c270f8****.slice/cri-containerd-aba883f8b3ae696e99c3a920a578e3649fa957c51522f3fb00ca943dc2c7****.scope/cpuset.cpus
預期輸出:
2-3
由預期輸出得到,容器綁定到CPU2和CPU3上,與步驟4的
spec.pod.containers.cpuset-cpus
描述一致。
修改Deployment級別參數
您可以通過Cgroups動態修改Deployment級別參數,具體操作步驟如下。
使用以下YAML內容,創建go-demo.yaml文件。
Deployment中包含兩個實例的壓測程序,每個實例使用的資源為0.5個CPU。
apiVersion: apps/v1 kind: Deployment metadata: name: go-demo labels: app: go-demo spec: replicas: 2 selector: matchLabels: app: go-demo template: metadata: labels: app: go-demo spec: containers: - name: go-demo image: polinux/stress command: ["stress"] args: ["--vm", "1", "--vm-bytes", "556M", "-c", "1", "--vm-hang", "1"] imagePullPolicy: Always resources: requests: cpu: 0.5 limits: cpu: 0.5
執行以下命令,將go-demo部署到集群中。
kubectl apply -f go-demo.yaml
使用以下YAML內容,創建cgroups-cpuset-sample.yaml文件。
文件中指定了CPU的綁定信息。
apiVersion: resources.alibabacloud.com/v1alpha1 kind: Cgroups metadata: name: cgroups-cpuset-sample spec: deployment: name: go-demo namespace: default containers: - name: go-demo cpuset-cpus: 2,3 #綁定Pod到CPU2和CPU3上。
執行以下命令,將cgroups-cpuset-sample部署到集群中。
kubectl apply -f cgroups-cpuset-sample.yaml
執行以下命令,查看當前容器修改后的CPU核心綁定情況。
#具體路徑可根據Pod的UID以及Container的ID拼接得到。 cat /sys/fs/cgroup/cpuset/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod06de7408_346a_4d00_ba25_02833b6c****.slice/cri-containerd-733a0dc93480eb47ac6c5abfade5c22ed41639958e3d304ca1f85959edc3****.scope/cpuset.cpus
預期輸出:
2-3
由預期輸出得到,容器綁定在CPU2和CPU3上,與步驟3的
spec.deployment.containers.cpuset-cpus
描述一致。
修改磁盤IOPS參數
如果您需要控制磁盤IOPS,請使用操作系統為Alibaba Cloud Linux的Worker節點。修改磁盤IOPS參數的具體操作如下:
在Cgroup V1環境下使用blkio限制時,操作系統內核只會限制容器的Direct I/O,無法限制Buffered I/O。如需對Buffered I/O進行限制,請使用Cgroup V2,或在Alibaba Cloud Linux啟用Cgroup V1的控制群組回寫(cgroup writeback)功能,請參見開啟cgroup writeback功能。
使用以下YAML,創建一個IO密集型的測試應用。
將宿主機目錄/mnt掛載至Pod內部使用,對應磁盤設備名稱為/dev/vda1。
apiVersion: apps/v1 kind: Deployment metadata: name: fio-demo labels: app: fio-demo spec: selector: matchLabels: app: fio-demo template: metadata: labels: app: fio-demo spec: containers: - name: fio-demo image: registry.cn-zhangjiakou.aliyuncs.com/acs/fio-for-slo-test:v0.1 command: ["sh", "-c"] #使用Fio工具對磁盤IOPS進行寫測試。 args: ["fio -filename=/data/test -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=16k -size=2G -numjobs=10 -runtime=12000 -group_reporting -name=mytest"] volumeMounts: - name: pvc mountPath: /data #掛載在/data的路徑下。 volumes: - name: pvc hostPath: path: /mnt
執行以下命令,將fio-demo部署到集群中。
kubectl apply -f fio-demo.yaml
部署控制磁盤IOPS的Cgroups,對Pod的吞吐進行限制。
使用以下YAML,創建cgroups-sample-fio.yaml文件。
文件中指定了設備/dev/vda1的BPS(Bit Per Second)限制信息。
apiVersion: resources.alibabacloud.com/v1alpha1 kind: Cgroups metadata: name: cgroups-sample-fio spec: deployment: name: fio-demo namespace: default containers: - name: fio-demo blkio: #BPS限制,例如1048576、2097152、3145728。 device_write_bps: [{device: "/dev/vda1", value: "1048576"}]
執行以下命令,查看當前容器修改后的磁盤IO限制情況。
#實際路徑可根據Pod的UID以及Container的ID拼接得到。 cat /sys/fs/cgroup/blkio/kubepods.slice/kubepods-besteffort.slice/kubepods-besteffort-pod0840adda_bc26_4870_adba_f193cd00****.slice/cri-containerd-9ea6cc97a6de902d941199db2fcda872ddd543485f5f987498e40cd706dc****.scope/blkio.throttle.write_bps_device
預期輸出:
253:0 1048576
由預期輸出得到,當前磁盤的限速配置為
1048576
。
查看對應節點的磁盤監控。
如上圖所示,容器的吞吐BPS和步驟3的
device_write_bps
限制一致,且修改過程中Pod沒有被重啟。