目录

前言

一、节点亲和性:让 Pod “偏好” 特定节点

1. 核心概念

2. 实操案例

案例 1:硬策略(排除特定节点)

案例 2:软策略(优先特定节点)

案例 3:软硬结合策略

二、Pod 亲和性与反亲和性:让 Pod “结伴” 或 “避嫌”

1. 核心区别

2. 实操案例

案例 1:Pod 亲和性(同拓扑域部署)

案例 2:Pod 反亲和性(不同节点部署)

三、污点与容忍:让节点 “拒绝” 或 “接纳” Pod

1. 污点核心概念

3. 容忍配置案例

四、驱逐机制:安全迁移 Pod

驱逐流程

五、emptyDir 存储卷:Pod 内容器共享临时存储

1. 核心特点

2. 实操案例:双容器共享数据

总结


前言

在 Kubernetes 集群管理中,Pod 调度的合理性和容器存储的稳定性是保障应用高效运行的关键。本文将聚焦 节点亲和性与 Pod 亲和性污点与容忍驱逐机制 以及 emptyDir 存储卷,通过通俗解释 + 实操案例,帮你快速掌握这些核心特性的用法与场景。

一、节点亲和性:让 Pod “偏好” 特定节点

节点亲和性(NodeAffinity)是 Pod 的一种属性,用于让 Pod 被 “吸引” 到一类特定节点上,支持 硬策略(必须满足)和 软策略(优先满足),比 nodeSelector 更灵活。

1. 核心概念

  • 硬策略(requiredDuringSchedulingIgnoredDuringExecution):Pod 必须调度到满足条件的节点,否则处于 Pending 状态。
  • 软策略(preferredDuringSchedulingIgnoredDuringExecution):Pod 优先调度到满足条件的节点,无满足节点时可调度到其他节点。
  • 操作符:用于定义标签匹配规则,支持 6 种类型:
运算符 通俗解释 应用场景 示例
In 标签值在指定列表中 筛选符合条件的节点 env In (dev, test)
NotIn 标签值不在指定列表中 排除特定节点 env NotIn (prod)
Gt 标签值大于指定数值 选择数值更大的节点 version Gt 3
Lt 标签值小于指定数值 选择数值更小的节点 version Lt 3
Exists 节点存在该标签(不论值) 筛选带有特定标签的节点 Exists zone
DoesNotExist 节点不存在该标签 筛选无该标签的节点 DoesNotExist debug

2. 实操案例

案例 1:硬策略(排除特定节点)

需求:Pod 不能调度到 kubernetes.io/hostname=node02 的节点上。

1.查看节点标签:
kubectl get nodes --show-labels
 
2.编写 Pod 配置(pod1.yaml):
apiVersion: v1
kind: Pod
metadata:
  name: affinity-hard
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: NotIn
            values:
            - node02
 
3.部署并验证:
kubectl apply -f pod1.yaml
kubectl get pods -o wide  # 查看 Pod 是否调度到 node01
 

注意:若无满足条件的节点,Pod 会一直处于 Pending 状态。

案例 2:软策略(优先特定节点)

需求:Pod 优先调度到 node03,无 node03 时调度到其他节点。

1.编写配置(pod2.yaml):
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
 
2.部署验证:
kubectl apply -f pod2.yaml
kubectl get pods -o wide  # 确认 Pod 运行在 node01 或 node02 上
 

案例 3:软硬结合策略

需求:Pod 不能调度到 node02(硬策略),优先调度到 yjs=a 的节点(软策略)。

apiVersion: v1
kind: Pod
metadata:
  name: affinity-mix
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
  affinity:
    nodeAffinity:
      # 硬性要求:必须不在 node02 上运行
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: NotIn
            values:
            - node02
      
      # 软性偏好:优先选择带有 yjs=a 标签的节点
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        preference:
          matchExpressions:
          - key: yjs
            operator: In
            values:
            - a
 

二、Pod 亲和性与反亲和性:让 Pod “结伴” 或 “避嫌”

Pod 亲和性(PodAffinity)/ 反亲和性(PodAntiAffinity)基于已运行 Pod 的标签进行调度,支持 拓扑域(如节点、机架、区域),实现 Pod 间的 “聚集” 或 “分散” 部署。

1. 核心区别

调度策略匹配对象支持拓扑域核心目标

策略类型 匹配对象 支持拓扑域 核心目标
PodAffinity 其他 Pod 新 Pod 与指定 Pod 同拓扑域
PodAntiAffinity 其他 Pod 新 Pod 与指定 Pod 不同拓扑域

拓扑域由 topologyKey 定义(如节点标签 yjskubernetes.io/hostname),相同 topologyKey 值的节点属于同一拓扑域。

2. 实操案例

案例 1:Pod 亲和性(同拓扑域部署)

需求:新 Pod 必须与 app=myapp01 的 Pod 处于 yjs 标签相同的拓扑域。

1,先创建参考 Pod(myapp01):
apiVersion: v1
kind: Pod
metadata:
  name: myapp01
  labels:
    app: myapp01
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
 
kubectl apply -f pod3.yaml
kubectl get pods -o wide
 

2.编写亲和性 Pod 配置(pod4.yaml):
apiVersion: v1
kind: Pod
metadata:
  name: myapp02
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - myapp01
        topologyKey: yjs
 
3.验证:
kubectl apply -f pod4.yaml
 
kubectl get pods -o wide
 

案例 2:Pod 反亲和性(不同节点部署)

需求:新 Pod 避免与 app=myapp01 的 Pod 部署在同一节点。

apiVersion: v1
kind: Pod
metadata:
  name: myapp10
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - myapp01
          topologyKey: kubernetes.io/hostname
 

