Kubernetes为系统守护进程预留计算资源

   

参考文档:http://arthurchiao.art/blog/k8s-cgroup-zh/

   

   

   

--cgroups-per-qos

默认开启。开启这个参数后,kubelet 会将所有的 pod 创建在 kubelet 管理的 cgroup 层次结构下(这样才有了限制所有 Pod 使用资源总量的基础)。要想启用 Node Allocatable 特性,这个参数必须开启

Kubernetes 会将所有 pod 分成三种 QoS,优先级从高到低:Guaranteed > Burstable > BestEffort。 三种 QoS 是根据 requests/limits 的大小关系来定义的:

  • Guaranteed: requests == limits, requests != 0, 即 正常需求 == 最大需求,换言之 spec 要求的资源量必须得到保证,少一点都不行;
  • Burstable: requests < limits, requests != 0, 即 正常需求 < 最大需求,资源使用量可以有一定弹性空间;
  • BestEffort: request == limits == 0, 创建 pod 时不指定 requests/limits 就等同于设置为 0,kubelet 对这种 pod 将尽力而为;有好处也有坏处:
    • 好处:node 的资源充足时,这种 pod 能使用的资源量没有限制;
    • 坏处:这种 pod 的 QoS 优先级最低,当 node 资源不足时,最先被驱逐

--cgroup-driver

指定 kubelet 使用的 cgroup driver。默认为 cgroupfs,还可以是 systemd,但是这个值需要和 docker runtime 所使用的 cgroup driver 保持一致

--cgroup-root

可选。指定给 pod 使用的根 cgroup,容器运行时会尽量将 pod 的资源限制在这个根 cgroup 下面。默认为空,即使用容器运行时作为根 cgroup

--enforce-node-allocatable

指定 kubelet 为哪些进程做硬限制,可选的值有:pods, kube-reserved, system-reserve

这个参数开启并指定 pods 后 kubelet 会为所有 pod 的总 cgroup 做资源限制(通过 cgroup 中的 kubepods.limit_in_bytes)

调度器可以限制节点上所有创建的 pod 的 request 量不会超过 allocatable,已可以保证不会有超过 allocatable 的 pod 跑在该节点上,这里还要用 cgroup 再做硬限制的意义是:pod 使用的资源是可以大于 request 的,所以,虽然在调度阶段限制了所有 request 的总量不会超过 allocatable 的值,但不能保证真正运行起来后所有 pod 的资源使用量不会超过 allocatable;而用 cgroup 做了硬限制后,当所有 pod 使用量达到 allocatable 后,会有 pod 被 OOM killer 机制杀掉,以保证实际使用量不会超过allocatable

--eviction-hard

设置进行 pod 驱逐的阈值,这个参数只支持内存和磁盘。通过 --eviction-hard 标志预留一些内存后,当节点上的可用内存降至保留值以下时,kubelet 将会对 pod 进行驱逐

   

Kube 预留值:

--kube-reserved-cgroup=

这个参数用来指定 k8s 系统组件所使用的 cgroup。注意,这里指定的 cgroup 及其子系统需要预先创建好,kubelet 并不会为你自动创建好

--kube-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]

kube-reserved 用来给诸如 kubelet、容器运行时、节点问题监测器等 Kubernetes 系统守护进程记述其资源预留值。 该配置并非用来给以 Pod 形式运行的系统守护进程预留资源

除了 cpu、内存 和 ephemeral-storage 之外,pid 可用来指定为 Kubernetes 系统守护进程预留指定数量的进程 ID

   

系统预留值:

--system-reserved-cgroup=

这个参数用来指定系统守护进程所使用的cgroup。注意,这里指定的cgroup及其子系统需要预先创建好,kubelet并不会为你自动创建好

--system-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]

system-reserved 用于为诸如 sshd、udev 等系统守护进程记述其资源预留值。 system-reserved 也应该为 kernel 预留 内存,因为目前 kernel 使用的内存并不记在 Kubernetes 的 Pod 上。 同时还推荐为用户登录会话预留资源(systemd 体系中的 user.slice)

   

例子一:只限制 pod 资源总量

将以下内容添加到 kubelet 的启动参数中:

--enforce-node-allocatable=pods \

--cgroup-driver=cgroupfs \

--kube-reserved=cpu=1,memory=1Gi,ephemeral-storage=10Gi \

--system-reserved=cpu=1,memory=2Gi,ephemeral-storage=10Gi \

--eviction-hard=memory.available<500Mi,nodefs.available<10%

按以上设置:

    • 节点上可供 Pod 所 request 的资源总和 allocatable 计算如下:

      allocatable = capacity - kube-reserved - system-reserved - eviction-hard

    • 节点上所有 Pod 实际使用的资源总和不会超过:capacity - kube-reserved - system-reserved

   

例子二:同时限制pod、k8s系统组件

   

修改 kubelet 配置:

方式一:将以下内容添加到 kubelet 的启动参数中:

--enforce-node-allocatable=pods,kube-reserved \

--cgroup-driver=cgroupfs \

--kube-reserved=cpu=500,memory=512Mi,ephemeral-storage=10Gi \

--kube-reserved-cgroup=/kubelet.slice

方式二:修改 kubelet 配置文件(默认配置文件 /var/lib/kubelet/config.yaml)

cgroupDriver: systemd

cgroupsPerQOS: true

enforceNodeAllocatable:

- pods

- kube-reserved

kubeReserved:

cpu: 500m

memory: 512Mi

ephemeral-storage: 10Gi

kubeReservedCgroup: /kubelet.slice

   

重启 kubelet 服务:

systemctl restart kubelet

需要注意,如果 --kube-reserved-cgroup 对应的路径不存在,Kubelet 不会创建它,启动 Kubelet 将会失败

