• K8S入门篇资源调度


    一、Job

    1 Job可以干什么

    Job可以干什么?在容器启动或退出时做一些任务。Job可以并行执行。

    1、需要等待后执行的任务

    2、导入SQL文件

    3、创建用户、清理表

    ........等等

    示例:

    cat job-pi.yaml 
    
    apiVersion: batch/v1
    kind: Job
    metadata:
      labels:
        job-name: echo-pi
      name: echo-pi
      namespace: default
    spec:
      #suspend: true # 1.21+
      #ttlSecondsAfterFinished: 100
      backoffLimit: 4
      completions: 10
      parallelism: 3
      template:
        spec:
          containers:
          - name: pi
            image: perl:5.34.0
            command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
            imagePullPolicy: Always
            resources: {}
          restartPolicy: Never
    

      

    查看job:

     

     注意事项:

     二、CronJob

    CronJob用于以时间为基准周期性地执行任务,这些自动化任务和运行在Linux或UNIX系统上的CronJob一样。CronJob对于创建定期和重复任务非常有用,例如执行备份任务、周期性调度程序接口、发送电子邮件等。

    对于Kubernetes 1.8以前的版本,需要添加--runtime-config=batch/v2alpha1=true参数至APIServer中,然后重启APIServer和Controller Manager用于启用API,对于1.8以后的版本无须修改任何参数,可以直接使用,本节的示例基于1.8以上的版本。

    2.1 创建CronJob

    创建CronJob有两种方式,一种是直接使用kubectl创建,一种是使用yaml文件创建。

    使用kubectl创建CronJob的命令如下:

    kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
    

      

    对应的yaml文件如下:

    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      name: hello
    spec:
      schedule: "*/1 * * * *"
      jobTemplate:
        spec:
          template:
            spec:
              containers:
              - name: hello
                image: busybox
                args:
                - /bin/sh
                - -c
                - date; echo Hello from the Kubernetes cluster
              restartPolicy: OnFailure
    

      

    本例创建一个每分钟执行一次、打印当前时间和Hello from the Kubernetes cluster的计划任务。

    查看创建的CronJob:

    kubectl get cj

    kubectl logs hello-27779598-pzznh

     

    2.2 CronJob参数

    2.3 suspend参数测试

    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      name: hello
    spec:
      schedule: "*/1 * * * *"
      suspend: true  #加上suspend参数
      jobTemplate:
        spec:
          template:
            spec:
              containers:
              - name: hello
                image: busybox
                args:
                - /bin/sh
                - -c
                - date; echo Hello from the Kubernetes cluster
              restartPolicy: OnFailure
    

      

     再次查看cronjob,超过1分钟后,也没有继续执行:

    查看是否被挂起:  

    kubectl get cronjob/hello -oyaml

     

    恢复挂起:

    kubectl patch cronjob/hello --type=strategic --patch '{"spec":{"suspend":false}}'
    

      

     再次查看是否被挂起:

    三、InitContainer

    3.1 初始化容器的用途


    在主应用启动之前,做一些初始化的操作,比如创建文件、修改内核参数、等待依赖程序启动或其他需要在主程序启动之前需要做的工作。

    3.2 Init容器和PostStart的区别

    PostStart:依赖主应用的环境,而且并不一定先于Command运行【如果执行失败,则主容器会不断重启】

    InitContainer:不依赖主应用的环境,可以有更高的权限和更多的工具,一定会在主应用启动之前完成【如果执行失败的话,主容器是不会执行的】

     3.3 Init容器和普通容器的区别

    Init 容器与普通的容器非常像,除了如下几点:

    • 它们总是运行到完成;
    • 上一个运行完成才会运行下一个;
    • 如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止,但是Pod 对应的 restartPolicy 值为 Never,Kubernetes 不会重新启动 Pod。
    • Init 容器不支持 lifecycle、livenessProbe、readinessProbe 和 startupProbe

    3.4 Init容器配置解析

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: es-cluster
    spec:
      serviceName: elasticsearch
      replicas: 3
      selector:
        matchLabels:
          app: elasticsearch
      template:
        metadata:
          labels:
            app: elasticsearch
        spec:
          volumes:
          - name: data  #设置一个emptyDir类型的共享目录,用于容器间内容共享
            emptyDir: {}
          initContainers:  #定义初始化容器
          - name: fix-permissions
            image: busybox  #定义一个容器,用于修改目录权限
            command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
            securityContext:
              privileged: true
            volumeMounts:  #进行目录挂载
            - name: data
              mountPath: /usr/share/elasticsearch/data
          - name: increase-vm-max-map  #修改内核参数
            image: busybox
            command: ["sysctl", "-w", "vm.max_map_count=262144"]
            securityContext:
              privileged: true
          - name: increase-fd-ulimit  # 修改内核参数
            image: busybox
            command: ["sh", "-c", "ulimit -n 65536"]
            securityContext:
              privileged: true
          containers:    #实际使用的容器
          - name: elasticsearch
            #image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.3
            image: dotbalo/es:2.4.6-cluster
            imagePullPolicy: Always
            resources:
                limits:
                  cpu: 1000m
                requests:
                  cpu: 100m
            ports:
            - containerPort: 9200
              name: rest
              protocol: TCP
            - containerPort: 9300
              name: inter-node
              protocol: TCP
            volumeMounts:
            - name: data  #挂载数据目录,由于是以普通用户启动,所以没权限修改所属用户和组,需要通过初始化容器来进行所属组和用户
              mountPath: /usr/share/elasticsearch/data
            env:
              - name: "cluster.name"
                value: "pscm-cluster"
              - name: "CLUSTER_NAME"
                value: "pscm-cluster"
              - name: "discovery.zen.minimum_master_nodes"
                value: "2"
              - name: "MINIMUM_MASTER_NODES"
                value: "2"
              - name: "node.name"
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: "NODE_NAME"
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: "discovery.zen.ping.unicast.hosts"
                value: "es-cluster-0.elasticsearch, es-cluster-1.elasticsearch, es-cluster-2.elasticsearch"
              #- name: ES_JAVA_OPTS
              #  value: "-Xms512m -Xmx512m"
    

      

    3.5 初始化容器示例

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: test-init
      name: test-init
      namespace: kube-public
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: test-init
      template:
        metadata:
          labels:
            app: test-init
        spec:
          volumes:
          - name: data
            emptyDir: {}
          initContainers:
          - command:
            - sh
            - -c
            - touch /mnt/test-init.txt
            image: nginx
            imagePullPolicy: IfNotPresent
            name: init-touch
            volumeMounts:
            - name: data
              mountPath: /mnt
          - command:
            - sh
            - -c
            - for i in `seq 1 100`; do echo $i; sleep 1; done
            image: nginx
            imagePullPolicy: IfNotPresent
            name: echo
          containers:
          - image: nginx
            imagePullPolicy: IfNotPresent
            name: test-init
            volumeMounts:
            - name: data
              mountPath: /mnt
    

      我们创建了2个初始化容器,第一个是创建一个文件;第二个是打印一串数字。

     

    四、临时容器(EphemeralContainers)

     在pod里面注入一个具有很多debug工具的容器,用于排查问题或故障。

    开启临时容器功能:

    Master节点
    vi /usr/lib/systemd/system/kube-apiserver.service
    --feature-gates=EphemeralContainers=true
    
    vi /usr/lib/systemd/system/kube-controller-manager.service
    --feature-gates=EphemeralContainers=true
    
    vi /usr/lib/systemd/system/kube-scheduler.service
    --feature-gates=EphemeralContainers=true
    
    所有节点
    vi /usr/lib/systemd/system/kube-proxy.service
    --feature-gates=EphemeralContainers=true
    
    vi /etc/kubernetes/kubelet-conf.yml
    featureGates:
      EphemeralContainers: true
    
    重启所有服务
    System restart kube-apiserver kube-controller-manager kube-scheduler kube-proxy kubelet
    

      

     临时容器使用

    K8s 1.20+  kubectl debug redis-new-5b577b46c7-2jv4j -ti --image=debug-tools
    

      

    五、污点和容忍

    5.1 调度的场景

    Master节点:保证master组件正常运行,一般不建议生产pod调度到master上。

    新增节点:灰度一些pod上来看看是否正常

    维护节点:节点维护时,临时不让新的pod调度上来

    特殊节点:比如ssd机器、GPU机器等特殊属性的节点,只能指定pod调度上来

    5.2 什么是污点和容忍度?

    污点(Taint) 是应用在节点之上的,从这个名字就可以看出来,是为了排斥pod 所存在的。

    容忍度(Toleration)是应用于 Pod 上的,允许(但并不要求)Pod 调度到带有与之匹配的污点的节点上。

     

    5.3 污点和容忍度的作用?

    Taint(污点)和 Toleration(容忍)可以作用于node和 pod 上,其目的是优化pod在集群间的调度,这跟节点亲和性类似,只不过它们作用的方式相反,具有taint的node和pod是互斥关系,而具有节点亲和性关系的node和pod是相吸的。另外还有可以给node节点设置label,通过给pod设置nodeSelector将pod调度到具有匹配标签的节点上。

    Taint 和 toleration 相互配合,可以用来避免pod被分配到不合适的节点上。每个节点上都可以应用一个或多个taint,这表示对于那些不能容忍这些taint的 pod,是不会被该节点接受的。如果将toleration应用于pod上,则表示这些pod可以(但不要求)被调度到具有相应taint的节点上。

     

    5.4 给节点打污点

    给节点node1增加一个污点,它的键名是key1,键值是value1,效果是NoSchedule。 这表示只有拥有和这个污点相匹配的容忍度的 Pod 才能够被分配到node1这个节点。

    kubectl taint nodes node1 key1=value1:NoSchedule
    

     

    若要移除上述命令所添加的污点,你可以执行:

    kubectl taint nodes node1 key1=value1:NoSchedule-
    
    kubectl taint nodes node1 key1:NoSchedule-
    

      二者都可以,k8s不会看value值,只会对比key和effect。

     

    5.5  在pod 中定义容忍度

    可以在 PodSpec 中定义 Pod 的容忍度。 下面两个容忍度均与上面例子中使用kubectl taint命令创建的污点相匹配, 因此如果一个 Pod 拥有其中的任何一个容忍度都能够被分配到node1

    #完全匹配
    
    tolerations:
    - key: "key1"
      operator: "Equal"
      value: "value1"
      effect: "NoSchedule"
    
    #模糊匹配
    
    tolerations:
    - key: "key1"
      operator: "Exists"
      effect: "NoSchedule"
    

      

     

    5.6 toleration实例

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        env: test
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
      tolerations:
      - key: "ssd"  #存在ssd这个key,且effect为NoSchedule的节点,可以被容忍,也就是可以被调度上去。
        operator: "Exists"
        effect: "NoSchedule"
    

      

    operator 的默认值是 Equal

    一个容忍度和一个污点相“匹配”是指它们有一样的键名和效果,并且:

    • 如果 operator 是 Exists (此时容忍度不能指定 value
    • 如果 operator 是 Equal ,则它们的 value 应该相等
    • 如果 operator 不指定,则默认为Equal

    注意:

    • 如果一个容忍度的 key 为空且 operator 为 Exists, 表示这个容忍度与任意的 key 、value 和 effect 都匹配,即这个容忍度能容忍任意 taint。
    • 如果 effect 为空,则可以与所有键名 key1 的效果相匹配。

    effect 的参数含义

    • NoSchedule 新的不能容忍的pod不能再调度过来,但是之前运行在node节点中的Pod不受影响
    • NoExecute 新的不能容忍的pod不能调度过来,老的pod也会被驱逐
    • PreferNoScheduler 表示尽量不调度到污点节点中去

     

    5.7 多个污点的匹配原则

    可以给一个节点添加多个污点,也可以给一个 Pod 添加多个容忍度设置。

    Kubernetes 处理多个污点和容忍度的过程就像一个过滤器:从一个节点的所有污点开始遍历, 过滤掉那些 Pod 中存在与之相匹配的容忍度的污点。余下未被过滤的污点的 effect 值决定了 Pod 是否会被分配到该节点,特别是以下情况:

    • 如果未被过滤的污点中存在至少一个 effect 值为 NoSchedule 的污点, 则 Kubernetes 不会将 Pod 分配到该节点。
    • 如果未被过滤的污点中不存在 effect 值为 NoSchedule 的污点, 但是存在 effect 值为 PreferNoSchedule 的污点, 则 Kubernetes 会 尝试 不将 Pod 分配到该节点。
    • 如果未被过滤的污点中存在至少一个 effect 值为 NoExecute 的污点, 则 Kubernetes 不会将 Pod 分配到该节点(如果 Pod 还未在节点上运行), 或者将 Pod 从该节点驱逐(如果 Pod 已经在节点上运行)。

     例如,假设您给一个节点添加了如下污点

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

      

    假定有一个 Pod,它有两个容忍度:

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

      

    上述 Pod 不会被分配到 node1 节点,因为其没有容忍度和第三个污点相匹配。

    但是如果在给节点添加上述污点之前,该 Pod 已经在上述节点运行, 那么它还可以继续运行在该节点上,因为第三个污点是三个污点中唯一不能被这个 Pod 容忍的。

     

    5.8 设置NoExcute 的驱逐时间

    通常情况下,如果给一个节点添加了一个 effect 值为NoExecute的污点, 则任何不能忍受这个污点的 Pod 都会马上被驱逐, 任何可以忍受这个污点的 Pod 都不会被驱逐。

    但是,如果 Pod 存在一个 effect 值为NoExecute的容忍度指定了可选属性tolerationSeconds的值,则表示在给节点添加了上述污点之后, Pod 还能继续在节点上运行的时间。

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

      这表示如果这个 Pod 正在运行,同时一个匹配的污点被添加到其所在的节点, 那么 Pod 还将继续在节点上运行 3600 秒,然后被驱逐。 如果在此之前上述污点被删除了,则 Pod 不会被驱逐。

    5.9 容忍的匹配方式

    #方式一、完全匹配 key为ssd,且值是true,effect是NoSchedule
    
    tolerations:
    - key: "ssd"
      operator: "Equal"
      value: "true"
      effect: "NoSchedule"
    
    
    #方式二、不完全匹配 key存在,且effect为NoSchedule
    
    tolerations:
    - key: "ssd"
      operator: "Exists"
      effect: "NoSchedule"
    
    #方式三、大范围匹配 key存在就行,不推荐为内置Taint
    
    tolerations:
    - key: "ssd"
      operator: "Exists"
    
    #方式四、匹配所有,不推荐!!
    
    tolerations:
    - operator: "Exists"
    
    
    #方式五、完全匹配 key为ssd,且值是true,effect是NoSchedule,保留时间配置,1小时后就迁移走
    
    tolerations:
    - key: "ssd"
      operator: "Equal"
      value: "true"
      effect: "NoExecute"
      tolerationSeconds: 3600
    

      

    5.10 基于污点的驱逐

    这是在每个 Pod 中配置的在节点出现问题时的驱逐行为。

    前文提到过污点的 effect 值 NoExecute会影响已经在节点上运行的 Pod

    • 如果 Pod 没有配置忍受 effect 值为 NoExecute 的污点,那么 Pod 将马上被驱逐
    • 如果 Pod 配置了忍受 effect 值为 NoExecute 的污点,但是在容忍度定义中没有指定 tolerationSeconds,则 Pod 还会一直在这个节点上运行。
    • 如果 Pod 配置了忍受 effect 值为 NoExecute 的污点,而且指定了 tolerationSeconds, 则 Pod 还能在这个节点上继续运行这个指定的时间长度。

    当某种条件为真时,节点控制器会自动给节点添加一个污点。当前内置的污点包括:

    • node.kubernetes.io/not-ready:节点未准备好。这相当于节点状态 Ready 的值为 "False"。
    • node.kubernetes.io/unreachable:节点控制器访问不到节点. 这相当于节点状态 Ready 的值为 "Unknown"。
    • node.kubernetes.io/memory-pressure:节点存在内存压力。
    • node.kubernetes.io/disk-pressure:节点存在磁盘压力。
    • node.kubernetes.io/pid-pressure: 节点的 PID 压力。
    • node.kubernetes.io/network-unavailable:节点网络不可用。
    • node.kubernetes.io/unschedulable: 节点不可调度。
    • node.cloudprovider.kubernetes.io/uninitialized:如果 kubelet 启动时指定了一个 "外部" 云平台驱动, 它将给当前节点添加一个污点将其标志为不可用。在 cloud-controller-manager 的一个控制器初始化这个节点后,kubelet 将删除这个污点。

    在节点被驱逐时,节点控制器或者 kubelet 会添加带有NoExecute效应的相关污点。 如果异常状态恢复正常,kubelet 或节点控制器能够移除相关的污点。

    六、affinity

    6.1 将pod指派给node

    我们前面知道了,有nodeSelector来对pod进行节点选择,但是这种方法比较粗狂,只能根据node的标签进行节点选择。比如:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        env: test
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
      nodeSelector:   #pod部署在具备disktype=ssd的节点上
        disktype: ssd
    

      

    如果我们需要更复杂的方式进行pod调度到node时,只有nodeSelector还是不够,我们需要更丰富的方法来进行调度。这里就是亲和性和反亲和性。

    6.2 亲和性与反亲和性

    nodeSelector 提供了一种最简单的方法来将 Pod 约束到具有特定标签的节点上。 亲和性和反亲和性扩展了你可以定义的约束类型。使用亲和性与反亲和性的一些好处有:

    • 亲和性、反亲和性语言的表达能力更强。nodeSelector 只能选择拥有所有指定标签的节点。 亲和性、反亲和性为你提供对选择逻辑的更强控制能力。【逻辑能力更强】
    • 你可以标明某规则是“硬需求”或者“软需求”,这样调度器在无法找到匹配节点时仍然调度该 Pod。【选择方式更多】
    • 你可以使用节点上(或其他拓扑域中)运行的其他 Pod 的标签来实施调度约束, 而不是只能使用节点本身的标签。这个能力让你能够定义规则允许哪些 Pod 可以被放置在一起。【灵活组合】

    亲和性功能由两种类型的亲和性组成:

    • 节点亲和性功能类似于 nodeSelector 字段,但它的表达能力更强,并且允许你指定软规则。
    • Pod 间亲和性/反亲和性允许你根据其他 Pod 的标签来约束 Pod。

    6.3 节点亲和性

    节点亲和性概念上类似于 nodeSelector, 它使你可以根据节点上的标签来约束 Pod 可以调度到哪些节点上。 节点亲和性有两种:

    • requiredDuringSchedulingIgnoredDuringExecution: 调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector, 但其语法表达能力更强。
    • preferredDuringSchedulingIgnoredDuringExecution: 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。
    apiVersion: v1
    kind: Pod
    metadata:
      name: with-node-affinity
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values:
                - antarctica-east1
                - antarctica-west1
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: another-node-label-key
                operator: In
                values:
                - another-node-label-value
      containers:
      - name: with-node-affinity
        image: registry.k8s.io/pause:2.0
    

     

     pod会被调度到这样的node上:

    • 节点必须包含一个键名为 topology.kubernetes.io/zone 的标签, 并且该标签的取值必须为 antarctica-east1 或 antarctica-west1
    • 节点最好具有一个键名为 another-node-label-key 且取值为 another-node-label-value 的标签。

    你可以使用 operator 字段来为 Kubernetes 设置在解释规则时要使用的逻辑操作符。 你可以使用 InNotInExistsDoesNotExistGt 和 Lt 之一作为操作符。

    NotIn 和 DoesNotExist 可用来实现节点反亲和性行为。 你也可以使用节点污点 将 Pod 从特定节点上驱逐。

    说明:

    如果你同时指定了 nodeSelector 和 nodeAffinity,两者 必须都要满足, 才能将 Pod 调度到候选节点上。

    如果你指定了多个与 nodeAffinity 类型关联的 nodeSelectorTerms, 只要其中一个 nodeSelectorTerms 满足的话,Pod 就可以被调度到节点上。

    如果你指定了多个与同一 nodeSelectorTerms 关联的 matchExpressions, 则只有当所有 matchExpressions 都满足时 Pod 才可以被调度到节点上。

    weight 权重

     你可以为 preferredDuringSchedulingIgnoredDuringExecution 亲和性类型的每个实例设置 weight 字段,其取值范围是 1 到 100。 当调度器找到能够满足 Pod 的其他调度请求的节点时,调度器会遍历节点满足的所有的偏好性规则, 并将对应表达式的 weight 值加和。

    最终的加和值会添加到该节点的其他优先级函数的评分之上。 在调度器为 Pod 作出调度决定时,总分最高的节点的优先级也最高。

    apiVersion: v1
    kind: Pod
    metadata:
      name: with-affinity-anti-affinity
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: label-1
                operator: In
                values:
                - key-1
          - weight: 50  #优先调度
            preference:
              matchExpressions:
              - key: label-2
                operator: In
                values:
                - key-2
      containers:
      - name: with-node-affinity
        image: registry.k8s.io/pause:2.0
    

      

    案例2:尽量调度到ssd,非gpu的机器上

    通过节点亲和力,调度到期望的节点上:

    • 尽量调度到ssd,且不是gpu的机器上(优先匹配,通过优先级weight配置;如果有多个匹配,则需要都满足;)
    • 尽量调度到物理机上
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: prefer-ssd
      name: prefer-ssd
      namespace: kube-public
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: prefer-ssd
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: prefer-ssd
        spec:
          affinity:
            nodeAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - preference:
                  matchExpressions:
                  - key: ssd
                    operator: In
                    values:
                    - "true"
                  - key: gpu
                    operator: NotIn
                    values:
                    - "true"
                weight: 14
              - preference:
                  matchExpressions:
                  - key: type
                    operator: In
                    values:
                    - physical
                weight: 10
          containers:
          - env:
            - name: TZ
              value: Asia/Shanghai
            - name: LANG
              value: C.UTF-8
            image: nginx
            imagePullPolicy: IfNotPresent
            name: prefer-ssd
    

      

    6.2 pod间亲和和反亲和

    案例1:通过反亲和将同一个项目的pod部署到不同的节点上

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: must-be-diff-nodes #deployment的标签,可以和pod的不同
      name: must-be-diff-nodes
      namespace: kube-public
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: must-be-diff-nodes
      template:
        metadata:
          labels:
            app: must-be-diff-nodes
        spec:
          affinity:
            podAntiAffinity:  #配置pod反亲和
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:  #具有app=must-be-diff-nodes的节点不在本节点上调度,也就是每个节点确保只有1个同项目的pod
                  - key: app
                    operator: In
                    values:
                    - must-be-diff-nodes
                topologyKey: kubernetes.io/hostname
          containers:
          - image: nginx
            imagePullPolicy: IfNotPresent
            name: must-be-diff-nodes
    

      

    案例2 topologyKey使用

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: must-be-diff-zone
      name: must-be-diff-zone
      namespace: kube-public
    spec:
      replicas: 4
      selector:
        matchLabels:
          app: must-be-diff-zone
      template:
        metadata:
          labels:
            app: must-be-diff-zone
        spec:
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - must-be-diff-zone
                topologyKey: region
          containers:
          - image: nginx
            imagePullPolicy: IfNotPresent
            name: must-be-diff-zone
    

      实现效果:通过pod反亲和实现:同一个应用部署在不同地区,每个地区1个pod。

     

  • 相关阅读:
    PDF数据提取------2.相关类介绍
    Google搜索的常用技巧
    a helper class for generating xls or csv file
    正则 提取html标签value
    获取 windows地址栏 网页地址栏 文件名
    MSSQL将逗号分隔的字符串转换成列显示
    C# String.Format字符串中包含"{" "}"时需注意的问题
    格式化JSON中时间
    Oracle 10G创建表空间
    Sqlserver取最近一分组中最新一条记录
  • 原文地址:https://www.cnblogs.com/skyflask/p/16829271.html
Copyright © 2020-2023  润新知