【Kubernetes】污点、容忍度、亲和性、调度和重启策略

标签、污点、容忍度、亲和性

  • 一、标签
    • 1、定义
    • 2、给资源打标签
      • 【1】给Pod打标签
      • 【2】给Service打标签
      • 【3】给Node打标签
    • 3、查看资源标签
  • 二、节点选择器
    • 1、nodeName
    • 2、nodeSelector
  • 三、污点、容忍度、亲和性
    • 1、node节点亲和性
      • 【1】硬亲和性
      • 【2】软亲和性
    • 2、pod节点亲和性
      • 【1】pod节点亲和性
      • 【2】pod节点反亲和性
      • 【3】换一个topologykey
    • 3、污点和容忍度
      • 【1】 NoSchedule使用
      • 【2】容忍度使用
      • 【3】NoExecute使用
  • 四、Pod状态和重启策略
    • 1、pod状态
    • 2、重启策略
      • 【1】测试Always重启策略
      • 【2】测试Never重启策略
      • 【3】测试OnFailure重启策略

一、标签

1、定义

标签其实就一对 key/value ,被关联到对象上,比如Pod,标签的使用我们倾向于能够表示对象的特殊特点,就是一眼就看出了这个Pod是干什么的
标签可以用来划分特定的对象(比如版本,服务类型等),标签可以在创建一个对象的时候直接定义,也可以在后期随时修改,每一个对象可以拥有多个标签,但是,key值必须是唯一的。
创建标签之后也可以方便我们对资源进行分组管理。如果对pod打标签,之后就可以使用标签来查看、删除指定的pod。
在k8s中,大部分资源都可以打标签。

2、给资源打标签

【1】给Pod打标签

apiVersion: v1
kind: Pod
metadata:name: mypodlabels:      # 打标签 ——》app: backend 和 tier: production。app: backendtier: production
spec:containers:- name: mycontainerimage: nginx

【2】给Service打标签

apiVersion: v1
kind: Service
metadata:name: myservicelabels:   # 打标签 ——》  app: frontend和tier: productionapp: frontendtier: production
spec:selector:app: frontendports:- protocol: TCPport: 80targetPort: 8080

【3】给Node打标签

kubectl label nodes <node-name> <label-key>=<label-value>
# 例如:kubectl label nodes node-1 disk=ssd

3、查看资源标签

# 查看默认名称空间下所有pod资源的标签
kubectl get pods --show-labels 
# 查看默认名称空间下指定pod具有的所有标签
kubectl get pods tomcat-test --show-labels
# 列出默认名称空间下标签key是release的pod,不显示标签	
kubectl get pods -l release=v1
# 列出默认名称空间下标签key是release的所有pod,并打印对应的标签值
kubectl get pods -L release
# 查看所有名称空间下的所有pod的标签
kubectl get pods --all-namespaces --show-labels

二、节点选择器

我们在创建pod资源的时候,pod会根据schduler进行调度,那么默认会调度到随机的一个工作节点,如果我们想要pod调度到指定节点或者调度到一些具有相同特点的node节点,怎么办呢?
可以使用pod中的nodeName或者nodeSelector字段指定要调度到的node节点

1、nodeName

指定pod节点运行在哪个具体node上

#把tomcat.tar.gz上传到xianchaonode1和xianchaonode2,手动解压:
[root@xianchaonode1 ~]# ctr -n=k8s.io images import  tomcat.tar.gz 
Loaded image: tomcat:8.5-jre8-alpine
[root@xianchaonode2 ~]# ctr -n=k8s.io images import  tomcat.tar.gz 
Loaded image: tomcat:8.5-jre8-alpine
# 把busybox.tar.gz上传到xianchaonode1和xianchaonode2,手动解压:
[root@xianchaonode1 ~]# ctr -n=k8s.io images import  busybox.tar.gz
[root@xianchaonode2 ~]# ctr -n=k8s.io images import  busybox.tar.gz [root@xianchaomaster1 ~]# cat pod-node.yaml 
apiVersion: v1
kind: Pod
metadata:name: demo-podnamespace: defaultlabels:app: myappenv: dev
spec:nodeName: xianchaonode1  # 指定pod节点运行在xianchaonode1节点上containers:- name:  tomcat-pod-javaports:- containerPort: 8080image: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresent- name: busyboximage: busybox:latestcommand:- "/bin/sh"- "-c"
- "sleep 3600"[root@xianchaomaster1 ~]# kubectl apply -f pod-node.yaml
#查看pod调度到哪个节点
[root@xianchaomaster1 ~]# kubectl get pods  -o wide
NAME             READY   STATUS    RESTARTS             
demo-pod        1/1     Running   0            xianchaonode1  

2、nodeSelector

指定pod调度到具有哪些标签的node节点上

# 给node节点打标签,打个具有disk=ceph的标签
[root@xianchaomaster1 ~]# kubectl label nodes xianchaonode2 disk=ceph
node/xianchaonode2 labeled
# 定义pod的时候指定要调度到具有disk=ceph标签的node上
[root@xianchaomaster1 ~]# cat pod-1.yaml 
apiVersion: v1
kind: Pod
metadata:name: demo-pod-1namespace: defaultlabels:app: myappenv: dev
spec:nodeSelector:  # 调度到具有disk=ceph标签的node上disk: cephcontainers:- name:  tomcat-pod-javaports:- containerPort: 8080image: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresent[root@xianchaomaster1 ~]# kubectl apply -f pod-1.yaml
#查看pod调度到哪个节点
[root@xianchaomaster1 ~]# kubectl get pods  -o wide
NAME             READY   STATUS    RESTARTS             
demo-pod-1        1/1     Running   0            xianchaonode2

