Kubernetes实践之深入掌握Pod——玩转Pod调度

1|0玩转Pod调度

1|0Deployment或RC:全自动调度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

1|0 NodeSelector:定向调度

(1)首先通过kubectl label命令给目标Node打上一些标签:

1
kubectl label nodes k8s-node-1 zone=north

(2)然后,在Pod的定义中加上nodeSelector的设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: v1
kind: ReplicationController
metadata:
  name: redis-master
  labels:
    name: redis-master
spec:
  replicas: 1
  selector:
    name: redis-master
  template:
    metadata:
      labels:
        name: redis-master
    spec:
      containers:
      - name: master
        image: kubeguide/redis-master
        ports:
        - containerPort: 6379
      nodeSelector:
        zone: north

1|0 NodeAffinity:Node亲和性调度

RequiredDuringSchedulingIgnoredDuringExecution:必须满足指 定的规则才可以调度Pod到Node上(功能与nodeSelector很像,但是使用 的是不同的语法),相当于硬限制

PreferredDuringSchedulingIgnoredDuringExecution:强调优先满足指定规则,调度器会尝试调度Pod到Node上,但并不强求,相当于软 限制。多个优先级规则还可以设置权重(weight)值,以定义执行的先 后顺序

IgnoredDuringExecution的意思是:如果一个Pod所在的节点在Pod运 行期间标签发生了变更,不再符合该Pod的节点亲和性需求,则系统将 忽略Node上Label的变化,该Pod能继续在该节点运行

下面的例子设置了NodeAffinity调度的如下规则

requiredDuringSchedulingIgnoredDuringExecution要求只运行在 amd64的节点上(beta.kubernetes.io/arch In amd64)preferredDuringSchedulingIgnoredDuringExecution的要求是尽量 运行在磁盘类型为ssd(disk-type In ssd)的节点上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: beta.kubernetes.io/arch
            operator: In
            values:
            - amd64
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: disk-type
            operator: In
            values:
            - ssd
  containers:
  - name: with-node-affinity
    image: gcr.io/google_containers/pause:2.0

 从上面的配置中可以看到In操作符,NodeAffinity语法支持的操作 符包括In、NotIn、Exists、DoesNotExist、Gt、Lt。虽然没有节点排斥功 能,但是用NotIn和DoesNotExist就可以实现排斥的功能了。

1|0NodeAffinity规则设置的注意事项如下

  • 如果同时定义了nodeSelector和nodeAffinity,那么必须两个条 件都得到满足,Pod才能最终运行在指定的Node上。
  • 如果nodeAffinity指定了多个nodeSelectorTerms,那么其中一个 能够匹配成功即可。
  • 如果在nodeSelectorTerms中有多个matchExpressions,则一个节 点必须满足所有matchExpressions才能运行该Pod。

1|0PodAffinity:Pod亲和与互斥调度策略

Pod的亲和性被定义 于PodSpec的affinity字段下的podAffinity子字段中。Pod间的互斥性则被 定义于同一层次的podAntiAffinity子字段中

1|01.参照目标Pod

首先,创建一个名为pod-flag的Pod,带有标签security=S1和 app=nginx,后面的例子将使用pod-flag作为Pod亲和与互斥的目标Pod

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
  name: pod-flag
  labels:
    security: "S1"
    app: "nginx"
spec:
  containers:
  - name: nginx
    image: nginx

1|02.Pod的亲和性调度

下面创建第2个Pod来说明Pod的亲和性调度,这里定义的亲和标签 是security=S1,对应上面的Pod“pod-flag”,topologyKey的值被设置 为“kubernetes.io/hostname”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Pod
metadata:
  name: pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: kubernetes.io/hostname
  containers:
  - name: with-pod-affinity
    image: gcr.io/google_containers/pause:2.0

 有兴趣的读者还可以测试一下,在创建这个Pod之前,删掉这个节 点的kubernetes.io/hostname标签,重复上面的创建步骤,将会发现Pod一 直处于Pending状态,这是因为找不到满足条件的Node了

1|0 3.Pod的互斥性调度

创建第3个Pod,我们希望它不与目标Pod运行在同一个Node上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: v1
kind: Pod
metadata:
  name: anti-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: failure-domain.beta.kubernetes.io/zone
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - nginx
        topologyKey: kubernetes.io/hostname
  containers:
  - name: anti-affinity
    image: gcr.io/google_containers/pause:2.0

