搭建k8s集群实战(四)k8s node 资源管理、避免系统无响应

本文详细介绍了如何在 Kubernetes 集群中管理节点资源,确保系统守护进程的稳定运行。通过启用 Node Allocatable 特性,设置 cgroup 驱动,预留 kube 和系统资源,以及配置驱逐阈值,可以有效避免因资源竞争导致的节点无响应。此外,文章还提供了实际操作步骤,帮助管理员实施节点资源约束。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kubernetes 的节点可以按照 Capacity 调度。默认情况下 pod 能够使用节点全部可用容量。 这是个问题,因为节点自己通常运行了不少驱动 OS 和 Kubernetes 的系统守护进程。 除非为这些系统守护进程留出资源,否则它们将与 pod 争夺资源并导致节点资源短缺问题,从而导致系统无响应

kubelet 公开了一个名为 ‘Node Allocatable’ 的特性,有助于为系统守护进程预留计算资源。 Kubernetes 推荐集群管理员按照每个节点上的工作负载密度配置 “Node Allocatable”。

节点可分配

在这里插入图片描述

Kubernetes 节点上的 ‘Allocatable’ 被定义为 pod 可用计算资源量。 调度器不会超额申请 ‘Allocatable’。 目前支持 ‘CPU’、‘memory’ 和 ‘ephemeral-storage’ 这几个参数。

可分配的节点暴露为 API 中 v1.Node 对象的一部分,也是 CLI 中 kubectl describe node 的一部分。

在 kubelet 中,可以为两类系统守护进程预留资源。

什么是cgroup

cgroup(control group)是一个内核特性,用于限制、统计、隔离一组进程的资源(CPU、内存、磁盘、网络等),首字母不要大写。

““cgroup” stands for “control group” and is never capitalized.

  • 单数形式(cgroup)指所有特性,也可以作为“cgroup controllers”的修饰。
  • 复数形式(cgroups)指多个 cgroup。

Google 工程师在 2006 年开始提出这个特性,最早叫“process containers”,为了避免造成歧义,在 2007 年改名为“control group”,在 2008 年 1 月发布的 Linux Kernel 2.6.24 合入主线分支。此后,在此基础上又增加了一系列特性,包括 kernfs(伪文件系统,用于向用户导出内核的设备模型),firewalling(基于预定义的安全规则管理网络流量)和 unified hierarchy。在 Linux Kernel 4.5 版本合入了 cgroup v2 的实现代码。

启用 QoS 和 Pod 级别的 cgroups

为了恰当的在节点范围实施节点可分配约束,你必须通过 --cgroups-per-qos 标志启用新的 cgroup 层次结构。这个标志是默认启用的。 启用后,kubelet 将在其管理的 cgroup 层次结构中创建所有终端用户的 Pod。

配置 cgroup 驱动

kubelet 支持在主机上使用 cgroup 驱动操作 cgroup 层次结构。 驱动通过 --cgroup-driver 标志配置。

支持的参数值如下:

  • cgroupfs 是默认的驱动,在主机上直接操作 cgroup 文件系统以对 cgroup 沙箱进行管理。
  • systemd 是可选的驱动,使用 init 系统支持的资源的瞬时切片管理 cgroup 沙箱。

取决于相关容器运行时的配置,操作员可能需要选择一个特定的 cgroup 驱动 来保证系统正常运行。 例如,如果操作员使用 containerd 运行时提供的 systemd cgroup 驱动时, 必须配置 kubelet 使用 systemd cgroup 驱动。

Kube 预留值

  • Kubelet 标志: --kube-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]
  • Kubelet 标志: --kube-reserved-cgroup=

kube-reserved 用来给诸如 kubelet、容器运行时、节点问题监测器等 kubernetes 系统守护进程记述其资源预留值。 该配置并非用来给以 Pod 形式运行的系统守护进程保留资源。kube-reserved 通常是节点上 pod 密度 的函数。

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

要选择性地对 kubernetes 系统守护进程上执行 kube-reserved 保护,需要把 kubelet 的 --kube-reserved-cgroup 标志的值设置为 kube 守护进程的父控制组。

推荐将 kubernetes 系统守护进程放置于顶级控制组之下(例如 systemd 机器上的 runtime.slice)。 理想情况下每个系统守护进程都应该在其自己的子控制组中运行。

请注意,如果 --kube-reserved-cgroup 不存在,Kubelet 将 不会 创建它。 如果指定了一个无效的 cgroup,Kubelet 将会失败。

系统预留值

  • Kubelet 标志: --system-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]
  • Kubelet 标志: --system-reserved-cgroup=

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

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

要想为系统守护进程上可选地实施 system-reserved 约束,请指定 kubelet 的 --system-reserved-cgroup 标志值为 OS 系统守护进程的父级控制组。

推荐将 OS 系统守护进程放在一个顶级控制组之下(例如 systemd 机器上的 system.slice)。

请注意,如果 --system-reserved-cgroup 不存在,kubelet 不会 创建它。 如果指定了无效的 cgroup,kubelet 将会失败。

