下面內容還處於測試階段,生產上是否能保證集群穩定暫時還不清楚。😁😁
事故
今天我們的開發環境由於java應用內存搶占原因導致k8s集群worker節點全部宕機,主要原因是程序和資源沒進行限制規划,且kubelet也沒配置資源預留,那host上所有資源都是可以給pod調配使用的,這樣就引起集群雪崩效應,比如集群內有一台上跑的pod沒做resource limt導致占用資源過大導致將宿主機壓死了,此時這個節點在kubernetes內就是一個no ready的狀態了,kubernetes會將這台host上所有的pod在其他節點上重建,也就意味着那個有問題的pod重新跑在其他正常的節點上,將另外正常的節點壓跨。循懷下去直到集群內所有主機都掛了,這就是集群雪崩效應。
解決辦法
在kubernetes中可以通過給kubelet配置參數預留資源給系統進程和kubernetes進程保證它們穩定運行。目前能實現到cpu、memory、ephemeral-storage層面的資源預留。
重點提兩點
cpu:cpu是配置cpu shares實際上對應的是cpu的優先級,簡單來說,這個在cpu繁忙時,它能有更高優先級獲取更多cpu資源。
ephemeral-storage是kubernetes1.8開始引入的一個資源限制的對象,kubernetes 1.10版本中kubelet默認已經打開的了,主要是用於對本地臨時存儲使用空間大小的限制,如對pod的empty dir、/var/lib/kubelet、日志、容器可讀寫層的使用大小的限制。
配置
基本概念
在講配置之前我們先了解幾個概念:
Node capacity:節點總共的資源
kube-reserved:給kubernetes進程預留的資源
system-reserved:給操作系統預留的資源
eviction-threshold:kubelet eviction的閥值
allocatable:留給pod使用的資源
node_allocatable=Node_capacity-(kube-reserved+system-reserved+hard-eviction)
Node Capacity
---------------------------
| kube-reserved |
|-------------------------|
| system-reserved |
|-------------------------|
| eviction-threshold |
|-------------------------|
| |
| allocatable |
| (available for pods) |
| |
| |
---------------------------
Kubernetes 節點上的 Allocatable
被定義為 pod 可用計算資源量。調度器不會超額申請 Allocatable
。目前支持 CPU
, memory
和 storage
這幾個參數。
Node Allocatable 暴露為 API 中 v1.Node
對象的一部分,也是 CLI 中 kubectl describe node
的一部分。
在 kubelet
中,可以為兩類系統守護進程預留資源。
使用kubelet參數進行限制
此方法適用於老版本的kubernetes集群,在新版本(1.11之前)中已經不適用了。
https://k8smeetup.github.io/docs/tasks/administer-cluster/reserve-compute-resources/
https://www.bladewan.com/2018/01/26/k8s_resource_resver/
使用kubelet config進行限制
kubelet 較新的版本都采用kubelet config對集群的kubelet進行配置,此處采用靜態配置方式,當然也可以使用動態配置方式。
# 編輯文檔kubelet config 文件
vim /var/lib/kubelet/config
配置資源預留
# 找到enforceNodeAllocatable 注釋掉
#enforceNodeAllocatable:
#- pods
# 添加以下內容,系統和kubelet均預留CPU500m內存500Mi磁盤5G
systemReserved:
cpu: "500m"
memory: "500Mi"
ephemeral-storage: "5Gi"
kubeReserved:
cpu: "500m"
memory: "500Mi"
ephemeral-storage: "5Gi"
systemReservedCgroup: /system.slice
kubeReservedCgroup: /kubelet.service
EnforceNodeAllocatable:
- pods
- kube-reserved
- system-reserved
配置軟驅逐(默認為硬驅逐)
軟驅逐有資源驅逐等待時間,硬驅逐為立刻驅逐。
# evictionHard 注釋掉,並在后面新增以下內容
#evictionHard:
EvictionSoft:
imagefs.available: 15%
memory.available: 10%
nodefs.available: 10%
nodefs.inodesFree: 5%
EvictionSoftGracePeriod:
memory.available: "5m"
nodefs.available: "2m"
nodefs.inodesFree: "2m"
imagefs.available: "2m"
# 如果你使用的cgroup driver是croup還需要進行以下操作
# cpuset和hugetlb subsystem是默認沒有初始化system.slice手動創建,
mkdir -p /sys/fs/cgroup/hugetlb/system.slice/kubelet.service/
mkdir -p /sys/fs/cgroup/cpuset/system.slice/kubelet.service/
# 配置在kubelet中避免重啟失效
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/cpuset/system.slice/kubelet.service
ExecStartPre=/usr/bin/mkdir -p /sys/fs/cgroup/hugetlb/system.slice/kubelet.service
重啟kubelet
service kubelet restart
驗證
[root@m3 pki]# kubectl describe node m1
Name: m1
Roles: master
Labels: beta.kubernetes.io/arch=amd64
....
CreationTimestamp: Mon, 26 Aug 2019 20:35:35 -0400
...
Addresses:
InternalIP: 172.27.100.13
Hostname: m1
Capacity:
cpu: 4
ephemeral-storage: 36678148Ki
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 8010576Ki
pods: 110
Allocatable:
cpu: 3
ephemeral-storage: 23065162901
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 6884176Ki
pods: 110
- 可以看到預留后,可用CPU為3,不預留為4,內存是一樣的計算方式,此處預留了1G(500Mi+500Mi)
參考文檔
https://github.com/rootsongjc/qa/issues/3
https://cloud.tencent.com/developer/article/1097002
https://blog.csdn.net/ahilll/article/details/82109008
http://dockone.io/article/4797
https://kubernetes.io/docs/tasks/administer-cluster/reconfigure-kubelet/
https://kubernetes.io/zh/docs/tasks/administer-cluster/kubelet-config-file/
https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/kubelet/config/v1beta1/types.go
https://www.bladewan.com/2018/01/26/k8s_resource_resver/