做完上面实验,需要把default名称空间下的pod全都删除,kubectl delete pods pod名字

# 删除node节点打的标签:
[root@xianchaomaster1 ~]# kubectl label nodes xianchaonode2 disk-#假如yaml文件改成如下:
apiVersion: v1
kind: Pod
metadata:name: demo-pod-1namespace: defaultlabels:app: myappenv: dev
spec:nodeName: xianchaonode2  # 指定节点nodeSelector: 		   # 指定标签disk: cephcontainers:- name:  tomcat-pod-javaports:- containerPort: 8080image: tomcat:8.5-jre8-alpineimagePullPolicy: IfNotPresent

那么创建pod,会报错,报什么错呢?
Warning NodeAffinity 17s kubelet Predicate NodeAffinity failed

同一个yaml文件里定义pod资源,如果同时定义了nodeName和NodeSelector,那么条件必须都满足才可以,有一个不满足都会调度失败

# 假如给xianchaonode2继续打上标签
[root@xianchaomaster1 ~]# kubectl label nodes xianchaonode2 disk=ceph[root@xianchaomaster1 pod-2]# kubectl get pods -owide
NAME         READY   STATUS    RESTARTS   AGE   IP              NODE            NOMINATED NODE   READINESS GATES
demo-pod-1   1/1     Running   0          4s    10.244.102.79   xianchaonode2   
# 上面可以看到pod能正常调度到xianchaonode2上 

三、污点、容忍度、亲和性

1、node节点亲和性

