zoukankan      html  css  js  c++  java
  • Kubernetes实践之深入掌握Pod——玩转Pod调度

    玩转Pod调度

    Deployment或RC:全自动调度

    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 
    

     NodeSelector:定向调度

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

    kubectl label nodes k8s-node-1 zone=north
    

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

    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
    

     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)的节点上

    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就可以实现排斥的功能了。

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

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

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

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

    1.参照目标Pod

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

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-flag
      labels:
        security: "S1"
        app: "nginx"
    spec:
      containers:
      - name: nginx
        image: nginx
    

    2.Pod的亲和性调度

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

    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了

     3.Pod的互斥性调度

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

    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

     Taints和Tolerations(污点和容忍)

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

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

    kubectl taint nodes node1 key=value:NoSchedule
    

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

    在Pod上声明Toleration

    spec:
      tolerations:
      - key: "key"
        operator: "Equal"
        value: "value"
        effect: "NoSchedule"
      containers:
      - name: pod-toleration
        image: gcr.io/google_containers/pause:2.0
    

     下面语法也行

      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已经在该 节点上运行,则会被驱逐;如果没有在该节点上运行,则也不会再被调 度到该节点上

    例如:

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

     Pod上设置两个Toleration:

      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) 

      tolerations:
      - key: "key1"
        operator: "Equal"
        value: "value1"
        effect: "NoSchedule"
      - key: "key1"
        operator: "Equal"
        value: "value1"
        effect: "NoExecute"
        tolerationsSeconds: 3600
    

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

     Taint和Toleration案例:

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

    NoExecute的taint影响


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

  • 相关阅读:
    RS错误RSV-VAL-0032之项目未在布局中引用的3种解决办法
    Cognos访问权限之让拒绝更友善
    SSIS包部署错误之运行环境设置
    RS开发中的一些小技巧[不定期更新]
    RS布局问题之块的不完美之完美
    Zuul使用Ribbon配置自动重试
    Eureka集群试验的一点总结
    centos 6.4 调整home和root分区大小
    ribbon区域亲和配置一例
    SpringMVC 类内部的RequestMapping注解能否被继承?
  • 原文地址:https://www.cnblogs.com/Wshile/p/12957857.html
Copyright © 2011-2022 走看看