显式保留的 CPU 列表

FEATURE STATE: Kubernetes v1.17 [stable]
Kubelet 标志:–reserved-cpus=0-3

reserved-cpus 旨在为操作系统守护程序和 kubernetes 系统守护程序保留一组明确指定编号的 CPU。reserved-cpus 适用于不打算针对 cpuset 资源为操作系统守护程序和 kubernetes 系统守护程序定义独立的顶级 cgroups 的系统。 如果 Kubelet 没有 指定参数 --system-reserved-cgroup 和 --kube-reserved-cgroup, 则 reserved-cpus 的设置将优先于 --kube-reserved 和 --system-reserved 选项。

驱逐阈值

Kubelet 标志:–eviction-hard=[memory.available<500Mi]

节点级别的内存压力将导致系统内存不足,这将影响到整个节点及其上运行的所有 Pod。 节点可以暂时离线直到内存已经回收为止。 为了防止(或减少可能性)系统内存不足,kubelet 提供了 资源不足管理。 驱逐操作只支持 memory 和 ephemeral-storage。 通过 --eviction-hard 标志预留一些内存后,当节点上的可用内存降至保留值以下时, kubelet 将尝试驱逐 Pod。 如果节点上不存在系统守护进程,Pod 将不能使用超过 capacity-eviction-hard 所 指定的资源量。因此,为驱逐而预留的资源对 Pod 是不可用的。

实施节点可分配约束

Kubelet 标志:–enforce-node-allocatable=pods[,][system-reserved][,][kube-reserved]

调度器将 ‘Allocatable’ 视为 Pod 可用的 capacity(资源容量)。

kubelet 默认对 Pod 执行 ‘Allocatable’ 约束。 无论何时,如果所有 Pod 的总用量超过了 ‘Allocatable’,驱逐 Pod 的措施将被执行。
可选地,通过在同一标志中同时指定 kube-reserved 和 system-reserved 值, 可以使 kubelet 强制实施 kube-reserved 和 system-reserved 约束。 请注意,要想执行 kube-reserved 或者 system-reserved 约束, 需要对应设置 --kube-reserved-cgroup 或者 --system-reserved-cgroup。

一般原则

系统守护进程一般会被按照类似 Guaranteed pods 一样对待。 系统守护进程可以在与其对应的控制组中出现突发资源用量,这一行为要作为 kubernetes 部署的一部分进行管理。 例如,kubelet 应该有它自己的控制组并和容器运行时共享 kube-reserved 资源。 不过,如果执行了 kube-reserved 约束,则 kubelet 不可出现突发负载并用光 节点的所有可用资源。

在执行 system-reserved 预留策略时请加倍小心,因为它可能导致节点上的 关键系统服务出现 CPU 资源短缺、因为内存不足而被终止或者无法在节点上创建进程。 建议只有当用户详尽地描述了他们的节点以得出精确的估计值, 并且对该组中进程因内存不足而被杀死时,有足够的信心将其恢复时, 才可以强制执行 system-reserved 策略。

  • 作为起步,可以先针对 pods 上执行 ‘Allocatable’ 约束。
  • 一旦用于追踪系统守护进程的监控和告警的机制到位,可尝试基于用量估计的 方式执行 kube-reserved 策略。
  • 随着时间推进,在绝对必要的时候可以执行 system-reserved 策略。

随着时间推进和越来越多特性被加入,kube 系统守护进程对资源的需求可能也会增加。 以后 kubernetes 项目将尝试减少对节点系统守护进程的利用,但目前这件事的优先级 并不是最高。 所以,将来的发布版本中 Allocatable 容量是有可能降低的。

实操

通过 ‘kubectl describe node k8s-node1’ 查看节点 k8s-node1配置前的数据:

Capacity:
  cpu: 14
  ephemeral-storage: 153571Mi
  hugepages-2Mi: 0
  memory: 18319536Ki
  pods: 110
Allocatable:
  cpu: 14
  ephemeral-storage: 144927778167
  hugepages-2Mi: 0
  memory: 18217136Ki
  pods: 110

在节点 k8s-node1 的 /var/lib/kubelet/config.yaml 加入下列內容:

systemReserved:
  memory: 300Mi
  cpu: 250m
kubeReserved:
  memory: 200Mi
  cpu: 500m
evictionHard:
  memory.available: 200Mi
  nodefs.available: 2Gi

重启kubelet载入新设定

sudo systemctl restart kubelet

通过 ‘kubectl describe node k8s-node1’ 查看节点 k8s-node1配置后的数据:

Capacity:
  cpu: 14
  ephemeral-storage: 153571Mi
  hugepages-2Mi: 0
  memory: 18319536Ki
  pods: 110
Allocatable:
  cpu: 13250m
  ephemeral-storage: 133091Mi
  hugepages-2Mi: 0
  memory: 16554160Ki
  pods: 110

可以看到可以分配的cpu和内存都变小了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiegwei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值