kubernetes高级资源之污点和容忍

一、介绍

# Kubernetes 高级资源:污点(Taints)和容忍(Tolerations)

## 污点(Taints)的作用

污点是节点(Node)的一个属性,它允许节点排斥一组特定的Pod。主要作用包括:

1. **节点专用**:确保某些节点只运行特定类型的Pod
   - 例如:保留带有GPU的节点只运行机器学习工作负载

2. **节点隔离**:
   - 维护节点时,可以给节点添加污点以防止新Pod被调度到该节点
   - 隔离问题节点,防止Pod被调度到不健康的节点上

3. **特殊硬件保留**:
   - 为具有特殊硬件(如SSD、GPU)的节点添加污点
   - 只有声明了相应容忍的Pod才能使用这些特殊资源

4. **多租户隔离**:
   - 在不同团队或项目间划分集群资源

## 容忍(Tolerations)的作用

容忍是Pod的一个属性,它允许(但不强制要求)Pod被调度到带有匹配污点的节点上。主要作用包括:

1. **访问专用节点**:
   - 允许特定Pod调度到带有污点的专用节点上
   - 例如:只有机器学习工作负载能使用GPU节点

2. **应对节点维护**:
   - 关键Pod可以容忍"NoSchedule"污点,确保在节点维护期间仍能运行

3. **处理节点问题**:
   - 关键系统Pod可以容忍"NoExecute"污点,即使节点出现问题也不被驱逐

4. **多租户资源共享**:
   - 允许高优先级工作负载使用为其他团队保留的资源

## 污点效果类型

1. **NoSchedule**:
   - 不会调度不容忍此污点的Pod到该节点
   - 已运行的Pod不受影响

2. **PreferNoSchedule**:
   - 尽量不调度不容忍此污点的Pod到该节点
   - 如果没有其他可用节点,仍可能调度

3. **NoExecute**:
   - 不会调度不容忍此污点的Pod到该节点
   - 已运行但不容忍此污点的Pod会被驱逐

## 使用示例

为节点添加污点:
```bash
kubectl taint nodes node1 key=value:NoSchedule
```

Pod中的容忍配置:
```yaml
tolerations:
- key: "key"
  operator: "Equal"
  value: "value"
  effect: "NoSchedule"
```

污点和容忍机制共同工作,为Kubernetes集群提供了精细的Pod调度控制能力,是生产环境中实现资源隔离和优先级调度的重要工具。

二、实战部署

[root@master ~]# kubectl taint node node1 cjr=yyj:NoSchedule
node/node1 tainted
[root@master ~]# kubectl get node
NAME     STATUS   ROLES           AGE    VERSION
master   Ready    control-plane   120m   v1.31.3
node1    Ready    <none>          119m   v1.31.3
node2    Ready    <none>          119m   v1.31.3
[root@master ~]# kubectl describe node node1 | grep Taint
Taints:             cjr=yyj:NoSchedule
[root@master ~]# kubectl apply -f tomcat.tar.gz
error: error parsing tomcat.tar.gz: invalid Yaml document separator: %s ping statistics ---
[root@master ~]# kubectl apply -f pod-taint.yaml
pod/taint-pod created
[root@master ~]# kubectl get pod -owide
NAME        READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
myapp3      1/1     Running   0          40m   10.244.166.145   node1   <none>           <none>
myapp4      1/1     Running   0          40m   10.244.166.146   node1   <none>           <none>
taint-pod   1/1     Running   0          4s    10.244.104.9     node2   <none>           <none>
[root@master ~]# cat pod-taint.yaml
apiVersion: v1
kind: Pod
metadata:
  name: taint-pod
  namespace: default
  labels:
    tomcat:  tomcat-pod
spec:
  containers:
  - name:  taint-pod
    ports:
    - containerPort: 8080
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent

[root@master ~]# kubectl taint node node2 c=y:NoExecute
node/node2 tainted

