(一) Job

Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。中文文档:https://www.Kubernetes.org.cn/jobKubernetes支持以下几种Job:A:非并行Job:通常创建一个Pod直至其成功结束B:固定结束次数的Job:设置.spec.completions,创建多个Pod,直到.spec.completions个Pod成功结束C:带有工作队列的并行Job:设置.spec.Parallelism但不设置.spec.completions,当所有Pod结束并且至少一个成功时,Job就认为是成功

kubernetes怎么保护数据(Kubernetes高级调度计划任务)(1)

根据.spec.completions和.spec.Parallelism的设置,可以将Job划分为以下几种pattern:

kubernetes怎么保护数据(Kubernetes高级调度计划任务)(2)

1.job****的使用

[root@k8s-master01 job]# vim job.yaml apiVersion: batch/v1 kind: Job metadata: labels: job-name: echo name: echo namespace: default spec: suspend: true # 1.21 ttlSecondsAfterFinished: 100 //Job在执行结束之后(状态为completed或Failed)自动清理。设置为0表示执行结束立即删除,不设置则不会清除,需要开启TTLAfterFinished特性 backoffLimit: 4 //如果任务执行失败,失败多少次后不再执行 completions: 1 //有多少个Pod执行成功,认为任务是成功的,为空默认和parallelism数值一样 parallelism: 1 //并行执行任务的数量,如果parallelism数值大于未完成任务数,只会创建未完成的数量;比如completions是4,并发是3,第一次会创建3个Pod执行任务,第二次只会创建一个Pod执行任务 template: spec: containers: - command: - echo - Hello, Job image: registry.cn-beijing.aliyuncs.com/dotbalo/busybox imagePullPolicy: Always name: echo resources: {} restartPolicy: Never

创建验证:

[root@k8s-master01 job]# kubectl create -f job.yaml job.batch/echo created [root@k8s-master01 job]# kubectl get pod NAME READY STATUS RESTARTS AGE echo-9wlwq 0/1 Completed 0 7s nginx-66cfc7f7d5-jkmvh 1/1 Running 1 6d1h nginx-66cfc7f7d5-zdk4r 1/1 Running 1 6d1h [root@k8s-master01 job]# kubectl get job //执行完毕 NAME COMPLETIONS DURATION AGE echo 1/1 4s 24s [root@k8s-master01 job]# kubectl logs -f echo-9wlwq //查看日志 Hello, Job

(二) CronJob

中文文档:https://www.kubernetes.org.cn/cronjobCronJob即定时任务,就类似于Linux系统的crontab,在指定的时间周期运行指定的任务。在Kubernetes 1.5,使用CronJob需要开启batch/v2alpha1 API,即–runtime-config=batch/v2alpha1。

.spec.schedule指定任务运行周期,格式同Cron.spec.jobTemplate指定需要运行的任务,格式同Job.spec.startingDeadlineSeconds指定任务开始的截止期限.spec.concurrencyPolicy指定任务的并发策略,支持Allow、Forbid和Replace三个选项

kubernetes怎么保护数据(Kubernetes高级调度计划任务)(3)

1.crontab的使用

[root@k8s-master01 job]# vim cronjob.yaml apiVersion: batch/v1beta1 //1.21 batch/v1 kind: CronJob metadata: labels: run: hello name: hello namespace: default spec: concurrencyPolicy: Allow //并发调度策略。可选参数如下:Allow:允许同时运行多个任务。Forbid:不允许并发运行,如果之前的任务尚未完成,新的任务不会被创建。Replace:如果之前的任务尚未完成,新的任务会替换的之前的任务。 failedJobsHistoryLimit: 1 //保留多少失败的任务。 jobTemplate: metadata: spec: template: metadata: labels: run: hello spec: containers: - args: - /bin/sh - -c - date; echo Hello from the Kubernetes cluster image: registry.cn-beijing.aliyuncs.com/dotbalo/busybox imagePullPolicy: Always name: hello resources: {} restartPolicy: OnFailure //重启策略,和Pod一致。 securityContext: {} schedule: '*/1 * * * *' //调度周期,和Linux一致,分别是分时日月周。 successfulJobsHistoryLimit: 3 //保留多少已完成的任务,按需配置。 suspend: false //如果设置为true,则暂停任务,默认为false。