报错内容:缺少对应的 cgroup 路径

Dec 15 14:41:14 instance-lx0qsle2 kubelet[75445]: E1215 14:41:14.299424 75445 kubelet.go:1511] "Failed to start ContainerManager" err="Failed to enforce Kube Reserved Cgroup Limits on \"/kubelet.slice\": cgroup [\"kubelet\"] has some missing paths: /sys/fs/cgroup/hugetlb/kubelet.slice, /sys/fs/cgroup/cpuset/kubelet.slice, /sys/fs/cgroup/cpu,cpuacct/kubelet.slice, /sys/fs/cgroup/cpu,cpuacct/kubelet.slice, /sys/fs/cgroup/systemd/kubelet.slice, /sys/fs/cgroup/pids/kubelet.slice, /sys/fs/cgroup/memory/kubelet.slice"

根据提示创建对应的 cgroup 路径:

mkdir /sys/fs/cgroup/hugetlb/kubelet.slice

mkdir /sys/fs/cgroup/cpuset/kubelet.slice

mkdir /sys/fs/cgroup/cpu,cpuacct/kubelet.slice

mkdir /sys/fs/cgroup/systemd/kubelet.slice

mkdir /sys/fs/cgroup/pids/kubelet.slice

mkdir /sys/fs/cgroup/memory/kubelet.slice

注意:systemd 的 cgroup 驱动对应的 cgroup 名称是以 .slice 结尾的,比如如果你把 cgroup 名称配置成 kubelet.service,那么对应的创建的 cgroup 名称应该为 kubelet.service.slice。如果你配置的是 cgroupfs 的驱动,则用配置的值即可。无论哪种方式,通过查看错误日志都是排查问题最好的方式

   

再次重启 kubelet 依然报错:

Dec 15 14:44:01 instance-lx0qsle2 kubelet[76089]: I1215 14:44:01.285110 76089 node_container_manager_linux.go:125] "Enforcing kube reserved on cgroup" cgroupName="/kubelet.slice" limits={"cpu":"500m","ephemeral-storage":"10Gi","memory":"512Mi"}

Dec 15 14:44:01 instance-lx0qsle2 kubelet[76089]: E1215 14:44:01.285971 76089 kubelet.go:1511] "Failed to start ContainerManager" err="Failed to enforce Kube Reserved Cgroup Limits on \"/kubelet.slice\": Unit kubelet.slice is not loaded."

   

启动 kubelet.slice

systemctl start kubelet.slice

   

再次重启 kubelet 成功

   

查看限制:

cat /sys/fs/cgroup/memory/kubelet.slice/memory.limit_in_bytes

536870912 # 内存限制 512Mi

   

查看节点详细描述:

kubectl describe node 10.100.0.98

   

Node Allocatable Resource = Node Capacity - Kube-reserved

   

例子三:同时限制pod、k8s系统组件、linux系统守护进程资源

   

修改 kubelet 配置:

方式一:将以下内容添加到 kubelet 的启动参数中:

--enforce-node-allocatable=pods,kube-reserved,system-reserved \

--cgroup-driver=cgroupfs \

--kube-reserved=cpu=500m,memory=512Mi,ephemeral-storage=10Gi \

--kube-reserved-cgroup=/kubelet.slice \

--system-reserved cpu=500m,memory=512Mi,ephemeral-storage=10Gi \

--system-reserved-cgroup=/system.slice \

--eviction-hard=memory.available<500Mi,nodefs.available<10%

   

方式二:修改 kubelet 配置文件(默认配置文件 /var/lib/kubelet/config.yaml)

cgroupDriver: systemd

cgroupsPerQOS: true

enforceNodeAllocatable:

- pods

- kube-reserved

- system-reserved

kubeReserved:

cpu: 500m

memory: 512Mi

ephemeral-storage: 10Gi

kubeReservedCgroup: /kubelet.slice

systemReserved:

cpu: 500m

memory: 512Mi

ephemeral-storage: 10Gi

systemReservedCgroup: /system.slice

evictionHard:

memory.available: 500Mi

nodefs.available: 10%

   

重启 kubelet 服务:

systemctl restart kubelet

   

报错信息:缺少对应的 cgroup 路径

Dec 15 15:45:23 instance-lx0qsle2 kubelet[22282]: I1215 15:45:23.212655 22282 node_container_manager_linux.go:116] "Enforcing system reserved on cgroup" cgroupName="/system.slice" limits={"cpu":"500m","ephemeral-storage":"10Gi","memory":"512Mi"}

Dec 15 15:45:23 instance-lx0qsle2 kubelet[22282]: E1215 15:45:23.212740 22282 kubelet.go:1511] "Failed to start ContainerManager" err="Failed to enforce System Reserved Cgroup Limits on \"/system.slice\": cgroup [\"system\"] has some missing paths: /sys/fs/cgroup/hugetlb/system.slice"

   

创建缺少的 cgroup 路径:

mkdir /sys/fs/cgroup/hugetlb/system.slice

   

再次重启 kubelet 服务成功:

systemct restart kubelet

   

查看 system.slice 状态:正常运行

systemctl status system.slice

   

查看限制:

cat /sys/fs/cgroup/memory/system.slice/memory.limit_in_bytes

536870912 # 内存限制 512Mi

   

查看节点详细描述:

kubectl describe node 10.100.0.98

   

  • 节点上可供 Pod 所 request 的资源总和 allocatable 计算如下:

    allocatable = capacity - kube-reserved - system-reserved - eviction-hard

  • 节点上所有 Pod 实际使用的资源总和不会超过:capacity - kube-reserved - system-reserved

       

   

   

   

posted @ 2024-02-01 16:38  小song博客  阅读(49)  评论(0编辑  收藏  举报