欢迎光临
我们一直在努力

Kubernetes 核心特性实战:亲和性调度、污点容忍与 emptyDir 存储卷

目录

前言

一、节点亲和性:让 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 定义(如节点标签 yjs、kubernetes.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 可容忍节点 node01 的 check=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> 恢复节点的可调度状态

驱逐流程

  • Kubernetes 向 Pod 发送 SIGTERM 信号,通知 Pod 优雅终止。
  • 等待一段时间(默认 30 秒),若 Pod 未终止,发送 SIGKILL 强制终止。
  • 若 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 等持久化存储方案,敬请关注!

    赞(0)
    未经允许不得转载:171主机测评 » Kubernetes 核心特性实战:亲和性调度、污点容忍与 emptyDir 存储卷
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址