创建验证

[root@k8s-master01 job]# kubectl create -f cronjob.yaml cronjob.batch/hello created [root@k8s-master01 job]# kubectl get cj //查看cronjob,简称cj NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE hello */1 * * * * False 0 43s 56s [root@k8s-master01 job]# kubectl get pod //查看pod NAME READY STATUS RESTARTS AGE echo-9wlwq 0/1 Completed 0 19m hello-1629201900-9q7wt 0/1 Completed 0 2m3s hello-1629201960-jtxj6 0/1 Completed 0 63s hello-1629202020-87n74 0/1 ContainerCreating 0 2s nginx-66cfc7f7d5-jkmvh 1/1 Running 1 6d1h nginx-66cfc7f7d5-zdk4r 1/1 Running 1 6d1h [root@k8s-master01 job]# kubectl logs hello-1629201900-9q7wt //查看执行日志 Tue Aug 17 12:05:03 UTC 2021 Hello from the Kubernetes cluster

(三) InitContainer**1.初始化容器的用途

Init容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码;Init容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低;Init容器可以以root身份运行,执行一些高权限命令;Init容器相关操作执行完成以后即退出,不会给业务容器带来安全隐患。

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

2.初始化容器PostStart区别

PostStart:依赖主应用的环境,而且并不一定先于Command运行。InitContainer:不依赖主应用的环境,可以有更高的权限和更多的工具,一定会在主应用启动之前完成。

3.初始化容器和普通容器的区别

Init容器与普通容器非常像,除了以下几点:它们总是运行到完成;上一个运行完成才会运行下一个;如果Pod的Init容器失败,Kubernetes会不断地重启Pod,直到Init容器成功为止,但是Pod对应的restartPolicy值为Never,Kubernetes不会重新启动Pod;Init容器不支持lifecycle、livenessProbe、readinessProbe和startupProbe。

4.初始化容器配置示例及解析

[root@k8s-master01 init]# vim init.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: test-init name: test-init namespace: kube-public spec: replicas: 3 //副本数3 selector: matchLabels: app: test-init template: metadata: labels: app: test-init spec: volumes: - name: data emptyDir: {} initContainers: //初始化容器,和volumes、containers平级。 - command: - sh - -c - touch /mnt/test-init.txt //执行的操作 image: nginx imagePullPolicy: IfNotPresent name: init-touch //容器名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 //容器名echo containers: - image: nginx imagePullPolicy: IfNotPresent name: test-init volumeMounts: - name: data mountPath: /mnt

创建验证:

[root@k8s-master01 init]# kubectl create -f init.yaml deployment.apps/test-init created [root@k8s-master01 init]# kubectl get pod -n kube-public //查看pod NAME READY STATUS RESTARTS AGE test-init-7c58ff4db4-4gjws 0/1 Init:1/2 0 116s test-init-7c58ff4db4-m8t2l 0/1 Init:1/2 0 116s test-init-7c58ff4db4-n68q4 0/1 Init:1/2 0 116s [root@k8s-master01 init]# kubectl describe pod test-init-7c58ff4db4-4gjws -n kube-public Name: test-init-7c58ff4db4-4gjws Namespace: kube-public Priority: 0 Node: k8s-master03/192.168.1.102 Start Time: Tue, 17 Aug 2021 20:52:57 0800 Labels: app=test-init pod-template-hash=7c58ff4db4 .... Normal Pulled 2m19s kubelet Successfully pulled image "nginx" in 29.496733351s Normal Created 2m18s kubelet Created container init-touch Normal Started 2m18s kubelet Started container init-touch Normal Pulled 2m18s kubelet Container image "nginx" already present on machine Normal Created 2m18s kubelet Created container echo Normal Started 2m18s kubelet Started container echo Normal Pulled 37s kubelet Container image "nginx" already present on machine Normal Created 37s kubelet Created container test-init Normal Started 37s kubelet Started container test-init //显示初始化容器中 [root@k8s-master01 init]# kubectl logs -f test-init-7c58ff4db4-4gjws -c echo -n kube-public //查看其中一个副本echo容器的日志,发现在打印中。

