nodeSelector简介:
官方文档:
https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/
可用于干预pod的调度结果,例如对磁盘IO要求比较高的pod调度到SSD节点,对内存要求比较高的pod调度到内存较高的节点上。
也可用于将node打上项目标签,然后将指定pod调度到打上项目标签的节点上
为节点打标签
kubectl label node 192.168.2.132 project='microservice'
kubectl label node 192.168.2.133 disktype='ssd'
yaml示例:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
disktype: ssd
nodeName简介:
将pod指定调度到某个节点上,一般值为node的IP或hostname
yaml示例:
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
nodeName: 192.168.2.132
node affinity简介:
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions: #匹配条件1,有一个key但是有多个values、则只要匹配成功一个value就可以调度
- key: topology.kubernetes.io/zone
operator: In
values:
- antarctica-east1 #只有一个value是匹配成功也可以调度
- antarctica-west1
- matchExpressions: #匹配条件2,多个matchExpressions加上以及每个matchExpressions 有一个key及多个values只有其中一个value匹配成功就可以调
- key: topology.kubernetes.io/zone
operator: In
values:
- 11 #即使这俩条件都匹配不上也可以调度,即多个matchExpressions只要有任意一个能匹配任何一个value就可以调用。
- 22
containers:
- name: with-node-affinity
image: k8s.gcr.io/pause:2.0
node硬亲和
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:#匹配条件1,同一个key的多个value只有有一个匹配成功就认为当前key匹配成功
- key:disktype
operator: In
values:
- ssd
- hhd
- key:project #匹配条件2,当前key也要匹配成功一个value,即条件1和条件2必须同时每个key至少匹配成功一个value,否则匹配失败
operator: In
values:
- zhangjw
node软亲和:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:#匹配条件1,同一个key的多个value只有有一个匹配成功就认为当前key匹配成功
- key:disktype
operator: In
values:
- ssd
- hhd
- key:project #匹配条件2,当前key也要匹配成功一个value,即条件1和条件2必须同时每个key至少匹配成功一个value,否则匹配失败
operator: In
values:
- zhangjw
node反亲和
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:#匹配条件1,同一个key的多个value只有有一个匹配成功就认为当前key匹配成功
- key:disktype
operator: In
values:
- ssd
- hhd
- key:project #匹配条件2,当前key也要匹配成功一个value,即条件1和条件2必须同时每个key至少匹配成功一个value,否则匹配失败
operator: NotIn
values:
- zhangjw
说明:
Pod 间亲和性和反亲和性都需要相当的计算量,因此会在大规模集群中显著降低调度速度。 我们不建议在包含数百个节点的集群中使用这类设置。
Pod Affinity与anti-affinity简介:
Pod亲和性与反亲和性可以基于已经在node节点上运行的Pod的标签来约束新创建的Pod可以调度到的目的节点,注意不是基于node上的标签而是使用的已经运行在node上的pod标签匹配。
其中规则表示一个具有可选的关联命名空间列表的LabelSelector,只所以Pod亲和与反亲和需可以通过LabelSelector选择namespace,是因为Pod是命名空间限定的而node不属于任何nemespace所以node的亲和与反亲和不需要namespace,因此作用于Pod标签的标签选择算符必须指定选择算符应用在哪个命名空间。
Pod 亲和性与反亲和性的合法操作符(operator)有 In、NotIn、Exists、DoesNotExist。
在Pod亲和性配置中,requiredDuringSchedulingIgnoredDuringExecution和preferredDuringSchedulingIgnoredDuringExecution中,topologyKey不允许为空(Empty topologyKey is not allowed.)。
在Pod反亲和性中配置中,requiredDuringSchedulingIgnoredDuringExecution和preferredDuringSchedulingIgnoredDuringExecution 中,topologyKey也不可以为空(Empty topologyKey is not allowed.)。
对于requiredDuringSchedulingIgnoredDuringExecution要求的Pod反亲和性,准入控制器LimitPodHardAntiAffinityTopology被引入以确保topologyKey只能是 kubernetes.io/hostname,如果希望 topologyKey 也可用于其他定制拓扑逻辑,可以更改准入控制器或者禁用。
pod亲和性示例
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: tomcat-app
name: tomcat-app
namespace: application
spec:
replicas: 1
selector:
matchLabels:
app: tomcat-app
template:
metadata:
labels:
app: tomcat-app
spec:
containers:
- name: tomcat-app
image: tomcat:7.0.94-alpine
imagePullPolicy: IfNotPresent
#imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
affinity:
podAffinity: #Pod亲和
#requiredDuringSchedulingIgnoredDuringExecution: #硬亲和,必须匹配成功才调度,如果匹配失败则拒绝调度。
preferredDuringSchedulingIgnoredDuringExecution: #软亲和,能匹配成功就调度到一个topology,匹配不成功会由kubernetes自行调度。
- weight: 100
podAffinityTerm:
labelSelector: #标签选择
matchExpressions: #正则匹配
- key: project
operator: In
values:
- python
topologyKey: kubernetes.io/hostname
namespaces:
- application
pod反亲和:
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: tomcat-app1
name: tomcat-app1
namespace: application
spec:
replicas: 3
selector:
matchLabels:
app: tomcat-app1
template:
metadata:
labels:
app: tomcat-app1
spec:
containers:
- name: tomcat-app1
image: tomcat:7.0.94-alpine
imagePullPolicy: IfNotPresent
#imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- tomcat-app1
topologyKey: "kubernetes.io/hostname"
namespaces:
- application
污点简介:
污点(taints),用于node节点排斥 Pod调度,与亲和的作用是完全相反的,即taint的node和pod是排斥调度关系。
容忍(toleration),用于Pod容忍node节点的污点信息,即node有污点信息也会将新的pod调度到node。
官方文档:
https://kubernetes.io/zh/docs/concepts/scheduling-eviction/taint-and-toleration/
污点三中类型:
NoSchedule: 表示k8s将不会将Pod调度到具有该污点的Node上
PreferNoSchedule: 表示k8s将尽量避免将Pod调度到具有该污点的 Node上
NoExecute: 表示k8s将不会将Pod调度到具有该污点的 Node上,同时会将Node上已经存在的Pod强制驱逐出去
kubectl taint nodes 192.168.2.132 key1=value1:NoSchedule #打污点
kubectl taint nodes 192.168.2.132 key1:NoSchedule- #取消污点
容忍介绍:
tolerations容忍:
定义 Pod 的容忍度(可以接受node的哪些污点),容忍后可以将Pod调度至含有该污点的node。
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "key1"
operator: "Exists"
effect: "NoSchedule"
pod驱逐介绍:
节点压力驱逐是由各kubelet进程主动终止Pod,以回收节点上的内存、磁盘空间等资源的过程, kubelet监控当前node节点的CPU、内存、磁盘空间和文件系统的inode等资源,当这些资源中的一个或者多个达到特定的消耗水平, kubelet就会主动地将节点上一个或者多个Pod强制驱逐,以防止当前node节点资源无法正常分配而引发的OOM(OutOfMemory)。
官方文档:https://kubernetes.io/zh/docs/concepts/scheduling-eviction/node-pressure-eviction/
宿主机内存:memory.available #node节点可用内存,默认 <100Mi
nodefs是节点的主要文件系统,用于保存本地磁盘卷、emptyDir、日志存储等数据,默认是/var/lib/kubelet/,或者是通过kubelet通过–root-dir所指定的磁盘挂载目录nodefs.inodesFree #nodefs的可用inode,默认<5%nodefs.available #nodefs的可用空间,默认<10%
imagefs是可选文件系统,用于给容器提供运行时存储容器镜像和容器可写层。imagefs.inodesFree #imagefs的inode可用百分比imagefs.available #imagefs的磁盘空间可用百分比,默认<15%pid.available #可用pid百分比
示例:
evictionHard:
imagefs.inodesFree: 5%
imagefs.available: 15%
memory.available: 300Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
pid.available: 5%
kube-controller-manager实现的eviction: node宕机后的驱逐
kubelet实现的eviction:基于node负载、资源利用率等进行pod驱逐。
驱逐(eviction,节点驱逐),用于当node节点资源不足的时候自动将pod进行强制驱逐,以保证当前node节点的正常运行。Kubernetes基于是QoS(服务质量等级)驱逐Pod , Qos等级包括目前包括以下三个:
Guaranteed: #limits和request的值相等,等级最高、最后被驱逐
Burstable: #limit和request不相等,等级折中、中间被驱逐
BestEffort: #没有限制,即resources为空,等级最低、最先被驱逐
软驱逐
软驱逐不会立即驱逐pod,可以自定义宽限期,在条件持续到宽限期还没有恢复,kubelet再强制杀死pod并触发驱逐:
软驱逐条件:
eviction-soft: 软驱逐触发条件,比如memory.available < 1.5Gi,如果驱逐条件持续时长超过指定的宽限期,可以触发Pod驱逐。
eviction-soft-grace-period:软驱逐宽限期, 如 memory.available=1m30s,定义软驱逐条件在触发Pod驱逐之前必须保持多长时间。
eviction-max-pod-grace-period:终止pod的宽限期,即在满足软驱逐条件而终止Pod时使用的最大允许宽限期(以秒为单位)。
硬驱逐
硬驱逐条件没有宽限期,当达到硬驱逐条件时,kubelet 会强制立即杀死 pod并驱逐:
kubelet 具有以下默认硬驱逐条件(可以自行调整):memory.available<100Mi
nodefs.available<10%
imagefs.available<15%
nodefs.inodesFree<5%(Linux 节点)
kubelet service文件:# vim /etc/systemd/system/kubelet.service
kubelet配置文件:# vim /var/lib/kubelet/config.yaml
evictionHard:
imagefs.available: 15%
memory.available: 300Mi
nodefs.available: 10%
nodefs.inodesFree: 5%