这里要求这个新Pod与security=S1的Pod为同一个zone,但是不与 app=nginx的Pod为同一个Node。创建Pod之后,同样用kubectl get pods -o wide来查看,会看到新的Pod被调度到了同一Zone内的不同Node上,与节点亲和性类似,Pod亲和性的操作符也包括In、NotIn、Exists、 DoesNotExist、Gt、Lt

1|0 Taints和Tolerations(污点和容忍)

Taint需要和Toleration配合使用,让Pod避开那些不合适的Node。在 Node上设置一个或多个Taint之后,除非Pod明确声明能够容忍这些污点,否则无法在这些Node上运行。Toleration是Pod的属性,让Pod能够 (注意,只是能够,而非必须)运行在标注了Taint的Node上

可以用kubectl taint命令为Node设置Taint信息:

1
kubectl taint nodes node1 key=value:NoSchedule

这个设置为node1加上了一个Taint。该Taint的键为key,值为value,Taint的效果是NoSchedule。这意味着除非Pod明确声明可以容忍 这个Taint,否则就不会被调度到node1上 

在Pod上声明Toleration

1
2
3
4
5
6
7
8
9
spec:
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"
  containers:
  - name: pod-toleration
    image: gcr.io/google_containers/pause:2.0

 下面语法也行

1
2
3
4
tolerations:
- key: "key"
  operator: "Exists"
  effect: "NoSchedule"

 Pod的Toleration声明中的key和effect需要与Taint的设置保持一致, 并且满足以下条件之一。

  •  operator的值是Exists(无须指定value)
  • operator的值是Equal并且value相等,如果不指定operator,则默认值为Equal

 另外,有如下两个特例

  • 空的key配合Exists操作符能够匹配所有的键和值
  • 空的effect匹配所有的effect

多个Taint和Toleration会先忽略匹配的部分,在按如下规则匹配:

  • 如果在剩余的Taint中存在effect=NoSchedule,则调度器不会把该Pod调度到这一节点上
  • 如果在剩余的Taint中没有NoSchedule效果,但是有PreferNoSchedule效果,则调度器会尝试不把这个Pod指派给这个节点
  • 如果在剩余的Taint中有NoExecute效果,并且这个Pod已经在该 节点上运行,则会被驱逐;如果没有在该节点上运行,则也不会再被调 度到该节点上

例如:

1
2
3
kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule

 Pod上设置两个Toleration:

1
2
3
4
5
6
7
8
9
tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"

这样的结果是该Pod无法被调度到node1上,这是因为第3个Taint没 有匹配的Toleration。但是如果该Pod已经在node1上运行了,那么在运行 时设置第3个Taint,它还能继续在node1上运行,这是因为Pod可以容忍前两个Taint。

Node加上effect=NoExecute的Taint,那么在该 Node上正在运行的所有无对应Toleration的Pod都会被立刻驱逐,系统允许给具有NoExecute 效果的Toleration加入一个可选的tolerationSeconds字段,这个设置表明 Pod可以在Taint添加到Node之后还能在这个Node上运行多久(单位为 s) 

1
2
3
4
5
6
7
8
9
10
tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
  tolerationsSeconds: 3600

 上述定义的意思是,如果Pod正在运行,所在节点都被加入一个匹 配的Taint,则这个Pod会持续在这个节点上存活3600s后被逐出。如果在 这个宽限期内Taint被移除,则不会触发驱逐事件

1|0 Taint和Toleration案例:

1|01.独占节点
1
kubectl taint nodes nodename dedicated=groupName:NoSchedule
1|0 2.具有特殊硬件设备的节点
1
2
kubectl taint nodes nodename special=true:NoSchedule
kubectl taint nodes nodename special=true:PreferNoSchedule
1|03.定义Pod驱逐行为,以应对节点故障 

NoExecute的taint影响


没有设置Toleration的Pod会被立刻驱逐
配置了对应Toleration的Pod,如果没有为tolerationSeconds赋值,则会一直留在这一节点中
配置了对应Toleration的Pod且指定了tolerationSeconds值,则会 在指定时间后驱逐

 


__EOF__

本文作者Wshile
本文链接https://www.cnblogs.com/Wshile/p/12957857.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Wshile  阅读(342)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示