(四) 临时容器EphemeralContainer**

临时容器:1.16版本以上支持官方文档:https://kubernetes.io/zh/docs/concepts/workloads/pods/ephemeral-containers/一种特殊的容器,容器在现有 Pod 中临时运行,以便完成用户发起的操作,例如故障排查。 你会使用临时容器来检查服务器,而不是用它来构建应用程序.

1.了解临时容器

Pod 是 Kubernetes 应用程序的基本构建块。 由于 Pod 是一次性且可替换的,因此一旦 Pod 创建,就无法将容器加入到 Pod 中。 取而代之的是,通常使用 Deployment 以受控的方式来删除并替换 Pod。有时有必要检查发现有 Pod 的状态。例如,对于难以复现的故障进行排查。 在这些场景中,可以在现有 Pod 中心运行临时容器来检查其状态并运行任意命令。

2.什么是临时容器?

临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启, 因此不适用于构建应用程序。 临时容器使用与常规容器相同的 ContainerSpec 节奏来描述,但许多字段是不兼容和不允许的。

A:临时容器没有端口配置,因此像 ports,livenessProbe,readinessProbe 这样的字段是不允许的。B:Pod 资源分配是不可变的,因此 resources 配置是不允许的。C:有关允许字段的完整列表

临时容器是使用 API 中的一种特殊的 ephemeralcontainers 处理器进行创建的, 而不是直接添加到 pod.spec 段,因此无法使用 kubectl edit 来添加一个临时容器。与常规容器一样,将临时容器添加到 Pod 后,将不能更改或删除临时容器

3.临时容器的用途

当由于容器崩溃或容器镜像不包含调试工具而导致 kubectl exec 无用时, 临时容器对于交互式故障排查很有用。尤其是,Distroless 镜像 允许用户部署最小的容器镜像,从而减少攻击面并减少故障和漏洞的暴露。 由于 distroless 镜像不包含 Shell 或任何的调试工具,因此很难单独使用 kubectl exec 命令进行故障排查。使用临时容器时,启用进程名字空间共享很有帮助,可以查看其他容器中的进程。

4.临时容器的使用

开启临时容器二进制方式:主节点

# 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

node节点

# vi /usr/lib/systemd/system/kube-proxy.service --feature-gates=EphemeralContainers=true # vi /etc/kubernetes/kubelet-conf.yml featureGates: EphemeralContainers: true

重启all:

[root@k8s-master01 ~]# systemctl daemon-reload [root@k8s-master01 ~]# systemctl restart kube-apiserver kube-scheduler kube-controller-manager kubelet kube-proxy

使用命令:K8s 1.16 https://kubernetes.io/docs/concepts/workloads/pods/ephemeral-containersK8s 1.18 kubectl alpha debug redis-new-5b577b46c7-2jv4j -ti –image=registry.cn-beijing.aliyuncs.com/dotbalo/debug-toolsK8s 1.20 kubectl debug redis-new-5b577b46c7-2jv4j -ti –image=registry.cn-beijing.aliyuncs.com/dotbalo/debug-toolskubectl debug node/k8s-node01 -it –image=registry.cn-beijing.aliyuncs.com/dotbalo/debug-tools

(****五) Tain和Toleration

官方文档:https://kubernetes.io/zh/docs/concepts/scheduling-eviction/taint-and-toleration/ 设计理念:Taint在一类服务器上打上污点,让不能容忍这个污点的Pod不能部署在打了污点的服务器上。Toleration是让Pod容忍节点上配置的污点,可以让一些需要特殊配置的Pod能够调用到具有污点和特殊配置的节点上。

