• 热门
  • 基础
  • 数据库
  • 安全
  • 大数据
  • 人工智能
  • 混合云
  • 开发与运维
  • 企业应用

应用服务

行业引擎

全部文档
当前文档

暂无内容

如果没有找到您期望的内容,请尝试其他搜索词

文档中心

设置nodeName风险

最近更新时间:2024-12-03 20:50:59

概述

在 Kubernetes 集群管理中,为确保集群的稳定性和可靠性,避免因节点故障引发一系列严重问题,我们强烈建议不要在 Deployment 或 StatefulSet 中设置 nodeName 字段,而是采用更为灵活和可靠的 nodeSelector 或 affinity 规则进行节点调度。

风险详细剖析

节点故障与状态上报机制

  1. 节点故障场景

    在 Kubernetes 集群运行过程中,节点可能会由于多种原因发生故障,例如硬件故障、软件崩溃、网络问题等。当节点出现故障时,该节点上运行的关键组件(如 kubelet)的功能将受到影响。

  2. kubelet 状态上报失效

    kubelet 在 Kubernetes 集群中负责与节点上运行的容器和其他组件进行交互,并向 kube-controller-manager 上报节点和容器的状态信息。一旦节点发生故障,kubelet 将无法正常工作,导致无法及时准确地向 kube-controller-manager 反馈节点状态。

节点标记与污点添加机制

  1. 节点标记为 not-ready

    kube-controller-manager 依赖 kubelet 上报的状态信息来判断节点的健康状况。当在一定时间内未收到节点的状态更新时,kube-controller-manager 会将该节点标记为 not-ready 状态,以表示该节点当前不可用于新的 Pod 调度。

  2. 添加 NoExecute 污点

    同时,为了防止不健康节点对集群造成更大的影响,kube-controller-manager 会在标记为 not-ready 的节点上添加 NoExecute 污点。这个污点会影响已经在该节点上运行的 Pod。

Pod 驱逐与循环创建问题

  1. Pod 驱逐触发

    当节点被添加了 NoExecute 污点后,根据 Kubernetes 的 Pod 驱逐策略,那些对污点敏感的 Pod 将被驱逐。如果 Deployment 或 StatefulSet 中使用了 nodeName 字段来指定 Pod 运行的节点,那么这些被驱逐的 Pod 在重新创建时,由于配置中固定了 nodeName,会尝试重新调度到已经故障的节点上。

  2. 循环创建现象

    由于节点故障未解决,被驱逐的 Pod 重新创建到故障节点后,可能会再次被驱逐,如此反复,形成 Pod 的循环创建和驱逐。这种循环会导致大量 Pod 处于 Terminating 状态,增加集群的负担。

服务资源耗尽风险

  1. 资源消耗

    在 Pod 循环创建和驱逐的过程中,会消耗大量的系统资源,包括 CPU、内存和网络带宽等。尤其是内存资源,在频繁的 Pod 操作过程中,可能会迅速被耗尽。

  2. 服务 OOM 错误

    关键服务(如 apiserver 和 etcd)依赖于足够的系统资源来维持正常运行。当集群资源被大量用于处理故障节点相关的 Pod 问题时,这些关键服务可能会因为得不到足够的内存而出现 OOM(内存溢出)错误,进而导致整个 Kubernetes 集群的服务中断或不稳定。

推荐的替代配置方式

使用 nodeSelector

  1. 原理

    nodeSelector 是一种基于标签的简单节点选择方法。在 Kubernetes 中,节点和 Pod 都可以被打上标签。标签是由键值对组成的元数据,用于描述节点或 Pod 的特定属性。nodeSelector 通过在 Pod 的配置中指定所需的节点标签,使 Pod 能够被调度到具有相应标签的节点上。

  2. 配置步骤

    (1)节点标签设置:使用 kubectl 命令为节点添加标签。例如,若要为节点 node-1 添加一个名为 “env=production” 的标签,可以执行以下命令:

kubectl label nodes node-1 env=production

(2)Pod 配置:在 Deployment 或 StatefulSet 的 Pod 模板中配置 nodeSelector。以下是一个示例的 Deployment 配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      nodeSelector:
        env: production
      containers:
      - name: my-container
        image: my-image

  1. 配置效果

    上述配置确保了名为 “my-deployment” 的 Deployment 所创建的 Pod 将被调度到具有 “env=production” 标签的节点上。

使用 nodeAffinity

  1. 原理

    nodeAffinity(节点亲和性)提供了更灵活和强大的节点选择机制。它支持更复杂的逻辑和条件判断,能够更好地满足多样化的集群调度需求。

  2. 配置步骤

    以下是一个使用 requiredDuringSchedulingIgnoredDuringExecution 类型的节点亲和性的示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: disk-type
                operator: In
                values:
                - ssd
      containers:
      - name: my-container
        image: my-image
  1. 配置效果

    在上述配置中,Pod 在调度时要求节点具有 “disk-type=ssd” 的标签。这种配置方式能够根据节点的特定属性进行更精准的调度。

组件 disablenodename-admission 介绍

组件功能

disablenodename-admission 是一个遵循标准 Admission wehook 规范的组件,其核心功能是禁止用户在创建或更新 Deployment 和 StatefulSet 时中设置 NodeName 字段,以防止用户将Pod强制调度到特定节点。

工作机制

在 Pod 创建过程中,disablenodename-admission 组件会介入 Pod 的创建请求处理流程。当它检测到 Pod 的 PodTemplateSpec 中存在 nodeName 字段时,会立即拒绝该 Pod 的创建操作,并返回明确的错误提示信息,引导用户采用 nodeSelector 或 affinity 规则进行节点调度。

版本与应用场景

当前版本为 0.1.0,适用于各种 Kubernetes 集群环境,特别是对集群稳定性和可靠性要求较高的生产环境。通过部署和启用该组件,可以有效地预防因不恰当使用 nodeName 字段而导致的集群故障风险。

注意:新增disablenodename-admission组件需要集群K8s版本在v1.16.0以上;如果您当前集群版本小于v1.16.0,请考虑按需升级,以避免组件安装失败。

总结

在 Kubernetes 集群的管理和操作中,避免在 Deployment 或 StatefulSet 中设置 nodeName 字段,并合理运用 nodeSelector 或 affinity 规则进行节点调度,是保障集群稳定运行的重要实践。同时,借助 disablenodename-admission 组件可以进一步强化这种配置规范,确保集群的可靠性和安全性。

纯净模式常规模式

纯净模式

点击可全屏预览文档内容

鼠标选中内容,快速反馈问题

如果在文档使用中出现问题,可选中有问题的部分进行快速反馈,我们将跟进处理。
不再提示
好的,我知道了

聆听反馈