[root@xianchaomaster1 ~]# kubectl explain pods.spec.affinity   
KIND:     Pod
VERSION:  v1
RESOURCE: affinity <Object>
DESCRIPTION:If specified, the pod's scheduling constraintsAffinity is a group of affinity scheduling rules.
FIELDS:nodeAffinity	<Object>   podAffinity	<Object>podAntiAffinity	<Object>[root@xianchaomaster1 ~]#  kubectl explain  pods.spec.affinity.nodeAffinity
KIND:     Pod
VERSION:  v1
RESOURCE: nodeAffinity <Object>
DESCRIPTION:Describes node affinity scheduling rules for the pod.Node affinity is a group of node affinity scheduling rules.
FIELDS:preferredDuringSchedulingIgnoredDuringExecution	<[]Object>   # 软亲和性requiredDuringSchedulingIgnoredDuringExecution	<Object>	 # 硬亲和性
[root@xianchaomaster1 ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution
KIND:     Pod
VERSION:  v1
RESOURCE: requiredDuringSchedulingIgnoredDuringExecution <Object>
DESCRIPTION:
FIELDS:nodeSelectorTerms	<[]Object> -required-Required. A list of node selector terms. The terms are ORed.[root@xianchaomaster1 ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms
KIND:     Pod
VERSION:  v1
RESOURCE: nodeSelectorTerms <[]Object>
DESCRIPTION:Required. A list of node selector terms. The terms are ORed.A null or empty node selector term matches no objects. The requirements ofthem are ANDed. The TopologySelectorTerm type implements a subset of theNodeSelectorTerm.
FIELDS:matchExpressions	<[]Object> # 匹配表达式的matchFields	<[]Object>     # 匹配字段的[root@xianchaomaster1 ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchFields
KIND:     Pod
VERSION:  v1
RESOURCE: matchFields <[]Object>
DESCRIPTION:FIELDS:     # 匹配字段key	<string> -required-values	<[]string>[root@xianchaomaster1 ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions
FIELDS:   # 匹配表达式key	<string> -required-      # key:检查labelThe label key that the selector applies to.operator	<string> -required-  # operator:做等值选则还是不等值选则Represents a key's relationship to a set of values. Valid operators are In,NotIn, Exists, DoesNotExist. Gt, and Lt.Possible enum values:- `"DoesNotExist"`- `"Exists"`- `"Gt"`- `"In"`- `"Lt"`- `"NotIn"`values	<[]string>    # values:给定值An array of string values. If the operator is In or NotIn, the values arraymust be non-empty. If the operator is Exists or DoesNotExist, the valuesarray must be empty. If the operator is Gt or Lt, the values array musthave a single element, which will be interpreted as an integer. This arrayis replaced during a strategic merge patch.

【1】硬亲和性

使用requiredDuringSchedulingIgnoredDuringExecution硬亲和性

# 把myapp-v1.tar.gz上传到xianchaonode2和xianchaonode1上,手动解压:
[root@xianchaonode1 ~]# ctr -n=k8s.io images import  myapp-v1.tar.gz 
Loaded image: ikubernetes/myapp:v1
[root@xianchaonode2 ~]# ctr -n=k8s.io images import  myapp-v1.tar.gz 
Loaded image: ikubernetes/myapp:v1[root@xianchaomaster1 ~]# cat pod-nodeaffinity-demo.yaml 
apiVersion: v1
kind: Pod
metadata:name:  pod-node-affinity-demonamespace: defaultlabels:app: myapptier: frontend
spec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:  # 匹配标签:key为zone,value为foo或bar的节点- key: zoneoperator: Invalues: - foo- barcontainers:- name: myappimage: docker.io/ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent# 我们检查当前节点中有任意一个节点拥有zone标签的值是foo或者bar
# 就可以把pod调度到这个node节点的foo或者bar标签上的节点上
[root@xianchaomaster1 ~]# kubectl apply -f pod-nodeaffinity-demo.yaml 
[root@xianchaomaster1 ~]# kubectl get pods -o wide | grep pod-node
pod-node-affinity-demo             0/1     Pending     0   xianchaonode1                       
# status的状态是pending,上面说明没有完成调度,因为没有一个拥有zone的标签的值是foo或者bar
# 而且使用的是硬亲和性,必须满足条件才能完成调度
[root@xianchaomaster1 ~]# kubectl label nodes xianchaonode1 zone=foo
# 给这个xianchaonode1节点打上标签zone=foo,在查看
[root@xianchaomaster1 ~]#kubectl get pods -o wide 显示如下:
pod-node-affinity-demo             1/1     Running  0   xianchaonode1

【2】软亲和性

使用preferredDuringSchedulingIgnoredDuringExecution软亲和性

[root@xianchaomaster1]# cat pod-nodeaffinity-demo-2.yaml 
apiVersion: v1
kind: Pod
metadata:name: pod-node-affinity-demo-2namespace: defaultlabels:app: myapptier: frontend
spec:containers:- name: myappimage: docker.io/ikubernetes/myapp:v1imagePullPolicy: IfNotPresentaffinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- preference:matchExpressions: - key: zone1operator: Invalues:- foo1- bar1weight: 10- preference:matchExpressions:- key: zone2operator: Invalues:- foo2- bar2weight: 20
[root@xianchaomaster1 ~]# kubectl apply -f pod-nodeaffinity-demo-2.yaml
[root@xianchaomaster1 ~]# kubectl get pods -o wide |grep demo-2
pod-node-affinity-demo-2           1/1     Running     0        xianchaonode1# 上面说明软亲和性是可以运行这个pod的,尽管没有运行这个pod的节点定义的zone1标签

Node节点亲和性针对的是pod和node的关系,Pod调度到node节点的时候匹配的条件

测试weight权重:
weight是相对权重,权重越高,pod调度的几率越大

# 假如给xianchaonode1和xianchaonode2都打上标签
[root@xianchaomaster1 ~]# kubectl label nodes xianchaonode1 zone1=foo1
[root@xianchaomaster1 ~]# kubectl label nodes xianchaonode2 zone2=foo2preferredDuringSchedulingIgnoredDuringExecution:- preference:matchExpressions: - key: zone1operator: Invalues:- foo1- bar1weight: 10  # 加权重- preference:matchExpressions:- key: zone2operator: Invalues:- foo2- bar2weight: 20  # 加权重# pod在定义node节点亲和性的时候,xianchaonode1和xianchaonode2都满足条件,都可以调度pod
# 但是xianchaonode2具有的标签是zone2=foo2,pod在匹配zone2=foo2的权重高,那么pod就会优先调度到xianchaonode2上[root@xianchaomaster1 ~]# kubectl label nodes xianchaonode1 zone1-
[root@xianchaomaster1 ~]# kubectl label nodes xianchaonode2 zone2-
[root@xianchaomaster1 ~]# kubectl label nodes xianchaonode1 zone-
[root@xianchaomaster1]# kubectl delete -f pod-nodeaffinity-demo.yaml
[root@xianchaomaster1]# kubectl delete -f pod-nodeaffinity-demo-2.yaml

2、pod节点亲和性

pod自身的亲和性调度有两种表示形式

podaffinity:pod和pod更倾向腻在一起,把相近的pod结合到相近的位置,如同一区域,同一机架,这样的话pod和pod之间更好通信,比方说有两个机房,这两个机房部署的集群有1000台主机,那么我们希望把nginx和tomcat都部署同一个地方的node节点上,可以提高通信效率;

podunaffinity:pod和pod更倾向不腻在一起,如果部署两套程序,那么这两套程序更倾向于反亲和性,这样相互之间不会有影响。

第一个pod随机选则一个节点,做为评判后续的pod能否到达这个pod所在的节点上的运行方式,这就称为pod亲和性;
我们怎么判定哪些节点是相同位置的,哪些节点是不同位置的;
我们在定义pod亲和性时需要有一个前提,哪些pod在同一个位置,哪些pod不在同一个位置,这个位置是怎么定义的,标准是什么?
以节点名称为标准,这个节点名称相同的表示是同一个位置,节点名称不相同的表示不是一个位置。

[root@xianchaomaster1 ~]# kubectl explain pods.spec.affinity.podAffinity
KIND:     Pod
VERSION:  v1
RESOURCE: podAffinity <Object>
DESCRIPTION:Describes pod affinity scheduling rules (e.g. co-locate this pod in thesame node, zone, etc. as some other pod(s)).Pod affinity is a group of inter pod affinity scheduling rules.
FIELDS:preferredDuringSchedulingIgnoredDuringExecution	<[]Object>requiredDuringSchedulingIgnoredDuringExecution	<[]Object>requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性
preferredDuringSchedulingIgnoredDuringExecution:# 软亲和性[root@xianchaomaster1 ~]# kubectl explain pods.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution
KIND:     Pod
VERSION:  v1
RESOURCE: requiredDuringSchedulingIgnoredDuringExecution <[]Object>
DESCRIPTION:
FIELDS:labelSelector	<Object>  namespaces	<[]string>topologyKey	<string> -required-  

topologyKey:
位置拓扑的键,这个是必须字段
怎么判断是不是同一个位置:
rack=rack1
row=row1
使用rack的键是同一个位置
使用row的键是同一个位置
labelSelector:
我们要判断pod跟别的pod亲和,跟哪个pod亲和,需要靠labelSelector,通过labelSelector选则一组能作为亲和对象的pod资源
namespace:
labelSelector需要选则一组资源,那么这组资源是在哪个名称空间中呢,通过namespace指定,如果不指定namespaces,那么就是当前创建pod的名称空间
在这里插入图片描述

【1】pod节点亲和性

定义两个pod,第一个pod做为基准,第二个pod跟着它走

# 查看默认名称空间有哪些pod
[root@xianchaomaster1 pod-2]# kubectl get pods
# 把看到的pod删除,让默认名称空间没有pod[root@xianchaomaster1 ~]# cat pod-required-affinity-demo-1.yaml 
apiVersion: v1
kind: Pod
metadata:name: pod-firstlabels:app2: myapp2tier: frontend
spec:containers:- name: myappimage: ikubernetes/myapp:v1imagePullPolicy: IfNotPresent
[root@xianchaomaster1 ]# kubectl apply -f pod-required-affinity-demo-1.yaml[root@xianchaomaster1 ~]# cat pod-required-affinity-demo-2.yaml 
apiVersion: v1
kind: Pod
metadata:name: pod-secondlabels:app: backendtier: db
spec:containers:- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 3600"]affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:  # 亲和性- labelSelector:matchExpressions:- {key: app2, operator: In, values: ["myapp2"]}topologyKey: kubernetes.io/hostname#上面表示创建的pod必须与拥有app=myapp标签的pod在一个节点上
[root@xianchaomaster1 ~]# kubectl apply -f pod-required-affinity-demo-2.yaml 
kubectl get pods -o wide 显示如下:
pod-first              running        xianchaonode2
pod-second             running        xianchaonode2# 上面说明第一个pod调度到哪,第二个pod也调度到哪,这就是pod节点亲和性
[root@xianchaomaster1 ~]# kubectl delete -f pod-required-affinity-demo-1.yaml
[root@xianchaomaster1 ~]# kubectl delete -f pod-required-affinity-demo-2.yaml

【2】pod节点反亲和性

定义两个pod,第一个pod做为基准,第二个pod跟它调度节点相反

[root@xianchaomaster1 ~]# cat pod-required-anti-affinity-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-firstlabels:app1: myapp1tier: frontend
spec:containers:- name: myappimage: ikubernetes/myapp:v1imagePullPolicy: IfNotPresent
[root@xianchaomaster1 ~]# kubectl apply -f  pod-required-anti-affinity-demo-1.yaml[root@xianchaomaster1 ~]# cat pod-required-anti-affinity-demo-2.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-secondlabels:app: backendtier: db
spec:containers:- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 3600"]affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:  # 反亲和性- labelSelector:matchExpressions:- {key: app1, operator: In, values: ["myapp1"]}topologyKey: kubernetes.io/hostname
[root@xianchaomaster1 ~]# kubectl apply -f pod-required-anti-affinity-demo-2.yaml[root@xianchaomaster1 ~]# kubectl get pods -o wide 显示两个pod不在一个node节点上,这就是pod节点反亲和性
pod-first            running        xianchaonode1
pod-second           running        xianchaonode2[root@xianchaomaster1 ~]# kubectl delete -f pod-required-anti-affinity-demo-1.yaml
[root@xianchaomaster1 ~]# kubectl delete -f pod-required-anti-affinity-demo-2.yaml

【3】换一个topologykey

[root@xianchaomaster1 ~]# kubectl label nodes  xianchaonode2  zone=foo
[root@xianchaomaster1 ~]# kubectl label nodes  xianchaonode1  zone=foo 
[root@xianchaomaster1 ~]# cat pod-first-required-anti-affinity-demo-1.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-firstlabels:app3: myapp3tier: frontend
spec:containers:- name: myappimage: ikubernetes/myapp:v1imagePullPolicy: IfNotPresent
[root@xianchaomaster1 affinity]# kubectl apply -f pod-first-required-anti-affinity-demo-1.yaml[root@xianchaomaster1]# cat pod-second-required-anti-affinity-demo-1.yaml 
apiVersion: v1
kind: Pod
metadata:name: pod-secondlabels:app: backendtier: db
spec:containers:- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentcommand: ["sh","-c","sleep 3600"]affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- {key: app3 ,operator: In, values: ["myapp3"]}topologyKey:  zone  # Pod 必须与其他拥有 app3=myapp3 标签的 Pod 分布在不同的拓扑域(例如不同的可用区域)上。[root@xianchaomaster1 affinity]# kubectl apply -f pod-second-required-anti-affinity-demo-1.yaml[root@xianchaomaster1 ~]#kubectl get pods -o wide 显示如下:
pod-first              running         xianchaonode1
pod-second            pending         <none>[root@xianchaomaster1]# kubectl delete -f pod-first-required-anti-affinity-demo-1.yaml 
[root@xianchaomaster1]# kubectl delete -f pod-second-required-anti-affinity-demo-1.yaml
[root@xianchaomaster1 ~]#  kubectl label nodes  xianchaonode1  zone-
[root@xianchaomaster1 ~]#  kubectl label nodes  xianchaonode2  zone-# 第二个pod是pending,因为两个节点是同一个位置,现在没有不是同一个位置的了
# 而且我们要求反亲和性,所以就会处于pending状态,如果在反亲和性这个位置把required改成preferred,那么也会运行。

总结:
podaffinity:pod节点亲和性,pod倾向于哪个pod
poduntiaffinity:pod反亲和性
nodeaffinity:node节点亲和性,pod倾向于哪个node

3、污点和容忍度

给了节点选择的主动权,我们给节点打一个污点,不容忍的pod就运行不上来,污点就是定义在节点上的键值属性数据,可以决定拒绝那些pod;

taints是键值数据,用在节点上,定义污点;
tolerations是键值数据,用在pod上,定义容忍度,能容忍哪些污点

pod亲和性是pod属性;但是污点是节点的属性,污点定义在k8s集群的节点上的一个字段

[root@xianchaomaster1 affinity]# kubectl describe nodes xianchaomaster1|grep Taints 
Taints:             node-role.kubernetes.io/control-plane:NoSchedule[root@xianchaomaster1 ~]# kubectl explain node.spec.taints
KIND:     Node
VERSION:  v1
RESOURCE: taints <[]Object>
DESCRIPTION:If specified, the node's taints.The node this Taint is attached to has the "effect" on any pod that doesnot tolerate the Taint.
FIELDS:effect	<string> -required-key	<string> -required-timeAdded	<string>value	<string>

taints的effect用来定义对pod对象的排斥等级(效果):

- NoSchedule:
仅影响pod调度过程,当pod能容忍这个节点污点,就可以调度到当前节点,后来这个节点的污点改了,加了一个新的污点,使得之前调度的pod不能容忍了,那这个pod会怎么处理,对现存的pod对象不产生影响
- NoExecute:
既影响调度过程,又影响现存的pod对象,如果现存的pod不能容忍节点后来加的污点,这个pod就会被驱逐
- PreferNoSchedule:
最好不,也可以,是NoSchedule的柔性版本

[root@xianchaomaster1 ~]# kubectl describe nodes xianchaomaster1
# 查看master这个节点是否有污点,显示如下:
Taints:             node-role.kubernetes.io/control-plane:NoSchedule# 上面可以看到master这个节点的污点是Noschedule
# 所以我们创建的pod都不会调度到master上,因为我们创建的pod没有容忍度
[root@xianchaomaster1 ~]# kubectl describe pods kube-apiserver-xianchaomaster1 -n kube-system
显示如下:
Tolerations:       :NoExecute op=Exists
# 可以看到这个pod的容忍度是NoExecute,则可以调度到xianchaomaster1上

【1】 NoSchedule使用

举例:把xianchaonode2当成是生产环境专用的,其他node是测试的

# 1、给节点打污点
[root@xianchaomaster1 ~]# kubectl taint node xianchaonode2 node-type=production:NoSchedule
# 2、配置pod yaml并运行
[root@xianchaomaster1 ~]# cat pod-taint.yaml 
apiVersion: v1
kind: Pod
metadata:name: taint-podnamespace: defaultlabels:tomcat:  tomcat-pod
spec:containers:- name:  taint-podports:- containerPort: 8080image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent 
[root@xianchaomaster1 ~]# kubectl apply -f pod-taint.yaml
[root@xianchaomaster1 ~]# kubectl get pods -o wide 
显示如下:
taint-pod   running    xianchaonode1

这里我创建pod的时候没有容忍度,所有pod不会调度到xianchaonode2上

【2】容忍度使用

kubectl taint nodes ydzs-node2 test=node2:NoSchedule
上面的命名将 ydzs-node2 节点标记为了污点,影响策略是 NoSchedule,只会影响新的 Pod 调度,如果仍然希望某个 Pod 调度到 taint 节点上,则必须在 Spec 中做出 Toleration 定义,才能调度到该节点

举例: 现在我们想要将一个 Pod 调度到 master 节点:(taint-demo.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:name: taintlabels:app: taint
spec:replicas: 3selector:matchLabels:app: tainttemplate:metadata:labels:app: taintspec:containers:- name: nginximage: nginxports:- name: httpcontainerPort: 80# 由于master节点被标记了污点,所以这里想要pod调度到master上# 要增加容忍度的声明tolerations:- key: "node-role.kubernetes.io/master"operator: "Exists"effect: "NoSchedule"

然后创建上面的资源,查看结果:

$ kubectl apply -f taint-demo.yaml
deployment.apps "taint" created
$ kubectl get pods -o wide
NAME                                      READY     STATUS             RESTARTS   AGE       IP             NODE
......
taint-845d8bb4fb-57mhm                    1/1       Running            0          1m        10.244.4.247   ydzs-node2
taint-845d8bb4fb-bbvmp                    1/1       Running            0          1m        10.244.0.33    ydzs-master
taint-845d8bb4fb-zb78x                    1/1       Running            0          1m        10.244.4.246   ydzs-node2
......

我们可以看到有一个 Pod 副本被调度到了 master 节点,这就是容忍的使用方法。

对于 tolerations 属性的写法,其中的 key、value、effect 与 Node 的 Taint 设置需保持一致, 还有以下几点说明:

  • 如果 operator 的值是 Exists,则 value 属性可省略
  • 如果 operator 的值是 Equal,则表示其 key 与 value 之间的关系是 equal(等于)
  • 如果不指定 operator 属性,则默认值为 Equal

另外,还有两个特殊值:

  • 空的 key 如果再配合 Exists 就能匹配所有的 key 与 value,也就是是能容忍所有节点的所有 Taints
  • 空的 effect 匹配所有的 effect

最后如果我们要取消节点的污点标记,可以使用下面的命令:

$ kubectl taint nodes ydzs-node2 test-
node "ydzs-node2" untainted

【3】NoExecute使用

举例:xianchaonode1也打上污点,pod根据容忍度匹配

[root@xianchaomaster1 ~]# kubectl taint node xianchaonode1 node-type=dev:NoExecute
[root@xianchaomaster1 ~]# kubectl get pods -o wide 
# 显示如下:
# taint-pod   termaitering
# 上面可以看到已经存在的pod节点都被撵走了[root@xianchaomaster1 ~]# cat pod-demo-1.yaml 
apiVersion: v1
kind: Pod
metadata:name: myapp-deploynamespace: defaultlabels:app: myapprelease: canary
spec:containers:- name: myappimage: ikubernetes/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80tolerations:- key: "node-type"operator: "Equal"value: "production"effect: "NoExecute"tolerationSeconds: 3600[root@xianchaomaster1 ~]# kubectl apply -f pod-demo-1.yaml
[root@xianchaomaster1 ~]# kubectl get pods
myapp-deploy   1/1     Pending   0          11s  xianchaonode2
# 这里只能调度到xianchaonode2上,但还是显示pending,因为我们使用的是equal(等值匹配),所以key和value,effect必须和node节点定义的污点完全匹配才可以
# 把上面配置effect: "NoExecute"变成effect: "NoSchedule"; tolerationSeconds: 3600这行去掉[root@xianchaomaster1 ~]# kubectl delete -f pod-demo-1.yaml
[root@xianchaomaster1 ~]# kubectl apply -f pod-demo-1.yaml
[root@xianchaomaster1 ~]# kubectl get pods
myapp-deploy   1/1     running  0          11s  xianchaonode2
# 上面就可以调度到xianchaonode2上了,因为在pod中定义的容忍度能容忍node节点上的污点

修改如下部分:

tolerations:
- key: "node-type"
operator: "Exists"
value: ""
effect: "NoSchedule"
# 只要对应的键是存在的,exists,其值被自动定义成通配符[root@xianchaomaster1 ~]# kubectl delete -f pod-demo-1.yaml
[root@xianchaomaster1 ~]# kubectl apply -f pod-demo-1.yaml
[root@xianchaomaster1 ~]# kubectl get pods
# 发现还是调度到xianchaonode2上
myapp-deploy   1/1     running  0          11s  xianchaonode2

再次修改:

tolerations:
- key: "node-type"
operator: "Exists"
value: ""
effect: ""
# 有一个node-type的键,不管值是什么,不管是什么效果,都能容忍
[root@xianchaomaster1 ~]# kubectl delete -f pod-demo-1.yaml
[root@xianchaomaster1 ~]# kubectl apply -f pod-demo-1.yaml
[root@xianchaomaster1 ~]#  kubectl get pods -o wide 显示如下:
myapp-deploy  running    xianchaonode1# 可以看到xianchaonode2和xianchaonode1节点上都有可能有pod被调度
[root@xianchaomaster1 taint]# kubectl taint nodes xianchaonode1 node-type:NoExecute-
[root@xianchaomaster1 taint]# kubectl taint nodes xianchaonode2 node-type-

四、Pod状态和重启策略

1、pod状态

在这里插入图片描述
第一阶段:

  • 挂起(Pending):

    • 正在创建Pod但是Pod中的容器还没有全部被创建完成,处于此状态的Pod应该检查Pod依赖的存储是否有权限挂载、镜像是否可以下载、调度是否正常等
    • 我们在请求创建pod时,条件不满足,调度没有完成,没有任何一个节点能满足调度条件,已经创建了pod但是没有适合它运行的节点叫做挂起,调度没有完成。
  • 失败(Failed):
    Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。

  • 未知(Unknown):
    未知状态,所谓pod是什么状态是apiserver和运行在pod节点的kubelet进行通信获取状态信息的,如果节点之上的kubelet本身出故障,那么apiserver就连不上kubelet,得不到信息了,就会看Unknown,通常是由于与pod所在的node节点通信错误。

  • Error 状态
    Pod 启动过程中发生了错误

  • 成功(Succeeded):
    Pod中的所有容器都被成功终止,即pod里所有的containers均已terminated。

第二阶段:

  • Unschedulable
    Pod不能被调度, scheduler没有匹配到合适的node节点
  • PodScheduled
    pod正处于调度中,在scheduler刚开始调度的时候,还没有将pod分配到指定的node,在筛选出合适的节点后就会更新etcd数据,将pod分配到指定的node
  • Initialized:
    所有pod中的初始化容器已经完成了
  • ImagePullBackOff
    Pod所在的node节点下载镜像失败
  • Running
    Pod内部的容器已经被创建并且启动。

扩展:还有其他状态,如下:

Evicted状态:出现这种情况,多见于系统内存或硬盘资源不足,可df-h查看docker存储所在目录的资源使用情况,如果百分比大于85%,就要及时清理下资源,尤其是一些大文件、docker镜像。
CrashLoopBackOff:容器曾经启动了,但可能又异常退出了

2、重启策略

Pod的重启策略(RestartPolicy)应用于Pod内的所有容器,当某个容器异常退出或者健康检查失败时,kubelet将根据 重启策略来进行相应的操作。

Pod 的 spec 中包含一个 restartPolicy 字段,其可能取值包括 Always、OnFailure 和 Never。默认值是 Always。

Always:只要容器异常退出,kubelet就会自动重启该容器。(这个是默认的重启策略)
OnFailure:当容器终止运行且退出码不为0时,由kubelet自动重启该容器。
Never:不论容器运行状态如何,kubelet都不会重启该容器。

【1】测试Always重启策略

[root@xianchaomaster1]# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:name: demo-podnamespace: defaultlabels:app: myapp
spec:restartPolicy: Alwayscontainers:- name:  tomcat-pod-javaports:- containerPort: 8080image: xianchao/tomcat-8.5-jre8:v1
imagePullPolicy: IfNotPresent
[root@xianchaomaster1]# kubectl apply -f pod.yaml

1)正常停止容器里的tomcat服务

[root@xianchaomaster1]# kubectl exec -it demo-pod -- /bin/bash
/usr/local/tomcat/bin/shutdown.sh# 查看pod状态:
[root@xianchaomaster1 pod-1]# kubectl get pod
NAME         READY   STATUS    RESTARTS     AGE
demo-pod   1/1     Running   1 (5s ago)   3m24s
# 发现正常停止容器里的tomcat服务,容器重启了一次,pod又恢复正常了

2)非正常停止容器里的tomcat服务

[root@xianchaomaster1]# kubectl exec -it demo-pod -- /bin/bash
kill 1[root@xianchaomaster1 pod-1]# kubectl get pod
NAME         READY   STATUS    RESTARTS     AGE
demo-pod   1/1     Running   2 (5s ago)   3m24s
# 上面可以看到容器终止了,并且又重启一次,重启次数增加了一次

【2】测试Never重启策略

[root@xianchaomaster1 ~]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:name: demo-podnamespace: defaultlabels:app: myapp
spec:restartPolicy: Nevercontainers:- name:  tomcat-pod-javaports:- containerPort: 8080image: xianchao/tomcat-8.5-jre8:v1
imagePullPolicy: IfNotPresent	[root@xianchaomaster1]# kubectl apply -f pod.yaml

1)正常停止容器里的tomcat服务