1.污点配置解析

创建一个污点(一个节点可以有多个污点):

# kubectl taint nodes NODE_NAME TAINT_KEY=TAINT_VALUE:EFFECT 比如: kubectl taint nodes k8s-node01 ssd=true:PreferNoSchedule

查看:

# kubectl describe node k8s-node01 | grep Taint (注意大写T)

NoSchedule:禁止调度到该节点,已经在该节点上的Pod不受影响 NoExecute:禁止调度到该节点,如果不符合这个污点,会立马被驱逐(或在一段时间后) PreferNoSchedule:尽量避免将Pod调度到指定的节点上,如果没有更合适的节点,可以部署到该节点

kubernetes怎么保护数据(Kubernetes高级调度计划任务)(4)

2.容忍配置解析

方式一完全匹配:满足全部条件 tolerations:

– key: “taintKey” operator: “Equal” value: “taintValue” effect: “NoSchedule”

方式二不完全匹配:满足一个key,符合NoSchedule

tolerations: – key: “taintKey” operator: “Exists” effect: “NoSchedule”

方式三大范围匹配(不推荐key为内置Taint):满足一个key即可 – key: “taintKey”

operator: “Exists

方式四匹配所有(不推荐): tolerations:

– operator: “Exists”

停留时间配置:(默认300秒迁移,tolerationSeconds设置迁移时间,下列3600秒驱逐走)

tolerations: – key: “key1” operator: “Equal” value: “value1” effect: “NoExecute” tolerationSeconds: 3600

实例: 1. 有一个节点(假设node01)是纯SSD硬盘的节点,现需要只有一些需要高性能存储的Pod才能调度到该节点上 给节点打上污点和标签:

[root@k8s-master01 ~]# kubectl get po -A -owide | grep node01 #查看node01有哪些pod [root@k8s-master01 ~]# kubectl taint nodes k8s-node01 ssd:PreferNoSchedule- #去除PreferNoSchedule属性污点 [root@k8s-master01 ~]# kubectl taint nodes k8s-node01 ssd=true:NoExecute #此时会驱逐没有容忍该污点的Pod [root@k8s-master01 ~]# kubectl taint nodes k8s-node01 ssd=true:NoSchedule #给node01打上污点 [root@k8s-master01 ~]# kubectl label node k8s-node01 ssd=true #给node01打上ssd标签 [root@k8s-master01 ~]# kubectl get node -l ssd #查看集群有ssd的节点 [root@k8s-master01 ~]# kubectl describe node k8s-node01 | grep Taint #查看node01打上的污点

配置Pod:(表示能部署到node01节点,并不表示一定能部署在node01节点)

[root@k8s-master01 ~]# vim tolerations.yaml apiVersion: v1 kind: Pod metadata: name: nginx labels: env: test spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent nodeSelector: ssd: "true" tolerations: - key: "ssd" operator: "Exists"

由于打了NoExecute,node01上只剩下了calico,然后创建pod,发现pod已经成功部署到node01节点。

[root@k8s-master01 ~]# kubectl get pod -A -owide | grep node01 kube-system calico-node-hrj82 1/1 Running 15 6d13h 192.168.0.103 k8s-node01 kube-system kube-proxy-mrl9j 1/1 Running 7 6d12h 192.168.0.103 k8s-node01 [root@k8s-master01 ~]# kubectl create -f tolerations.yaml #创建pod,查看效果 pod/nginx created [root@k8s-master01 ~]# kubectl get pod -A -owide | grep node01 #发现pod已经成功部署到node01节点 default nginx 1/1 Running 0 50s 172.161.125.33 k8s-node01

删除pod,修改yaml,把容忍注释掉,再次部署发现pod没部署成功,describe寻找问题。

