一、为何要控制Pod应该如何调度
1、集群中有些机器的配置高(SSD,更好的内存等),我们希望核心的服务(比如说数据库)运行在上面。
2、某两个服务的网络传输很频繁,我们希望它们最好在同一台机器上。
3、限制某些节点,只允许跑固定的业务。
二、Kubernetes Scheduler 的作用
将待调度的 Pod 按照一定的调度算法和策略绑定到集群中一个合适的 Worker Node 上,并将绑定信息写入到 etcd 中,之后目标 Node 中 kubelet 服务通过 API Server 监听到 Scheduler 产生的 Pod 绑定事件获取 Pod 信息,然后下载镜像启动容器。
三、Label作用
label是kubernetes中一个非常重要的概念,用户可以非常灵活的利用 label 来管理集群中的资源,POD 的调度可以根据节点的
label 进行特定的部署。
四、Label常用操作
1、查看node与pod标签信息(--show-labels)
2、为pod与node打标签
3、删除label
4、修改label标签
五、将pod固定运行在相关的node节点
apiVersion: v1
kind: Pod
metadata:
name: kubia-manual
namespace: test
labels:
app: web_html
env: prod
spec:
nodeSelector: #节点标签选择器
disktype: ssd #disktype为ssd的节点
containers:
- name: kubia
image: luksa/kubia
ports:
- containerPort: 8080
protocol: TCP
六、nodeAffinity属性
1、nodeAffinity作用
节点亲和性 , 比上面的nodeSelector更加灵活,它可以进行一些简单的逻辑组合,不只是简单的相等匹配 。分为两种,硬策略和软策略。
requiredDuringSchedulingIgnoredDuringExecution : 硬策略,如果没有满足条件的节点的话,就不断重试直到满足条件为止,简单说就是你必须满足我的要求,不然我就不会调度Pod。
preferredDuringSchedulingIgnoredDuringExecution:软策略,如果你没有满足调度要求的节点的话,Pod就会忽略这条规则,继续完成调度过程,说白了就是满足条件最好了,没有满足就忽略掉的策略。
2、nodeAffinity应用
#要求 Pod 不能运行在10.3.153.201节点上,如果有节点满足disktype=ssd或者sas的话就优先调度到这类节点上
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: kang
spec:
containers:
- name: nginx
image: nginx:latest
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: #硬性要求,不允许在10.3.153.201节点主机上要求
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values:
- 10.3.153.201
preferredDuringSchedulingIgnoredDuringExecution: #软性要求,最好放在节点包含disktype=ssd节点上
- weight: 1
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
这里的匹配逻辑是 label 的值在某个列表中,现在Kubernetes提供的操作符有下面的几种:
In:label 的值在某个列表中
NotIn:label 的值不在某个列表中
Gt:label 的值大于某个值
Lt:label 的值小于某个值
Exists:某个 label 存在
DoesNotExist:某个 label 不存在
七、污点(Taints)与容忍(tolerations)
1、使用场景
对于nodeAffinity无论是硬策略还是软策略方式,都是调度 Pod 到预期节点上,而Taints恰好与之相反,如果一个节点标记为 Taints ,除非 Pod 也被标识为可以容忍污点节点,否则该 Taints 节点不会被调度Pod。
Taints(污点)是Node的一个属性,设置了Taints(污点)后,因为有了污点,所以Kubernetes是不会将Pod调度到这个Node上的。于是Kubernetes就给Pod设置了个属性Tolerations(容忍),只要Pod能够容忍Node上的污点,那么Kubernetes就会忽略Node上的污点,就能够(不是必须)把Pod调度过去。
2、设置污点
$ kubectl taint node [node_name] key=value:[effect]
其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]
NoSchedule:一定不能被调度。
PreferNoSchedule:尽量不要调度。
NoExecute:不仅不会调度,还会驱逐Node上已有的Pod。
示例:kubectl taint node k8s-slave1 gpu=true:NoSchedule
3、设置pod的容忍(tolerations)
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: kang
spec:
containers:
- name: nginx
image: nginx:latest
tolerations: #设置容忍性
- key: "gpu"
operator: "Equal" #如果操作符为Exists,那么value属性可省略,不指定operator,默认为Equal
value: "true"
effect: "NoSchedule"
- key: "drunk"
operator: "Exists"
#意思是这个Pod要容忍的有污点的Node的key是smoke Equal true,效果是NoSchedule,
#tolerations属性下各值必须使用引号,容忍的值都是设置Node的taints时给的值。
4、删除污点
八、Label 与Taints的使用理解
当前环境有两个从节点,一个A节点设置了污点,另外一个B节点没有设置污点,如果我们在一个POD上面设置了对节点的容忍后,该POD不代表就一定必须放在A节点上,如需该pod,指定放在A节点,必须同时设置容忍与lable匹配选择,所以在设置污点容忍时,要结合实际情况使用,如果要固定某个POD运行在某个节点,建议采用lable的方式,如果要为某个节点排除其它pod调度过来,可以使用污点。