kubelet 压力驱逐 - The node had condition:[DiskPressure]

本文详细介绍了Kubernetes中kubelet如何监控节点资源,包括磁盘压力驱逐、内存和磁盘使用率阈值、驱逐条件以及软硬驱逐策略。当节点资源达到预设阈值时,kubelet会执行驱逐操作,以确保集群稳定。此外,还讲解了如何调整kubelet配置文件来定制资源管理策略。

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

浅言碎语

在查看 pod 运行状态时,发现有的 pod 的状态是 Evicted,通过 describe 去查看发现了 The node had condition: [DiskPressure]. 的报错

原因是 kubelet 检测到本地磁盘使用率超过了 85% ,这是 kubelet 的默认配置

grep '85%' /var/log/messages

可以看到类似如下的内容

May 7 10:45:19 DC3-03-010 kubelet[637219]: I0507 10:45:19.660844 637219 image_gc_manager.go:300] [imageGCManager]: Disk usage on image filesystem is at 85% which is over the high threshold (85%). Trying to free 4934070272 bytes down to the low threshold (80%).

方法只有两种,要么清理磁盘或者磁盘扩容,要么就是修改 kubelet 的配置

清理 docker

  • docker system prune 命令可以用于清理磁盘,删除关闭的容器、无用的数据卷和网络,以及 dangling 的镜像(docker images 命令输出的 REPOSITORYTAG 显示为 <none> 的镜像)
  • docker system prune -a 命令清理得更加彻底,可以将没有容器使用Docker镜像都删掉
    • 这两个命令会将当前关闭的容器,以及当前没有用到的 Docker 镜像都删掉了
    • 所以使用之前一定要确认清楚了
docker system prune
docker system prune -a

kubelet 节点压力驱逐

  • kubelet 监控集群节点的 CPU、内存、磁盘空间和文件系统的 inode 等资源
    • 当这些资源中的一个或者多个达到特定的消耗水平, kubelet 可以主动地使节点上一个或者多个 Pod 失效,以回收资源防止饥饿
    • 在节点压力驱逐期间,kubelet 将所选 Pod 的 PodPhase 设置为 Failed。这将终止 Pod
  • kubelet 在终止最终用户 Pod 之前会尝试回收节点级资源
    • 例如,它会在磁盘资源不足时删除未使用的容器镜像

驱逐信号

  • memory.available
    • 当前节点可用内存
    • 计算方式为 cgroup memory 子系统中 memory.usage_in_bytes 中的值减去 memory.stattotal_inactive_file 的值
    • 默认值为 memory.available<100Mi
  • nodefs.available
    • nodefs 包含 kubelet 配置中 --root-dir 指定的文件分区和 /var/lib/kubelet/ 所在的分区磁盘使用率
    • 默认值为 nodefs.available<10%
  • nodefs.inodesFree
    • nodefs.available 分区的 inode 使用率
  • imagefs.available
    • 镜像所在分区磁盘使用率
    • 默认值为 imagefs.available<15%
  • imagefs.inodesFree
    • 镜像所在分区磁盘 inode 使用率
    • 默认值为 nodefs.inodesFree<5% (Linux 节点)
  • pid.available
    • /proc/sys/kernel/pid_max 中的值为系统最大可用 pid 数
  • kubelet 可以通过参数 --eviction-hard 来配置以上几个参数的阈值,当达到阈值时会驱逐节点上的容器