[root@k8s-master01 ~]# vim tolerations.yaml #修改 .... nodeSelector: ssd: "true" #tolerations: #- key: "ssd" # operator: "Exists" [root@k8s-master01 ~]# kubectl delete -f tolerations.yaml #删除 pod "nginx" deleted [root@k8s-master01 ~]# kubectl get -f tolerations.yaml #nginx处于pending状态 NAME READY STATUS RESTARTS AGE nginx 0/1 Pending 0 89s [root@k8s-master01 ~]# kubectl describe po nginx #一个节点有污点,但是没容忍,四个节点没affinity。 ... Warning FailedScheduling 84s default-scheduler 0/5 nodes are available: 1 node(s) had taint {ssd: true}, that the pod didn't tolerate, 4 node(s) didn't match Pod's node affinity.

3.内置污点

node.kubernetes.io/not-ready:#节点未准备好,相当于节点状态Ready的值为False。node.kubernetes.io/unreachable:#Node Controller访问不到节点,相当于节点状态Ready的值为Unknown。node.kubernetes.io/out-of-disk:#节点磁盘耗尽。node.kubernetes.io/memory-pressure:#节点存在内存压力。node.kubernetes.io/disk-pressure:#节点存在磁盘压力。node.kubernetes.io/network-unavailable:#节点网络不可达。node.kubernetes.io/unschedulable:#节点不可调度。node.cloudprovider.kubernetes.io/uninitialized:#如果Kubelet启动时指定了一个外部的cloudprovider,它将给当前节点添加一个Taint将其标记为不可用。在cloud-controller-manager的一个controller初始化这个节点后,Kubelet将删除这个Taint。

节点不健康,6000秒后再驱逐(默认是300秒):

tolerations: - key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 6000

4.taint常用命令

创建一个污点(一个节点可以有多个污点): kubectl taint nodes NODE_NAME TAINT_KEY=TAINT_VALUE:EFFECT比如:

# kubectl taint nodes k8s-node01 ssd=true:PreferNoSchedule

查看一个节点的污点:

# kubectl get node k8s-node01 -o go-template --template {{.spec.taints}} # kubectl describe node k8s-node01 | grep Taints -A 10

删除污点(和label类似):基于Key删除: kubectl taint nodes k8s-node01 ssd-基于Key Effect删除: kubectl taint nodes k8s-node01 ssd:PreferNoSchedule-修改污点(Key和Effect相同):kubectl taint nodes k8s-node01 ssd=true:PreferNoSchedule --overwrite

(六) Affinity亲和性**

kubernetes怎么保护数据(Kubernetes高级调度计划任务)(5)

1.Affinity分类

Affinity亲和力: ·NodeAffinity:节点亲和力/反亲和力 ·PodAffinity:Pod亲和力 ·PodAntiAffinity:Pod反亲和力 Affinity分类:

kubernetes怎么保护数据(Kubernetes高级调度计划任务)(6)

2.Affinity的几种场景

如下图,一个应用分别部署在4个node节点中,当其中一个出现问题时,其他3个可以确保高可用。

kubernetes怎么保护数据(Kubernetes高级调度计划任务)(7)

如下图,一个应用分别部署在两个区域,当其中一个区域出故障(光纤挖断等),另一个区域可以确保高可用。

kubernetes怎么保护数据(Kubernetes高级调度计划任务)(8)

尽量把同一项目不同应用部署在不同的节点上(确保宕机等影响范围降低)

kubernetes怎么保护数据(Kubernetes高级调度计划任务)(9)

3.节点node亲和力的配置

