自动调度(Deployment)
Deployment 功能包括自动部署容器应用的多份副本,以及持续监控副本的数量,在集群内始终维持用户指定的副本数量。多个Pod由系统全自动完成调度。运行节点的选择由 Scheduler 经过调度算法得出,用户无法干预调度过程和结果。
定向调度(NodeSelector)
查看标签
kubectl get nodes —show-labels
为 k8s-node-1 节点打 zone=north 标签
kubectl label node k8s-node-1 zone=north
应用资源(pod只调度到有 zone: north 标签的节点)
apiVersion: v1kind: Podmetadata:labels:app: busybox-podname: test-busyboxspec:containers:- command:- sleep- "3600"image: busyboximagePullPolicy: Alwaysname: test-busyboxnodeSelector:zone: north
亲和性&反亲和性
亲和性调度可分成软策略和硬策略两种方式:
- 软策略:若没有满足调度要求的节点,Pod 会忽略调度规则,继续完成调度过程。简单说是,满足条件最好,没有的话也无所谓
- 硬策略:若没有满足条件的节点,会不断重试直到满足条件为止。简单说是,必须满足要求,不然就不干了
对于亲和性与反亲和性都有两种规则可以设置:
preferredDuringSchedulingIgnoredDuringExecution 软策略
requiredDuringSchedulingIgnoredDuringExecution 硬策略
nodeAffinity(node亲和性)
节点亲和性(nodeAffinity)主要是用来控制 Pod 要部署在哪些节点上,以及不能部署在哪些节点上。
示例:(node-affinity-demo.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: node-affinity
labels:
app: node-affinity
spec:
replicas: 3
selector:
matchLabels:
app: node-affinity
template:
metadata:
labels:
app: node-affinity
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
name: nginxweb
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬策略
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values:
- k8s-node3
preferredDuringSchedulingIgnoredDuringExecution: # 软策略
- weight: 1
preference:
matchExpressions:
- key: com
operator: In
values:
- crab
配置解读:
不能运行在 k8s-node3 节点,优先调度到满足标签 com=crab 的节点。
注意:
若 nodeSelectorTerms 下面有多个选项时,满足任何一个条件就可以了;若 matchExpressions 有多个选项,则必须同时满足这些条件才能正常调度 Pod。
操作符说明:
- In:label 的值在某个列表中
- NotIn:label 的值不在某个列表中
- Gt:label 的值大于某个值
- Lt:label 的值小于某个值
- Exists:某个 label 存在
- DoesNotExist:某个 label 不存在
podAffinity(pod 亲和性)
Pod 亲和性主要解决 Pod 可以和哪些 Pod 部署在同一个拓扑域中的问题。比如一个 Pod 在 A 节点上了,那么另一个 Pod 也要在 A 节点。
pod-affinity-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-affinity
labels:
app: pod-affinity
spec:
replicas: 3
selector:
matchLabels:
app: pod-affinity
template:
metadata:
labels:
app: pod-affinity
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: nginxweb
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬策略
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- busybox-pod
topologyKey: kubernetes.io/hostname
配置解读:
要求调度到拥有 app=busybox-pod 标签的 pod 所在的节点上。
# 查看有标签 app=busybox-pod 的 pod 列表
$ kubectl get pods -l app=busybox-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-busybox 1/1 Running 0 27m 10.244.2.242 crab-node2 <none> <none>
# 应用
$ kubectl apply -f pod-affinity-demo.yaml
# 查看
$ kubectl get pods -o wide -l app=pod-affinity
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-affinity-587f9b5b58-5nxmf 1/1 Running 0 26s 10.244.2.249 crab-node2 <none> <none>
pod-affinity-587f9b5b58-m2j7s 1/1 Running 0 26s 10.244.2.248 crab-node2 <none> <none>
pod-affinity-587f9b5b58-vrd7b 1/1 Running 0 26s 10.244.2.250 crab-node2 <none> <none>
podAntiAffinity(pod 反亲和性)
Pod 反亲和性主要解决 Pod 不可以和哪些 Pod 部署在同一个拓扑域中的问题。比如一个 Pod 在 A 节点上了,那么另一个 Pod 一定不在 A 节点上。
pod-antiaffinity-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-antiaffinity
labels:
app: pod-antiaffinity
spec:
replicas: 3
selector:
matchLabels:
app: pod-antiaffinity
template:
metadata:
labels:
app: pod-antiaffinity
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
name: nginxweb
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 硬策略
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- busybox-pod
topologyKey: kubernetes.io/hostname
配置解读:
当拥有标签 app=busybox-pod 的 Pod 运行在 A 节点上时,那么 Pod 不会调度到 A 节点上。
污点&容忍
对于 nodeAffinity 无论是硬策略还是软策略方式,都是调度 Pod 到预期节点。而污点(Taints)与之相反,当 A 节点标记为 Taints ,则此节点不会被调度 Pod ,除非 Pod 被标识为可以容忍污点节点。
kubeadm 搭建的集群默认 master 节点有污点标记,所以用户创建 Pod 时不会调度到 master 节点。
$ kubectl describe node crab-master
Name: crab-master
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=crab-master
kubernetes.io/os=linux
node-role.kubernetes.io/master=
......
Taints: node-role.kubernetes.io/master:NoSchedule
Unschedulable: false
......
污点影响策略:
- NoSchedule:已调度在node上的pod保持不动,新增pod没有此污点容忍度就不能调度到有此污点的node
- NoExecute:已调度在node上的pod都将被驱逐,新增pod没有此污点容忍度就不能调度到有此污点的node
- PreferNoSchedule:NoSchedule 的软策略版本,表示尽量不调度到污点节点上
污点 taint 标记节点:
$ kubectl taint nodes crab-node2 test=node2:NoSchedule
取消节点的污点标记:
$ kubectl taint nodes crab-node2 test-
将 Pod 调度到 master 节点:(taint-demo.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: taint
labels:
app: taint
spec:
replicas: 3
selector:
matchLabels:
app: taint
template:
metadata:
labels:
app: taint
spec:
containers:
- name: nginx
image: nginx
ports:
- name: http
containerPort: 80
tolerations: # 因master节点被标记为了污点,要想 Pod 能够调度到该节点去,要增加容忍的声明
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
Pod 的 tolerations 内容中 key 和 effect 的值要与 Taint 设置保持一致,且满足以下条件之一:
- operator的值是Exists(无须指定value)
- operator的值是Equal且value相等
若不指定 operator,默认值为 Equal 。
两个特殊值:
- 空的 key 再配合 Exists 能匹配所有的 key 与 value,即能容忍所有节点的所有 Taints
- 空的 effect 匹配所有的 effect