三、污点与容忍:让节点 “拒绝” 或 “接纳” Pod

污点(Taint)是节点的属性,用于排斥特定 Pod;容忍(Tolerations)是 Pod 的属性,用于 “忽略” 节点的污点,两者配合实现 Pod 调度的精准控制。

1. 污点核心概念

  • 格式:key=value:effect(value 可空)
  • Effect(污点作用):

NoSchedule:禁止新 Pod 调度至该节点(已运行的 Pod 不受影响)

PreferNoSchedule:尽量避免新 Pod 调度至该节点(非强制性)

NoExecute:禁止新 Pod 调度并驱逐已运行且不容忍该污点的 Pod

2.污点操作命令

# 给节点 node01 添加 NoSchedule 污点(阻止新 Pod 调度)
kubectl taint node node01 app=backend:NoSchedule

# 检查节点污点状态
kubectl describe node node01 | grep -i taints

# 移除 node01 的 NoSchedule 污点
kubectl taint node node01 app:NoSchedule-

# 给节点 node02 添加 NoExecute 污点(立即驱逐非容忍 Pod)
kubectl taint node node02 maintenance=true:NoExecute
 

3. 容忍配置案例

需求:Pod 可容忍节点 node01check=mycheck:NoExecute 污点。

1.node01 设置污点:

kubectl taint node node01 check=mycheck:NoExecute
 

2.编写带容忍的 Pod 配置(pod-tolerate.yaml):

apiVersion: v1
kind: Pod
metadata:
  name: myapp-tolerate
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
  tolerations:
  - key: "check"
    operator: "Equal"
    value: "mycheck"
    effect: "NoExecute"
    tolerationSeconds: 3600
 

3.验证:

kubectl apply -f pod-tolerate.yaml
 
kubectl get pods -o wide
 

四、驱逐机制:安全迁移 Pod

驱逐(Eviction)是将运行中的 Pod 从节点迁移到其他节点的过程,用于节点维护、资源不足等场景,核心命令如下:

命令功能:

kubectl cordon <node>
将节点标记为不可调度状态(不影响已运行的 Pod)

kubectl drain <node> --ignore-daemonsets --delete-local-data
驱逐节点上所有 Pod(跳过 DaemonSet 管理的 Pod,并清理本地数据)

kubectl uncordon <node>
恢复节点的可调度状态

驱逐流程

  1. Kubernetes 向 Pod 发送 SIGTERM 信号,通知 Pod 优雅终止。
  2. 等待一段时间(默认 30 秒),若 Pod 未终止,发送 SIGKILL 强制终止。
  3. 若 Pod 由 Deployment/StatefulSet 管理,会在其他节点自动重建,维持副本数。

五、emptyDir 存储卷:Pod 内容器共享临时存储

容器文件系统是临时的(崩溃重启后数据丢失),emptyDir 是 Kubernetes 提供的临时存储卷,解决 Pod 内多容器数据共享临时数据持久化 问题。

1. 核心特点

  • 生命周期与 Pod 一致:Pod 调度到节点时自动创建,Pod 删除时数据销毁。
  • 存储介质:默认使用节点本地磁盘,也可使用内存(性能更高)。
  • 适用场景:临时缓存、Pod 内容器数据共享。

2. 实操案例:双容器共享数据

需求:Pod 内两个容器(nginx + busybox)共享 emptyDir 卷,busybox 持续写入日期,nginx 提供访问。

1.编写配置(pod-emptydir.yaml):

apiVersion: v1
kind: Pod
metadata:
  name: pod-emptydir
spec:
  containers:
  # nginx 容器:提供 web 访问
  - name: nginx
    image: ikubernetes/myapp:v1
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html  # 挂载卷名称(与下方 volumes 一致)
      mountPath: /usr/share/nginx/html  # 容器内挂载路径
  # busybox 容器:持续写入日期到共享文件
  - name: busybox
    image: busybox:latest
    volumeMounts:
    - name: html
      mountPath: /data  # 容器内挂载路径
    command: ["/bin/sh", "-c", "while true; do echo $(date) >> /data/index.html; sleep 2; done"]
  # 定义 emptyDir 存储卷
  volumes:
  - name: html
    emptyDir: {}  # 临时存储卷(默认磁盘存储)
 

2.部署并验证:

# 部署 Pod
kubectl apply -f pod-emptydir.yaml

# 检查 Pod 状态(确保 STATUS 显示为 Running)
kubectl get pods -o wide

# 获取 Pod IP 并测试数据共享
POD_IP=$(kubectl get pod shared-storage-pod -o jsonpath='{.status.podIP}')
curl $POD_IP
 

总结

本文介绍的特性可总结为:

  • 亲和性:让 Pod “主动选择” 节点(节点亲和性)或 “追随” 其他 Pod(Pod 亲和性)。
  • 污点与容忍:让节点 “被动拒绝” Pod,容忍则是 Pod 的 “例外申请”。
  • 驱逐:安全迁移 Pod,保障节点维护时业务不中断。
  • emptyDir:解决 Pod 内容器临时共享存储问题。

这些特性是 Kubernetes 调度与存储的基础,灵活运用可实现集群资源的高效利用和应用的稳定运行。后续将继续分享 PV/PVC、StorageClass 等持久化存储方案,敬请关注!

Logo

脑启社区是一个专注类脑智能领域的开发者社区。欢迎加入社区,共建类脑智能生态。社区为开发者提供了丰富的开源类脑工具软件、类脑算法模型及数据集、类脑知识库、类脑技术培训课程以及类脑应用案例等资源。

更多推荐