(2)亲和性pod调度
pod和node节点标签之间的定向调度
上面的定向调度还是比较粗糙的方式,因为如果我们设置了定向调度,但标签忘记打了,或者标签写错了,nodeSelector又设置了,那么部署将会变成pending。无疑,我们还是希望每次的部署都是成功的,因此,我们需要一种或者几种更为精细的pod调度。
a)NodeAffinity(节点亲和性)
pod.spec.affinity.nodeAffinity requiredDuringSchedulingIgnoredDuringExecution Node节点必须满足指定的所有规则才可以,相当于硬限制(找不到会调度失败) nodeSelectorTerms 节点选择列表 matchFields 按节点字段列出的节点选择器要求列表 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持Exists(存在), DoesNotExist(不存在), In(范围), NotIn(范围取反), Gt(大于), Lt(小于) preferredDuringSchedulingIgnoredDuringExecution 优先调度到满足指定的规则的Node,相当于软限制 (倾向,找不到不会调度失败) preference 一个节点选择器项,与相应的权重相关联 matchFields 按节点字段列出的节点选择器要求列表 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持In, NotIn, Exists, DoesNotExist, Gt, Lt weight 倾向权重,在范围1-100。
关系符operator的使用说明:
- matchExpressions: - key: nodeenv # 匹配存在标签的key为nodeenv的节点,只匹配key就行 operator: Exists - key: nodeenv # 匹配标签的key为nodeenv,且value是"xxx"或"yyy"的节点,key和value都要匹配 operator: In values: ["xxx","yyy"] - key: nodeenv # 匹配标签的key为nodeenv,且value大于"xxx"的节点 operator: Gt values: "xxx"
例子1:
apiVersion: v1 kind: Pod metadata: name: nginx namespace: default spec: containers: - name: nginx image: nginx:1.18 tolerations: - operator: Exists effect: NoExecute nodeName: k8s-node2 affinity: #亲和性设置 nodeAffinity: #申明是node亲和策略 requiredDuringSchedulingIgnoredDuringExecution: # 硬限制 nodeSelectorTerms: - matchExpressions: # 匹配env的值在["web","dev"]中的标签,实际没有设置此标签,所以会匹配失败 - key: node operator: In values: ["web","dev"]
这个亲和策略表示只要node标签里有web或者dev就可以成功部署此pod,否则,必定不能部署,现在先运行一哈,查看pod的状态,可以看到状态是NodeAffinity ,部署不成功:
[root@master coredns]# k get po -A -owide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES default nginx 0/1 NodeAffinity 0 18s <none> k8s-node2 <none> <none> kube-system coredns-76648cbfc9-87fc7 1/1 Running 1 12h 10.244.0.17 k8s-master <none> <none> kube-system kube-flannel-ds-2jqg2 1/1 Running 0 111m 192.168.217.17 k8s-node1 <none> <none> kube-system kube-flannel-ds-jd6p7 1/1 Running 0 111m 192.168.217.16 k8s-master <none> <none> kube-system kube-flannel-ds-k4qx9 1/1 Running 0 105m 192.168.217.18 k8s-node2 <none> <none>
那么,现在就给node1设置标签值为web吧:
kubectl label nodes k8s-node1 node=dev
再次部署就会成功了。
例子2:
[root@master coredns]# cat nginx.yaml apiVersion: v1 kind: Pod metadata: name: pod-nodeaffinity-preferred namespace: default spec: containers: - name: nginx image: nginx:1.18 affinity: #亲和性设置 nodeAffinity: #设置node亲和性 preferredDuringSchedulingIgnoredDuringExecution: # 软限制 - weight: 1 preference: matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签(当前环境没有) - key: nodeenv operator: In values: ["3432","ewrew"]
这里设置的values是我随便乱写的,自然是随便调度到了某个节点,如果确实有,那自然会调度成功。
(3)PodAffinity(Pod亲和性)
pod亲和性是相对pod来说的,比如,A pod已经在某个节点或者作用域运行了,现在B pod需要和A pod在同一个节点或者作用域运行,反亲和就是A pod不和B pod在同一个node或者作用域。
PodAffinity的可配置项:
pod.spec.affinity.podAffinity requiredDuringSchedulingIgnoredDuringExecution 硬限制 namespaces 指定参照pod的namespace topologyKey 指定调度作用域 labelSelector 标签选择器 matchExpressions 按节点标签列出的节点选择器要求列表(推荐) key 键 values 值 operator 关系符 支持In, NotIn, Exists, DoesNotExist. matchLabels 指多个matchExpressions映射的内容 preferredDuringSchedulingIgnoredDuringExecution 软限制 podAffinityTerm 选项 namespaces topologyKey labelSelector matchExpressions key 键 values 值 operator matchLabels weight 倾向权重,在范围1-100
topologyKey用于指定调度时作用域,例如: 如果指定为kubernetes.io/hostname,那就是以Node节点为区分范围 如果指定为beta.kubernetes.io/os,则以Node节点的操作系统类型来区分 这些都是node节点的标签在管理,例如有的集群有beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64 也可能有arrch架构的操作系统
这里weight权重的作用是,一个pod节点可以有多个软策略,每个软策略可以有不同的权重,然后根据权重由高到选择不同软策略,直到选中符合条件的节点。如果设置了多个软策略,权重价值就体现出来了。比如张三节点权重为4,先看看三节点符不符合选中条件,不符合,再看权重为3的李四节点符不符合选中条件...直到找到符合选中条件的节点。也就是说,权重按值高低来确定,越高越优先
例子1:
有一个A pod,此pod有如下pod标签并设置了nodename:
1. 2. labels: 3. podenv: pro #设置标签
硬策略B pod:
apiVersion: v1 kind: Pod metadata: name: pod-podaffinity-required namespace: default spec: containers: - name: nginx image: nginx:1.18 affinity: #亲和性设置 podAffinity: #设置pod亲和性 requiredDuringSchedulingIgnoredDuringExecution: # 硬限制 - labelSelector: #标签选择器 matchExpressions: # 匹配env的值在["xxx","yyy"]中的标签 - key: podenv operator: In values: ["fdsfdsf","pro"] topologyKey: kubernetes.io/hostname #调度作用域,即如果匹配到,就调度到目标pod同一节点上
上面配置表达的意思是:新Pod必须要与拥有标签podenv=fdsfdsf或者podenv=pro的pod在同一Node上
关于PodAffinity的 preferredDuringSchedulingIgnoredDuringExecution(软策略),这里不再演示,和硬策略基本一样。
(4)PodAntiAffinity(Pod反亲和性)
PodAntiAffinity主要实现以运行的Pod为参照,让新创建的Pod跟参照pod不在一个区域中的功能。
它的配置方式和选项跟PodAffinty是基本一样的,只修改一个地方即可,其余的都一样
affinity: #亲和性设置 podAntiAffinity: #设置pod亲和性
那么,符合条件的Apod将不会和Bpod部署到一起。
资源限制策略:
资源限制策略指的是某些场景如节点 NotReady,或者某一个节点的硬件资源达到预设阈值后,节点内的pod就进入驱逐状态。
硬件资源限制主要是有kube-controller-manager和kubelet这两个核心服务来进行的,也就是它们的配置文件来设定阈值的,一般kube-controller-manager是不做设定,主要是由kubelet设定。
以二进制安装的集群为例,在config文件内配置:
kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 0.0.0.0 port: 10250 readOnlyPort: 10255 cgroupDriver: cgroupfs clusterDNS: - 10.0.0.2 clusterDomain: cluster.local failSwapOn: false authentication: anonymous: enabled: false webhook: cacheTTL: 2m0s enabled: true x509: clientCAFile: /opt/kubernetes/ssl/ca.pem authorization: mode: Webhook webhook: cacheAuthorizedTTL: 5m0s cacheUnauthorizedTTL: 30s evictionHard: imagefs.available: 15% memory.available: 100Mi nodefs.available: 10% nodefs.inodesFree: 5% maxOpenFiles: 1000000 maxPods: 110
关于硬驱逐的阈值, nodefs.available: 10%表示节点服务器剩余磁盘空间小于百分之10就触发,那么,现在在node1节点上有两个pod在运行:
[root@master cfg]# k get po -A -owide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES default pod-nodeaffinity-preferred 1/1 Running 0 133m 10.244.1.16 k8s-node1 <none> <none> kube-system coredns-76648cbfc9-z8kh5 1/1 Running 1 8h 10.244.1.9 k8s-node1 <none> <none> kube-system kube-flannel-ds-99lsb 1/1 Running 1 6h42m 192.168.217.16 k8s-master <none> <none> kube-system kube-flannel-ds-w2kjl 1/1 Running 6 6h42m 192.168.217.17 k8s-node1 <none> <none> kube-system kube-flannel-ds-xdm6r 1/1 Running 0 6h22m 192.168.217.18 k8s-node2 <none> <none>
将nodefs.available: 10%修改为nodefs.available: 90%,然后在重启node1节点上的kubelet会发生什么呢?
答案是该节点的所有pod会转成Terminating状态,因为这个节点有一个coredns服务。
未完待续@@@@@@!!!!!!!!!!!!