[root@xianchaomaster1]# kubectl exec -it demo-pod -- /bin/bash
/usr/local/tomcat/bin/shutdown.sh#查看pod状态:
[root@xianchaomaster1 pod-1]# kubectl get pod
NAME         READY   STATUS     RESTARTS     AGE
demo-pod   1/1       Completed  0     3m24s# 发现正常停止容器里的tomcat服务,pod正常运行,容器没有重启

2)非正常停止容器里的tomcat服务

[root@xianchaomaster1]# kubectl exec -it tomcat-pod -- /bin/bash
kill 1
[root@xianchaomaster1 pod-1]# kubectl get pod
NAME         READY   STATUS    RESTARTS     AGE
demo-pod   1/1       error     0            3m24s
# 上面可以看到容器状态是error,并且没有重启
# 这说明重启策略是never,那么pod里容器服务无论如何终止,都不会重启

【3】测试OnFailure重启策略

[root@xianchaomaster1 ~]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:name: demo-podnamespace: defaultlabels:app: myapp
spec:restartPolicy: OnFailurecontainers:- name:  tomcat-pod-javaports:- containerPort: 8080image: xianchao/tomcat-8.5-jre8:v1
imagePullPolicy: IfNotPresent	[root@xianchaomaster1]# kubectl apply -f pod.yaml

