官网:Kubernetes之应用部署调度策略
Kubernetes之应用部署调度策略测试用例
kubernetes中默认的部署方式时根据调度算法分析kubernetes中资源使用情况,进行动态分配。有时候调度应用时需要将应用部署到某个特定的节点上,或者需要将应用部署多个实例,为了保持高可用需要将应用分配到不同的节点上等等。
集群环境信息如下:
参数 Pod.spec.nodeName 可用于强制约束 Pod 跳过默认的 Kubernetes 调度规则,直接调度 Pod 到指定的 Node 节点上。
nodeName指定pod节点运行在哪个具体node上,通过explain命令查看nodeName字段含义
如下所示:
vim nodeName.yaml
apiVersion: apps/v1 #apiVersion是当前配置格式的版本
kind: Deployment #kind是要创建的资源类型,这里是Deploymnet
metadata: #metadata是该资源的元数据,name是必须的元数据项
name: nginx-deployment
labels:
app: nginx
spec: #spec部分是该Deployment的规则说明
replicas: 1 #relicas指定副本数量,默认为1
selector:
matchLabels:
app: nginx
template: #template定义Pod的模板,这是配置的重要部分
metadata: #metadata定义Pod的元数据,至少要顶一个label,label的key和value可以任意指定
labels:
app: nginx
spec: #spec描述的是Pod的规则,此部分定义pod中每一个容器的属性,name和image是必需的
containers:
- name: nginx
image: nginx:1.16.0
imagePullPolicy: IfNotPresent #镜像拉取策略
ports:
- containerPort: 80
nodeName: k8s-node-21 #指定pod调度节点
如下图所示:
如上所示,pod均被调度在k8s-node-21节点上。
nodeSelector指定pod调度到具有哪些标签的node节点上,通过explain命令查看nodeSelector字段含义
参数 spec.selector.matchLabels 可以设置应用启动到带有指定 Label 的节点上。如果该参数指定有多个标签,那么需要存在带有多个 Label 标签的节点 Pod 才能够被调度,否则被标记为无法调度状态。
官方nodeSelector
1、对节点设置 Label 标签
[root@k8s-client-17 yaml]# kubectl label nodes k8s-worker-16 deploy=nginx
node/k8s-worker-16 labeled
2、查看节点的 Label 标签
[root@k8s-client-17 yaml]# kubectl get nodes --show-labels
如下所示:
3、设置 Deployment 对象配置 nodeSelector 参数
vim nodeSelector.yaml
apiVersion: apps/v1 #apiVersion是当前配置格式的版本
kind: Deployment #kind是要创建的资源类型,这里是Deploymnet
metadata: #metadata是该资源的元数据,name是必须的元数据项
name: nginx-deployment
labels:
app: nginx
spec: #spec部分是该Deployment的规则说明
replicas: 6 #relicas指定副本数量,默认为1
selector:
matchLabels:
app: nginx
template: #template定义Pod的模板,这是配置的重要部分
metadata: #metadata定义Pod的元数据,至少要顶一个label,label的key和value可以任意指定
labels:
app: nginx
spec: #spec描述的是Pod的规则,此部分定义pod中每一个容器的属性,name和image是必需的
containers:
- name: nginx
image: nginx:1.16.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
nodeSelector:
deploy: nginx #调度到拥有label为deploy=nginx的节点
如下图所示,pod均被调度到labels为deploy=nginx节点上
由于上面 NodeName 和 NodeSelector 两种调度方式过于生硬,不能够灵活的配置应用能在什么节点启动、不能在什么节点启动以及配置多实例在不同节点启动。所以kubernetes推出了Affinity亲和性,这种方式可以很灵活的配置应用的调度规则。
Affinity 可以分为三种类,如下图所示:
preferredDuringSchedulingIgnoredDuringExecution(软策略): 如果没有满足调度要求的节点,Pod 就会忽略这条规则,继续完成调度过程,即是满足条件最好,没有满足也无所谓的一种策略。
requiredDuringSchedulingIgnoredDuringExecution(硬策略): 比较强硬,如果没有满足条件的节点的话,就不断重试直到满足条件为止,即是必须满足该要求,不然不调度的策略。
相关参数介绍
#1、调度条件参数
nodeSelectorTerms:下面有多个选项的话,满足任何一个条件就可以
matchExpressions:有多个选项的话,则必须同时满足这些条件才能正常调度pod
#2、权重weight参数
权重范围为 1-100,权重的值涉及调度器的优选打分过程,每个节点的评分都会加上这个weight,最后绑定最高的节点
#3、位置拓扑键topologyKey参数及可配置选项
topologykey的值表示指作用于topology范围内的node上运行的pod,其值可配置为:
kubernetes.io/hostname(Node)
failure-domain.beta.kubernetes.io/zone(Zone)
failure-domain.beta.kubernetes.io/region(Region)
#4、匹配选项 operator 可用的选项:
In: label 的值在某个列表中
NotIn: label 的值不在某个列表中
Gt: label 的值大于某个值
Lt: label 的值小于某个值
Exists: 存在某个 label 标签
DoesNotExist: 不存在某个 label 标签
查看NodeAffinity字段含义,如下所示
说明:NodeAffinity 是用于调度应用时候,会根据 NodeAffinity 参数去跟 Node 上的 Label 进行匹配,如果有符合条件的 Node 则该应用就可与调度到该节点,其功能跟 NodeSelector 类似,不过设置的条件比其更灵活。
#1、对节点设置 Label 标签
kubectl label nodes k8s-worker-16 deploy=nginx
#2、nodeAffinity.yaml文件
vim nodeAffinity.yaml
apiVersion: apps/v1 #apiVersion是当前配置格式的版本
kind: Deployment #kind是要创建的资源类型,这里是Deploymnet
metadata: #metadata是该资源的元数据,name是必须的元数据项
name: nginx-deployment
labels:
app: nginx
spec: #spec部分是该Deployment的规则说明
replicas: 3 #relicas指定副本数量,默认为1
selector:
matchLabels:
app: nginx
template: #template定义Pod的模板,这是配置的重要部分
metadata: #metadata定义Pod的元数据,至少要顶一个label,label的key和value可以任意指定
labels:
app: nginx
spec: #spec描述的是Pod的规则,此部分定义pod中每一个容器的属性,name和image是必需的
containers:
- name: nginx
image: nginx:1.16.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
affinity:
nodeAffinity: #Pod亲和性
requiredDuringSchedulingIgnoredDuringExecution: #硬策略
nodeSelectorTerms: #节点选择器
- matchExpressions:
- key: deploy #label标签名称,对等于app: nginx中左边的app
operator: In #等值关系,做等值选则还是不等值选则
values:
- nginx #label标签名称对应的值,对等于app: nginx中右边的nginx
如下图所示:
NodeAffinity 规则设置的注意事项如下:
1、如果 nodeAffinity 指定了多个 nodeSelectorTerms,那么其中任意一个能够匹配成功即可。
2、如果同时定义了 nodeSelector 和 nodeAffinity,那么必须两个条件都得到满足,Pod 才能最终运行在指定的 Node 上。
3、如果在 nodeSelectorTerms 中有多个 matchExpressions,则一个节点必须满足所有 matchExpressions 才能运行该 Pod。
查看 PodAffinity字段含义,如下所示
Pod 亲和性 主要解决 Pod 可以和哪些 Pod 部署在同一个拓扑域中的问题。一般用于一个应用存在多个实例,或者设置应用与另一个应用间建立关联的时候才会用到,比如,A 应用要启动两个实例,但是要求这两个实例启动在同一个节点上。再比如,有 A 和 B 两个应用,要求这两个引用起动在同一节点上。
vim podAffinity.yaml
apiVersion: apps/v1 #apiVersion是当前配置格式的版本
kind: Deployment #kind是要创建的资源类型,这里是Deploymnet
metadata: #metadata是该资源的元数据,name是必须的元数据项
name: nginx-deployment
labels:
app: nginx
spec: #spec部分是该Deployment的规则说明
replicas: 6 #relicas指定副本数量,默认为1
selector:
matchLabels:
app: nginx
template: #template定义Pod的模板,这是配置的重要部分
metadata: #metadata定义Pod的元数据,至少要顶一个label,label的key和value可以任意指定
labels:
app: nginx
spec: #spec描述的是Pod的规则,此部分定义pod中每一个容器的属性,name和image是必需的
containers:
- name: nginx
image: nginx:1.16.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
affinity:
podAffinity: #Pod亲和性,表示第一个pod调度到哪,第二个pod也调度到哪,这就是pod节点亲和性
requiredDuringSchedulingIgnoredDuringExecution: #硬策略
- topologyKey: kubernetes.io/hostname #位置拓扑键
labelSelector: #标签选择器
matchExpressions: #匹配规则表达式
- key: app ##label标签名称,对等于app: nginx中左边的app
operator: In #等值关系,做等值选则还是不等值选则
values:
- nginx #label标签名称对应的值,对等于app: nginx中右边的nginx
上面说明第一个pod调度到哪,第二个pod也调度到哪,这就是pod节点亲和性,如下图所示:
查看 PodAntiAffinity字段含义,如下所示
Pod 反亲和性主要是解决 Pod 不能和哪些 Pod 部署在同一个拓扑域中的问题,是用于处理的 Pod 之间的关系。比如一个 Pod 被调度到某一个节点上,新起的 Pod 不想和这个 Pod 调度到一起,就可以使用 Pod 的反亲和性 podAntiAffinity。
vim podAntiAffinity.yaml
apiVersion: apps/v1 #apiVersion是当前配置格式的版本
kind: Deployment #kind是要创建的资源类型,这里是Deploymnet
metadata: #metadata是该资源的元数据,name是必须的元数据项
name: nginx-deployment
labels:
app: nginx
spec: #spec部分是该Deployment的规则说明
replicas: 2 #relicas指定副本数量,默认为1
selector:
matchLabels:
app: nginx
template: #template定义Pod的模板,这是配置的重要部分
metadata: #metadata定义Pod的元数据,至少要顶一个label,label的key和value可以任意指定
labels:
app: nginx
spec: #spec描述的是Pod的规则,此部分定义pod中每一个容器的属性,name和image是必需的
containers:
- name: nginx
image: nginx:1.16.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
affinity:
podAntiAffinity: #Pod反亲和性,定义两个pod,第一个pod做为基准,第二个pod跟它调度节点相反
requiredDuringSchedulingIgnoredDuringExecution: #硬策略
- topologyKey: kubernetes.io/hostname #位置拓扑键
labelSelector: #标签选择器
matchExpressions: #匹配规则表达式
- key: app #label标签名称,对等于app: nginx中左边的app
operator: In #等值关系,做等值选则还是不等值选则
values:
- nginx #label标签名称对应的值,对等于app: nginx中右边的nginx
定义两个pod,第一个pod做为基准,第二个pod跟它调度节点相反,如下图所示:
更多详细内容请参考:企业级K8s集群运维实战