驱逐条件

  • 驱逐条件的形式为 [eviction-signal][operator][quantity]
    • eviction-signal 是要使用的驱逐信号
    • operator 是你想要的关系运算符, 比如 <(小于)
    • quantity 是驱逐条件数量,例如 1Gi
      • quantity 的值必须与 Kubernetes 使用的数量表示相匹配
      • 可以使用文字值或百分比(%
    • 例如,如果一个节点的总内存为 10Gi 并且你希望在可用内存低于 1Gi 时触发驱逐
      • 可以将驱逐条件定义为 memory.available<10%
      • 或者 memory.available<1G
      • 不能同时使用二者
软驱逐条件
  • 将驱逐条件与管理员所必须指定的宽限期配对
    • 在超过宽限期之前,kubelet 不会驱逐 Pod
    • 如果没有指定的宽限期,kubelet 会在启动时返回错误
  • 可以既指定软驱逐条件宽限期,又指定 Pod 终止宽限期的上限,给 kubelet 在驱逐期间使用
    • 如果指定了宽限期的上限并且 Pod 满足软驱逐阈条件,则 kubelet 将使用两个宽限期中的较小者
    • 如果没有指定宽限期上限,kubelet 会立即杀死被驱逐的 Pod,不允许其体面终止
  • 软驱逐条件标志
    • eviction-soft:一组驱逐条件,如 memory.available<1.5Gi, 如果驱逐条件持续时长超过指定的宽限期,可以触发 Pod 驱逐。
    • eviction-soft-grace-period:一组驱逐宽限期, 如 memory.available=1m30s,定义软驱逐条件在触发 Pod 驱逐之前必须保持多长时间。
    • eviction-max-pod-grace-period:在满足软驱逐条件而终止 Pod 时使用的最大允许宽限期(以秒为单位)
硬驱逐条件
  • 硬驱逐条件没有宽限期
    • 当达到硬驱逐条件时, kubelet 会立即杀死 pod,而不会正常终止以回收紧缺的资源
  • 硬驱逐条件标志
  • eviction-hard :一组硬驱逐条件, 如 memory.available<1Gi

驱逐监测间隔

  • kubelet 根据其配置的 housekeeping-interval 评估驱逐条件
    • 默认为 10s

节点条件

  • kubelet 报告节点状况以反映节点处于压力之下,因为满足硬或软驱逐条件,与配置的宽限期无关
  • MemoryPressure
    • 节点上的可用内存已满足驱逐条件
  • DiskPressure
    • 节点的根文件系统或映像文件系统上的可用磁盘空间和 inode 已满足驱逐条件
  • PIDPressure
    • 节点上的可用进程标识符已低于驱逐条件 (Linux)
  • 根据配置的 --node-status-update-frequency 更新节点条件
    • 默认为 10s

最小驱逐回收

  • 可以使用 --eviction-minimum-reclaim 标志为每个资源配置最小回收量
    • 当 kubelet 注意到某个资源耗尽时,它会继续回收该资源,直到回收到所指定的数量为止
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
evictionHard:
  memory.available: "500Mi"
  nodefs.available: "1Gi"
  imagefs.available: "100Gi"
evictionMinimumReclaim:
  memory.available: "0Mi"
  nodefs.available: "500Mi"
  imagefs.available: "2Gi"
  • memory.available 信号满足驱逐条件, kubelet 会回收资源
    • 直到信号达到 500Mi 的条件
  • nodefs.available 信号满足驱逐条件, kubelet 会回收资源
    • 直到信号达到 1Gi 的条件, 然后继续回收至少 500Mi 直到信号达到 1.5Gi
  • imagefs.available 信号满足驱逐条件, kubelet 会回收资源
    • 直到信号达到 100Gi 的条件, 然后继续回收至少 2Gi 直到信号达到 102Gi
  • 所有资源的默认 eviction-minimum-reclaim 都为 0

其他更多细节,可以查看官方文档:节点压力驱逐

修改 kubelet 配置文件

修改 kubelet 配置文件的方式

查看配置文件路径
systemctl cat kubelet

以自己的路径为准,找到相关的 yaml 配置文件,我的是 kubeadm 的方式部署的,看 KUBELET_CONFIG_ARGS=--config 指定的路径即可

备份配置文件
  • 备份做的好,跑路跑的少
cp /var/lib/kubelet/config.yaml{,.bak}
vim /var/lib/kubelet/config.yaml
# 软驱逐 evictionSoft
# 硬驱逐 evictionHard
evictionHard:
  nodefs.available: "5Gi"
  imagefs.available: "5Gi"
# 最小驱逐回收,可以不配置
evictionMinimumReclaim:
  nodefs.available: "500Mi"

修改 kubelet.service 的方式

查看配置文件路径
systemctl cat kubelet

找到 kubelet.service 文件的路径

备份配置文件
  • 备份做的好,跑路跑的少

以自己的路径为准,一般都会有 EnvironmentFile 参数,如果没有,可以加到 Environment 参数后面

cp /etc/sysconfig/kubelet{,.bak}
vim /etc/sysconfig/kubelet

软驱逐必须要设置驱逐宽限期,如果没有配置,kubelet 会启动失败,报错:grace period must be specified for the soft eviction threshold imagefs.available

--eviction-soft=nodefs.available<5%,imagefs.available<5% \
--eviction-soft-grace-period=nodefs.available=2m,imagefs.available=2m \
--eviction-max-pod-grace-period=30

重启 kubelet

systemctl restart kubelet
--- # Source: calico/templates/calico-kube-controllers.yaml # This manifest creates a Pod Disruption Budget for Controller to allow K8s Cluster Autoscaler to evict apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: calico-kube-controllers namespace: kube-system labels: k8s-app: calico-kube-controllers spec: maxUnavailable: 1 selector: matchLabels: k8s-app: calico-kube-controllers --- # Source: calico/templates/calico-kube-controllers.yaml apiVersion: v1 kind: ServiceAccount metadata: name: calico-kube-controllers namespace: kube-system --- # Source: calico/templates/calico-node.yaml apiVersion: v1 kind: ServiceAccount metadata: name: calico-node namespace: kube-system --- # Source: calico/templates/calico-config.yaml # This ConfigMap is used to configure a self-hosted Calico installation. kind: ConfigMap apiVersion: v1 metadata: name: calico-config namespace: kube-system data: # Typha is disabled. typha_service_name: "none" # Configure the backend to use. calico_backend: "bird" # Configure the MTU to use for workload interfaces and tunnels. # By default, MTU is auto-detected, and explicitly setting this field should not be required. # You can override auto-detection by providing a non-zero value. veth_mtu: "0" # The CNI network configuration to install on each node. The special # values in this config will be automatically populated. cni_network_config: |- { "name": "k8s-pod-network", "cniVersion": "0.3.1", "plugins": [ { "type": "calico", "log_level": "info", "log_file_path": "/var/log/calico/cni/cni.log", "datastore_type": "kubernetes", "nodename": "__KUBERNETES_NODE_NAME__", "mtu": __CNI_MTU__, "ipam": { "type": "calico-ipam" }, "policy": { "type": "k8s" }, "kubernetes": { "kubeconfig": "__KUBECONFIG_FILEPATH__"
最新发布
03-20
### Calico 在 Kubernetes 中的配置详解 #### 1. **Calico 的基本功能** Calico 是一种流行的开源网络解决方案,用于实现 Kubernetes 集群中的网络策略 (NetworkPolicy)[^1]。它通过提供细粒度的安全性和隔离能力来增强集群安全性。 --- #### 2. **Calico 组件及其作用** 以下是 Calico 在 Kubernetes 中的主要组件及其功能: - **calico/node 容器**: 这是一个 DaemonSet,在每个节点上运行 calico/node 容器,负责管理路由表、IP 地址分配以及与其他节点之间的通信[^2]。 - **CNI 插件**: 使用另一个 DaemonSet 将 Calico CNI 二进制文件和网络配置部署到每个节点上,从而支持 Kubernetes 网络接口标准(CNI)。 - **calico/kube-controller Deployment**: 此控制器处理与 Kubernetes API Server 的集成工作,例如同步数据和服务代理等功能。 - **Secret/calico-etcd-secrets**: 提供 TLS 密钥信息以便安全地连接 etcd 数据库(如果启用了加密传输的话)。这是可选项。 - **ConfigMap/calico-config**: 存储安装过程中所需的全局参数设置,比如 IP 池范围等。 --- #### 3. **PodDisruptionBudget 字段含义及用途** `PodDisruptionBudget` (PDB) 是用来控制应用中断容忍度的一种机制。其主要字段如下: - `minAvailable`: 表示最小可用副本数或者百分比形式表示的比例。 - `maxUnavailable`: 可以被驱逐的最大不可用实例数量或比例。 - 当两者同时存在时,取更严格的约束条件作为实际生效规则[^3]. 此对象帮助管理员确保即使在维护期间也能维持服务级别协议(SLA),防止因计划外的操作而导致整个应用程序完全下线的情况发生. --- #### 4. **ServiceAccount 字段解释** Kubernetes 中的服务账户(Service Account)允许 Pods 访问特定权限下的 API 请求或其他外部资源。常见的几个属性有: - `metadata.name`: 唯一标识符. - `secrets[]`: 关联 Secret 对象列表,通常包含访问令牌(token). - `imagePullSecrets[]`: 如果镜像存储于私仓,则需指定拉取凭证名. 这些信息共同构成了 Pod 执行操作所需的身份认证基础结构. --- #### 5. **ConfigMap 各字段意义** ConfigMaps 主要用于保存非敏感性的配置项,可以映射成环境变量或是挂载为卷内的文件内容给容器使用。具体来说: - `data`: 键值对集合,其中键代表变量名称而对应的值则是具体的设定字符串。 - 若要将其加载至 Volume 下面则还需要定义相应的路径位置(`claimName`) 和读写模式 (`readOnly`) [^3]: ```yaml apiVersion: v1 kind: PersistentVolumeClaim spec: volumes: - name: config-volume persistentVolumeClaim: claimName: my-pvc-name readOnly: false ``` 上述 YAML 片段展示了如何利用 PVC 来持久化存储 ConfigMap 文件的方式之一。 --- ### 总结 以上是对 Calico 在 Kubernetes 上配置的一些核心概念解析,涵盖了从底层架构设计思路直至高级运维技巧等多个层面的知识要点。希望对你有所帮助! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值