5 minutes reading time
Kubernetes 的 pod 可以按照节点的资源进行调度,默认情况下 pod 能够使用节点的全部资源,这样往往会出现因为节点自身运行的一些驱动及 Kubernetes 系统守护进程,导致资源不足的问题。 例如有一个应用在运行中使用了大量的系统资源,导致 kubelet 和 apiserver 的心跳出现故障,导致节点处于 Not Ready 的状态,节点出现 Not Ready 的状况后,过一会儿会将 pod 调度到其它 node 节点上运行,往往会导致节点雪崩,一个接一个的出现 Not Ready 状况.
那么如何解决这个问题呢? 这时可以通过 为 Kubernetes 集群配置资源预留,kubelet 暴露了一个名为 Node Allocatable 的特性,有助于为系统守护进程预留计算资源,Kubernetes 也是推荐集群管理员按照每个节点上的工作负载来配置 Node Allocatable。
Kubernetes 节点上的 Allocatable 被定义为 Pod 可用计算资源量。 调度器不会超额申请 Allocatable。 目前支持 CPU、内存 和 存储 这几个参数。可以通过 kubectl describe node
命令查看节点可分配资源的数据:
可以看到有 Capacity 和 Allocatable 两个内容,Allocatable 这个就是节点可分配资源,由于没有设置,所以默认 Capacity 和 Allocatable 是一致的。
Capacity 是节点所有的系统资源,kube-reserved 是给 kube 组件预留的资源,system-reserved 是给系统进程预留的资源,eviction-hard 是Kubelet 的驱逐阈值。
因此节点的可用资源大概为 Node Capacity - Kube-reserved - system-reserved - eviction-hard
,当节点的使用资源超过可用大小时,会将 pod 驱逐到其它节点。
先来设置 Kube-reserved ,要配置 Kube-reserved,需要把 kubelet 的 --kube-reserved-cgroup 标志的值设置为 kube 守护进程的父控制组。 不过需要注意,如果 --kube-reserved-cgroup 不存在,Kubelet 不会创建它,启动 Kubelet 将会失败。,修改node节点的 kubelet 配置文件,添加以下配置:
enforceNodeAllocatable:
- pods
- kube-reserved
kubeReserved:
cpu: 500m
memory: 1Gi
ephemeral-storage: 1Gi
kubeReservedCgroup: /kubelet.slice
修改完重启服务,发现服务启动失败,查看日志,发现cgroup没创建,创建相应的路径即可:
Mar 09 14:22:47 node01 kubelet[4800]: E0309 14:22:47.058618 4800 kubelet.go:1542] "Failed to start ContainerManager" err="Failed to enforce Kube Reserved Cgroup Limits on \"/kubelet.slice\": cgroup [\"kubelet\"] has some missing paths: /sys/fs/cgroup/memory/kubelet.slice, /sys/fs/cgroup/pids/kubelet.slice, /sys/fs/cgroup/hugetlb/kubelet.slice, /sys/fs/cgroup/cpuset/kubelet.slice, /sys/fs/cgroup/cpu,cpuacct/kubelet.slice, /sys/fs/cgroup/systemd/kubelet.slice, /sys/fs/cgroup/cpu,cpuacct/kubelet.slice"
mkdir -p /sys/fs/cgroup/cpu,cpuacct/kubelet.slice
mkdir -p /sys/fs/cgroup/memory/kubelet.slice
mkdir -p /sys/fs/cgroup/systemd/kubelet.slice
mkdir -p /sys/fs/cgroup/pids/kubelet.slice
mkdir -p /sys/fs/cgroup/cpu,cpuacct/kubelet.slice
mkdir -p /sys/fs/cgroup/cpuset/kubelet.slice
mkdir -p /sys/fs/cgroup/hugetlb/kubelet.slice
创建完重启 kubelet 服务,发现服务恢复正常了,再次查看节点信息,发现 Allocatable 值已经修改成功。
system-reserved 也可以使用同样的方式进行设置,同样需要注意的是同样需要配置 system-reserved-cgroup 参数,这里就不过多赘述了。
如何修改驱逐阈值了,同样修改 kubelet 的配置文件,添加以下配置:
evictionHard:
memory.available: "100Mi"
nodefs.available: "10%"
nodefs.inodesFree: "5%"
imagefs.available: "15%"
当节点的内存达到保留值以下时,会进行 pod的驱逐。配置完,再次查看节点的可使用资源,可以看到可分配资源再次减少。
本文讲解了如何为 Kubernetes 节点设置可分配的资源限制,通过设置节点可分配资源大小,可以提高 Kubernetes 系统的稳定性,但需要注意的是配置参数时,需要注意参数的大小,不当的参数可能会导致系统出现异常。