[root@k8s-master01 ~]# vim with-node-affinity.yaml apiVersion: v1 kind: Pod metadata: name: with-node-affinity spec: affinity: #和containers对齐 nodeAffinity: #节点亲和力(部署在一个节点) requiredDuringSchedulingIgnoredDuringExecution: #硬亲和力配置(required,强制),与软亲和力只能存在一项。 nodeSelectorTerms: #节点选择器配置,可以配置多个matchExpressions(满足其一) - matchExpressions: #可以配置多个key、value类型的选择器(都需要满足) - key: kubernetes.io/e2e-az-name operator: In #标签匹配的方式(下文) values: #可以配置多个(满足其一) - e2e-az1 - az-2 preferredDuringSchedulingIgnoredDuringExecution: #软亲和力配置(preferred),与硬亲和力只能存在一项。 - weight: 1 #软亲和力的权重,权重越高优先级越大,范围1-100 preference: #软亲和力配置项,和weight同级,可以配置多个,matchExpressions和硬亲和力一致 matchExpressions: - key: another-node-label-key operator: In #标签匹配的方式(下文) values: - another-node-label-value containers: - name: with-node-affinity image: nginx operator:标签匹配的方式 In:相当于key = value的形式 NotIn:相当于key != value的形式 Exists:节点存在label的key为指定的值即可,不能配置values字段 DoesNotExist:节点不存在label的key为指定的值即可,不能配置values字段 Gt:大于value指定的值 Lt:小于value指定的值

4.pod亲和力的配置

[root@k8s-master01 ~]# vim with-pod-affinity.yaml apiVersion: v1 kind: Pod metadata: name: with-pod-affinity spec: affinity: podAffinity: #pod亲和力 requiredDuringSchedulingIgnoredDuringExecution: #硬亲和力 - labelSelector: #Pod选择器配置,可以配置多个 matchExpressions: #可以配置多个key、value类型的选择器(都需要满足) - key: security operator: In #标签匹配的方式 values: #可以配置多个(满足其一) - S1 topologyKey: failure-domain.beta.kubernetes.io/zone #匹配的拓扑域的key,也就是节点上label的key,key和value相同的为同一个域,可以用于标注不同的机房和地区 podAntiAffinity: #pod反亲和力 preferredDuringSchedulingIgnoredDuringExecution: #软亲和力 - weight: 100 #权重,权重越高优先级越大,范围1-100 podAffinityTerm: labelSelector: matchExpressions: - key: security operator: In values: - S2 namespaces: #和哪个命名空间的Pod进行匹配,为空为当前命名空间 - default topologyKey: failure-domain.beta.kubernetes.io/zone containers: - name: with-pod-affinity image: nginx

5.同一个应用部署在不同的宿主机

如下例,有5个副本,配置的是强制反亲和力,假设K8S总共有3个节点,那么会分别在3个节点启动一个pod,剩下2个会一直处于pending状态,并且pod不能和app=must-be-diff-nodes的标签部署在一起。

apiVersion: apps/v1 kind: Deployment metadata: labels: app: must-be-diff-nodes name: must-be-diff-nodes namespace: kube-public spec: replicas: 5 #副本数 selector: matchLabels: app: must-be-diff-nodes template: metadata: labels: app: must-be-diff-nodes spec: affinity: podAntiAffinity: #反亲和力 requiredDuringSchedulingIgnoredDuringExecution: #强制 - labelSelector: matchExpressions: - key: app operator: In values: - must-be-diff-nodes #标签 topologyKey: kubernetes.io/hostname containers: - image: nginx imagePullPolicy: IfNotPresent name: must-be-diff-nodes

5.1同一个应用不同副本固定节点

apiVersion: apps/v1 kind: Deployment metadata: name: redis-cache spec: selector: matchLabels: app: store replicas: 3 template: metadata: labels: app: store spec: nodeSelector: app: store affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - store topologyKey: "kubernetes.io/hostname" containers: - name: redis-server image: redis:3.2-alpine

5.2应用和缓存尽量部署在同一个域内

apiVersion: apps/v1 kind: Deployment metadata: name: web-server spec: selector: matchLabels: app: web-store replicas: 3 template: metadata: labels: app: web-store spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - web-store topologyKey: "kubernetes.io/hostname" podAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - store topologyKey: "kubernetes.io/hostname" containers: - name: web-app image: nginx:1.16-alpine

6.尽量调度到高配置服务器

如下图pod尽量配置到ssd=true的标签节点(软亲和,100权重),而且没有GPU=true标签的节点,也可以部署在type=physical标签的节点(权重10).