1)正常停止容器里的tomcat服务
正常退出,退出代码为0,不重启

[root@xianchaomaster1]# kubectl exec -it demo-pod -- /bin/bash
/usr/local/tomcat/bin/shutdown.sh# 查看pod状态:
[root@xianchaomaster1 pod-1]# kubectl get pod
NAME         READY   STATUS    RESTARTS     AGE
demo-pod     0/1     complete   0     3m24s# 发现正常停止容器里的tomcat服务,退出码是0,pod里的容器不会重启

2)非正常停止容器里的tomcat服务
非正常退出,容器会重启

[root@xianchaomaster1]# kubectl exec -it tomcat-pod -- /bin/bash
kill 1[root@xianchaomaster1 pod-1]# kubectl get pod
NAME         READY   STATUS    RESTARTS     AGE
demo-pod   1/1       running    1         3m24s# 上面可以看到非正常停止pod里的容器,容器退出码不是0,那就会重启容器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/838060.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode hot100-36-N

94. 二叉树的中序遍历给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。这题都写不出来&#xff0c;废了 以前学数据结构的时候&#xff0c;书上老师写伪代码&#xff0c;于是递归版的遍历在伪代码中看起来就很简单。但是怎么输出这个list呢&#xff0c;其实是另…

安泰电子电压放大器应用及示例是什么样的