[root@master ~]# kubectl get pod -owide -w
NAME        READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
myapp3      1/1     Running   0          41m   10.244.166.145   node1   <none>           <none>
myapp4      1/1     Running   0          41m   10.244.166.146   node1   <none>           <none>
taint-pod   1/1     Running   0          6s    10.244.104.10    node2   <none>           <none>
taint-pod   1/1     Running   0          102s   10.244.104.10    node2   <none>           <none>
taint-pod   1/1     Terminating   0          102s   10.244.104.10    node2   <none>           <none>
taint-pod   1/1     Terminating   0          102s   10.244.104.10    node2   <none>           <none>
taint-pod   1/1     Terminating   0          102s   10.244.104.10    node2   <none>           <none>
taint-pod   0/1     Error         0          102s   10.244.104.10    node2   <none>           <none>
taint-pod   0/1     Error         0          103s   10.244.104.10    node2   <none>           <none>
taint-pod   0/1     Error         0          103s   10.244.104.10    node2   <none>           <none>

[root@node1 ~]# kubectl describe node node1 | grep Taints
Taints:             cjr=yyj:NoSchedule
[root@node1 ~]# kubectl describe node node2 | grep Taints
Taints:             cjr=yyj:NoExecute

[root@master ~]# vi pod-taint.yaml
apiVersion: v1
kind: Pod
metadata:
  name: taint-pod
  namespace: default
  labels:
    tomcat:  tomcat-pod
spec:
  containers:
  - name:  taint-pod
    ports:
    - containerPort: 8080
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
  tolerations:
  - effect: NoSchedule
    key:
    value:
    operator: Exists

[root@master ~]# kubectl get pod -owide -w
NAME        READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
myapp3      1/1     Running   0          61m   10.244.166.145   node1   <none>           <none>
myapp4      1/1     Running   0          61m   10.244.166.146   node1   <none>           <none>
taint-pod   1/1     Running   0          10s   10.244.166.150   node1   <none>           <none>

[root@master ~]# vi pod-taint.yaml
apiVersion: v1
kind: Pod
metadata:
  name: taint-pod
  namespace: default
  labels:
    tomcat:  tomcat-pod
spec:
  containers:
  - name:  taint-pod
    ports:
    - containerPort: 8080
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
  tolerations:
  - effect: NoExecute
    key: cjr
    value: yyj
    operator: Equal

root@master ~]# kubectl get pod -owide -w
NAME        READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
myapp3      1/1     Running   0          62m   10.244.166.145   node1   <none>           <none>
myapp4      1/1     Running   0          62m   10.244.166.146   node1   <none>           <none>
taint-pod   1/1     Running   0          12s   10.244.104.12    node2   <none>           <none>

三、总结

# Kubernetes污点(Taints)和容忍(Tolerations)实验总结

## 实验过程回顾

1. **初始节点状态**:
   - 集群有3个节点:master(control-plane)、node1和node2
   - 初始状态下节点没有污点

2. **添加污点**:
   - 给node1添加`NoSchedule`污点:`cjr=yyj:NoSchedule`
   - 给node2添加`NoExecute`污点:`c=y:NoExecute`

3. **Pod调度行为观察**:
   - 未配置容忍的Pod无法调度到node1(NoSchedule效果)
   - 已运行在node2的Pod被立即驱逐(NoExecute效果)

4. **添加容忍测试**:
   - 首先添加通用容忍(`operator: Exists`),Pod可调度到node1
   - 然后添加精确匹配的容忍(`key: cjr, value: yyj, operator: Equal`),Pod可调度到node2

## 关键结论

1. **污点效果差异**:
   - `NoSchedule`:只影响新Pod调度,不影响已运行Pod
   - `NoExecute`:既影响新Pod调度,也会驱逐已运行的不容忍Pod

2. **容忍配置方式**:
   - **宽松容忍**:使用`operator: Exists`可容忍任意污点(不指定key/value)
   - **精确匹配**:使用`operator: Equal`并指定key/value可针对特定污点

3. **调度优先级**:
   - 当Pod同时满足节点选择条件和容忍条件时才会被调度
   - 容忍只是"允许"而非"强制"调度到污点节点

4. **生产环境建议**:
   - 对关键系统组件(如DaemonSet)配置适当的容忍
   - 谨慎使用`NoExecute`,可能导致服务中断
   - 为专用节点设计清晰的污点命名规范

## 示例配置解析

```yaml
# 精确匹配容忍配置示例
tolerations:
- key: "cjr"
  operator: "Equal"
  value: "yyj"
  effect: "NoExecute"

# 宽松容忍配置示例
tolerations:
- operator: "Exists"
  effect: "NoSchedule"
```

通过本次实验,清晰演示了污点和容忍如何协同工作控制Pod调度,这是Kubernetes高级调度策略的重要组成部分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

云原生的爱好者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值