[root@k8s-master01 ~]# vim nodeAffinitySSD.yaml 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: #软亲和力,如果需要强制部署在一个节点可以用requried - preference: matchExpressions: - key: ssd #ssd标签 operator: In #满足 values: - "true" - key: GPU #GPU便标签 operator: NotIn #不满足 values: - "true" weight: 100 #权重 - preference: matchExpressions: - key: type #type=physical标签 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

打标签

[root@k8s-master01 ~]# kubectl get node --show-labels #查看节点标签 分别给master01,node01节点打上ssd=true的标签,master01节点单独打上GPU=true的标签 [root@k8s-master01 ~]# kubectl label node k8s-master01 ssd=true [root@k8s-master01 ~]# kubectl label node k8s-master01 GPU=true [root@k8s-master01 ~]# kubectl label node k8s-node01 GPU=true 给node02打上type=physical的标签 [root@k8s-master01 ~]# kubectl label node k8s-node02 type=physical

创建应用

[root@k8s-master01 ~]# kubectl create -f nodeAffinitySSD.yaml [root@k8s-master01 ~]# kubectl get pod -n kube-public -owide #发现部署在node01上 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES prefer-ssd-dcb88b7d9-wdd54 1/1 Running 0 18s 172.161.125.41 k8s-node01

假设去掉node1的ssd标签,再重新创建,就会创建到node02打了type标签的节点上。

[root@k8s-master01 ~]# kubectl label node k8s-node01 ssd- #去掉node01的ssd标签 node/k8s-node01 labeled [root@k8s-master01 ~]# kubectl delete -f nodeAffinitySSD.yaml #删除 deployment.apps "prefer-ssd" deleted [root@k8s-master01 ~]# kubectl create -f nodeAffinitySSD.yaml #再创建 deployment.apps/prefer-ssd created [root@k8s-master01 ~]# kubectl get pod -n kube-public -owide #查看 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES prefer-ssd-dcb88b7d9-58rfw 1/1 Running 0 87s 172.171.14.212 k8s-node02

7.拓扑域TopologyKey

topologyKey:拓扑域,主要针对宿主机,相当于对宿主机进行区域的划分。用label进行判断,不同的key和不同的value是属于不同的拓扑域 如下图,相同区域可以打相同的一个标签,不同区域打不一样的标签,避免同一个区出现故障,所有pod都部署在同一个区域里面导致服务无法使用。

kubernetes怎么保护数据(Kubernetes高级调度计划任务)(10)

7.1同一个应用多区域部署

根据上图逻辑上设置3个域标签,把应用pod部署在不同的的区域内

master01,02: region=daxing master03,node01: region=chaoyang node02: region=xxx [root@k8s-master01 ~]# kubectl label node k8s-master01 k8s-master02 region=daxing [root@k8s-master01 ~]# kubectl label node k8s-node01 k8s-master03 region=chaoyang [root@k8s-master01 ~]# kubectl label node k8s-node02 region=xxx

创建yaml,设置topologyKey为region,每个pod会部署在不同region上,由于设置是pod强制反亲和力,如果pod副本数超过区域上限数量,剩下的pod就会处于pending状态启动不了。

[root@k8s-master01 ~]# vim must-be-diff-zone.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: must-be-diff-zone name: must-be-diff-zone namespace: kube-public spec: replicas: 3 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

创建并查看,发现启动的3个pod都在不同的节点上。

[root@k8s-master01 ~]# kubectl create -f must-be-diff-zone.yaml [root@k8s-master01 ~]# kubectl get pod -n kube-public -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES must-be-diff-zone-755966bd8b-42fft 1/1 Running 0 2m22s 172.171.14.213 k8s-node02 must-be-diff-zone-755966bd8b-fx6cs 1/1 Running 0 2m22s 172.169.92.68 k8s-master02 must-be-diff-zone-755966bd8b-k5d7q 1/1 Running 0 2m22s 172.161.125.42

文章来源:https://www.jianshu.com/p/e12721f831b9

,