电压放大器是电子电路中常用的一种器件&#xff0c;用于将输入信号的电压放大至所需的输出电压。它在许多领域中有着重要的应用&#xff0c;包括通信、音频放大、仪器测量等。以下是电压放大器的一些应用及示例&#xff1a; 信号处理&#xff1a;在许多电子系统中&#xff0c;需…

Kasawaki川崎机器人故障维修

在当今的自动化工业领域&#xff0c;川崎工业机器人以其卓越的性能和可靠的工作效率赢得了广泛的赞誉。作为机器人的核心组成部分&#xff0c;伺服电机的作用至关重要。然而&#xff0c;就像所有机械设备一样&#xff0c;也可能会遭遇电机磨损或故障&#xff0c;需要适时的川崎…

vue自定义权限指令

定义v-hasPermi指令 /*** v-hasPermi 操作权限处理*/import useUserStore from /store/modules/userexport default {mounted(el, binding, vnode) {const { value } bindingconst all_permission "*:*:*";const permissions useUserStore().permissions&#xff…

linux - 搭建部署ftp服务器

ftp 服务: 实现ftp功能的一个服务,安装vsftpd软件搭建一台ftp服务器 ftp协议: 文件传输协议 (file transfer protocol),在不同的机器之间实现文件传输功能, 例如 视频文件下载,源代码文件下载 公司内部:弄一个专门的文件服务器,将公司里的文档资料和视频都存放…

基于死区补偿的永磁同步电动机矢量控制系统simulink仿真模型

整理了基于死区补偿的永磁同步电动机矢量控制系统simulink仿真&#xff0c;该模型使用线性死区补偿的PMSM矢量控制算法进行仿真&#xff0c;使用Foc电流双闭环 。 1.模块划分清晰&#xff0c;补偿前后仿真有对比&#xff0c;易于学习; 2.死区补偿算法的线性区区域可调; 3.自…

5.13网络编程

只要在一个电脑中的两个进程之间可以通过网络进行通信那么拥有公网ip的两个计算机的通信是一样的。但是一个局域网中的两台电脑上的虚拟机是不能进行通信的&#xff0c;因为这两个虚拟机在电脑中又有各自的局域网所以通信很难实现。 socket套接字是一种用于网络间进行通信的方…

Python接口自动化测试之动态数据处理

在前面的知识基础上介绍了在接口自动化测试中&#xff0c;如何把数据分离出来&#xff0c;并且找到它的共同点&#xff0c;然后依据这个共同点来找到解决复杂问题的思想。我一直认为&#xff0c;程序是人设计的&#xff0c;它得符合人性&#xff0c;那么自动化测试的&#xff0…

自由职业是种怎样的体验?普通人如何成为一名自由职业者?

自由职业在哪都能办公自由职业在哪都要办公。 放弃幻想&#xff0c;没有不辛苦的工作&#xff0c;5年经验后端开发程序员&#xff0c;已经从事自由职业1年半&#xff0c;今天就来客观分享一下自由职业的利与弊。 时间自由&#xff0c;减少中间商赚差价 自由职业最让人羡慕的就…

React Native 开发心得分享

有一段时间没更新了&#xff0c;花了点时间研究了下 React Native&#xff08;后续用 RN 简称&#xff09;&#xff0c;同时也用该技术作为我的毕设项目(一个校园社交应用&#xff0c;仿小红书)&#xff0c;经过了这段时间的疯狂折腾&#xff0c;对 RN 生态有了一定的了解&…

【实战selenium框架下在爱企查爬取企业的历史变更信息】文末附Google浏览器和驱动的下载

代码如下 # 导入包 import random import time from tkinter import filedialog import tkinter as tk import xlrd import os import datetime import csv from selenium import webdriver from selenium.webdriver import Keys from selenium.webdriver.common.by import By…

图搜索算法-最小生成树问题-普里姆算法(prim)

相关文章&#xff1a; 数据结构–图的概念 图搜索算法 - 深度优先搜索法&#xff08;DFS&#xff09; 图搜索算法 - 广度优先搜索法&#xff08;BFS&#xff09; 图搜索算法 - 拓扑排序 图搜索算法-最短路径算法-戴克斯特拉算法 图搜索算法-最短路径算法-贝尔曼-福特算法 图搜索…

Flutter 中的 AlertDialog 小部件:全面指南

Flutter 中的 AlertDialog 小部件&#xff1a;全面指南 在Flutter中&#xff0c;AlertDialog是一个用于显示警告、错误、信息或者确认消息的模态对话框。它提供了一种简单而直接的方式与用户进行交流&#xff0c;通常用于需要用户注意的重要信息或者需要用户做出决策的场合。本…

【069】基于SpringBoot+Vue实现的企业资产管理系统

系统介绍 基于SpringBootVue实现的企业资产管理系统管理员功能有个人中心&#xff0c;用户管理&#xff0c;资产分类管理&#xff0c;资产信息管理&#xff0c;资产借出管理&#xff0c;资产归还管理&#xff0c;资产维修管理。用户可以对资产进行借出和归还操作。因而具有一定…

计算机类的英语

Algorithm&#xff08;算法&#xff09;Binary code&#xff08;二进制代码&#xff09;Byte&#xff08;字节&#xff09;Cache&#xff08;缓存&#xff09;Database&#xff08;数据库&#xff09;Encryption&#xff08;加密&#xff09;Firewall&#xff08;防火墙&#x…

软考-下午题-试题一

1、概念 2、答题技巧和规范 问题1、2&#xff1a;直接看 格式&#xff1a; 问题3&#xff1a; 格式&#xff1a; 3、例题 eg2&#xff1a;可以以后写完问题4之后&#xff0c;把问题3补充完整 问题4&#xff1a; 问题4 官方解释&#xff1a; 问题4&#xff08;3‘&#xff09; 2…

如何玩转github

如何玩转github 很多的小伙伴&#xff0c;经常会有这样的困惑&#xff0c;我看了很多技术的学习文档、书籍、甚至视频&#xff0c;我想动手实践&#xff0c;于是我打开了GitHub&#xff0c;想找个开源项目&#xff0c;进行学习&#xff0c;获取项目实战经验。这个时候很多小伙…

FDA认证的相关流程以及基本要求

一、FDA认证是什么&#xff1f; FDA认证&#xff0c;全称为"美国食品药品监督管理局认证"&#xff08;U.S. Food and Drug Administration&#xff09;&#xff0c;是美国政府机构负责确保食品、药品、医疗器械和化妆品等产品的质量、安全和有效性。FDA认证是基于美…

在做题中学习(58):和为K的子数组

560. 和为 K 的子数组 - 力扣&#xff08;LeetCode&#xff09; 因为是判断子数组的和 要返回 k 的次数&#xff0c;所以 解法&#xff1a;前缀和 哈希表 提出一个概念&#xff1a;以下标i为结尾的所有子数组 那要找出所有和 k的子数组 就相当于&#xff1a;找出所有值为…

SD8002 集成电路芯片IC高电源输出功率1W功率音频放大器

对于SD8002A的表面级封装&#xff0c;日JA140℃/W&#xff0c;TJMAX150℃。依赖于系统工作的环境温度TA&#xff0c;(2)可 用于计算由芯片封装所能承受的内部最大功耗。如果式(1)的结果比式(2)大&#xff0c;此时就需要降低电 源电压或者提高负载阻值。在5V电源和8Ω负载的典型…