nodeSelector是目前最为简单的一种pod运行时调度限制,目前在Kubernetes1.7.x及以下版本可用。Pod.spec.nodeSelector通过kubernetes的label-selector机制选择节点,由调度器调度策略匹配label,而后调度pod到目标节点,该匹配规则属于强制约束。
kubectl label node node1 disktype=ssd --给节点打标签
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector: --选择对应节点标签
disktype: ssd
给node节点设置label,然后在pod 启动yaml文档中通过nodeSelector选择标签选择对应label即可。
前面提及的nodeSelector,其仅以一种非常简单的方式、即label强制限制pod调度到指定节点。而亲和性(Affinity)与非亲和性(anti-affinity)则更加灵活的指定pod调度到预期节点上,相比nodeSelector,Affinity与anti-affinity优势体现在:
(1)、表述语法更加多样化,不再仅受限于强制约束与匹配。
(2)、调度规则不再是强制约束(hard),取而代之的是软限(soft)或偏好(preference)。
(3)、指定pod可以和哪些pod部署在同一个/不同拓扑结构下。
亲和性主要分为3种类型:node affinity与inter-pod affinity/anti-affinity。
2.1、节点亲和性(Node affinity)
Node affinity在Kubernetes 1.2做为alpha引入,其涵盖了nodeSelector功能,主要分为requiredDuringSchedulingIgnoredDuringExecution 与 preferredDuringSchedulingIgnoredDuringExecution 2种类型。前者可认为一种强制限制,如果 Node 的标签发生了变化导致其没有符合 Pod 的调度要求节点,那么pod调度就会失败。而后者可认为理解为软限或偏好,同样如果 Node 的标签发生了变化导致其不再符合 pod 的调度要求,pod 依然会调度运行。
$ kubectl label nodes node1 cpu=high
node "node1" labeled
$ kubectl label nodes node1 cpu=mid
node "node1" labeled
$ kubectl label nodes node1 cpu=low
node "node1" labeled
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: role
operator: NotIn
values:
- master
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: cpu
operator: In
values:
- high
containers:- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
2.2、pod亲和性(Inter-pod affinity)与反亲和性(anti-affinity)
inter-pod affinity与anti-affinity由Kubernetes 1.4引入,当前处于beta阶段,其中podAffinity用于调度pod可以和哪些pod部署在同一拓扑结构之下。而podAntiAffinity相反,其用于规定pod不可以和哪些pod部署在同一拓扑结构下。通过pod affinity与anti-affinity来解决pod和pod之间的关系。
与Node affinity类似,pod affinity与anti-affinity同样分为requiredDuringSchedulingIgnoredDuringExecution and preferredDuringSchedulingIgnoredDuringExecution等2种类型,前者被认为是强制约束,而后者后者可认为理解软限(soft)或偏好(preference)。
spec:
replicas: 1template:
metadata:
labels:
app: is
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: NotIn
values:
- solr --不亲和pod solr,不处于同一台机器
topologyKey: kubernetes.io/hostname
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- oltp --亲和pod oltp,会处于同一台机器
topologyKey: beta.kubernetes.io/os
对于Node affinity,无论是强制约束(hard)或偏好(preference)方式,都是调度pod到预期节点上,而Taints恰好与之相反,如果一个节点标记为 Taints ,除非 Pod也被标识为可以耐受污点节点,否则该Taints节点不会被调度pod。Taints与tolerations当前处于beta阶段。
Taints节点应用场景比如用户希望把Kubernetes Master节点保留给 Kubernetes 系统组件使用,或者把一组具有特殊资源预留给某些 pod。pod不会再被调度到taint标记过的节点。
应用场景:
(1)、针对拥有特定资源的节点,允许对资源有特殊要求的pod在上面运行
(2)、针对不同环境进行区分,比如,将node1、node2分配给部分1或者项目1。将node3、node4分配给其他部门或者其他项目
#给node1节点设置污点
kubectl taint node node1 node-type=production:NoSchedule
node/node1 tainted
#去除污点
kubectl taint nodes node_name key:[effect]- #(这里的key不用指定value)
kubectl taint node node1 node-type:NoSchedule-
#describe node1节点可以发现如下配置
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
#创建污点之后,对于已经处于运行中的pod是没有任何影响的,但是对与新创建的pod如果没有设置容忍则无法在对应节点上创建pod
#修改部署yaml,添加容忍相关配置(在containers同级部分添加如下标红配置),只有配置容忍的pod才能被成功调度到设置污点的节点
spec:
tolerations:
- key: node-type
operator: Equal
value: production
effect: NoSchedule
containers:
- name: nginx
image: nginx:latest
imagePullPolicy: Never
ports:
- containerPort: 80
#有污点无容忍不可以创建pod,有容忍无污点可以创建pod,两种情况对已经创建的pod都无影响。
effect 共有三个可选项,可按实际需求进行设置:
(1)、NoSchedule:pod不会被调度到标记为taints节点。
(2)、PreferNoSchedule:NoSchedule的“preference”或“soft”版本。
(3)、NoExecute:该选项意味着一旦Taint 生效,如该节点内正在运行的 Pod 没有对应 Tolerate 设置,会直接被逐出。
另见:https://toutiao.io/posts/3bdbaf/preview