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

news2024/11/15 4:46:40

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

  • 一、标签
    • 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: mypod
  labels:      # 打标签 ——》app: backend 和 tier: production。
    app: backend
    tier: production
spec:
  containers:
  - name: mycontainer
    image: nginx

【2】给Service打标签

apiVersion: v1
kind: Service
metadata:
  name: myservice
  labels:   # 打标签 ——》  app: frontend和tier: production
    app: frontend
    tier: production
spec:
  selector:
    app: frontend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 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-pod
  namespace: default
  labels:
    app: myapp
    env: dev
spec:
  nodeName: xianchaonode1  # 指定pod节点运行在xianchaonode1节点上
  containers:
  - name:  tomcat-pod-java
    ports:
    - containerPort: 8080
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
  - name: busybox
    image: busybox:latest
    command:
    - "/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-1
  namespace: default
  labels:
    app: myapp
    env: dev
spec:
  nodeSelector:  # 调度到具有disk=ceph标签的node上
    disk: ceph
  containers:
  - name:  tomcat-pod-java
    ports:
    - containerPort: 8080
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: 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-1
  namespace: default
  labels:
    app: myapp
    env: dev
spec:
  nodeName: xianchaonode2  # 指定节点
  nodeSelector: 		   # 指定标签
    disk: ceph
  containers:
  - name:  tomcat-pod-java
    ports:
    - containerPort: 8080
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: 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 constraints
    Affinity 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 of
     them are ANDed. The TopologySelectorTerm type implements a subset of the
     NodeSelectorTerm.
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:检查label
     The 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 array
     must be non-empty. If the operator is Exists or DoesNotExist, the values
     array must be empty. If the operator is Gt or Lt, the values array must
     have a single element, which will be interpreted as an integer. This array
     is 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-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
spec:
  affinity:
    nodeAffinity:
     requiredDuringSchedulingIgnoredDuringExecution:
       nodeSelectorTerms:
       - matchExpressions:  # 匹配标签:key为zone,value为foo或bar的节点
         - key: zone
           operator: In
           values: 
           - foo
           - bar
  containers:
  - name: myapp
    image: 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-2
  namespace: default
  labels:
    app: myapp
    tier: frontend
spec:
  containers:
  - name: myapp
    image: docker.io/ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - preference:
          matchExpressions: 
          - key: zone1
            operator: In
            values:
            - foo1
            - bar1
        weight: 10
      - preference:
          matchExpressions:
          - key: zone2
            operator: In
            values:
            - foo2
            - bar2
        weight: 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=foo2

preferredDuringSchedulingIgnoredDuringExecution:
      - preference:
          matchExpressions: 
          - key: zone1
            operator: In
            values:
            - foo1
            - bar1
        weight: 10  # 加权重
      - preference:
          matchExpressions:
          - key: zone2
            operator: In
            values:
            - foo2
            - bar2
        weight: 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 the
     same 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-first
  labels:
    app2: myapp2
    tier: frontend
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
      imagePullPolicy: 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-second
  labels:
    app: backend
    tier: db
spec:
    containers:
    - name: busybox
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["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-first
  labels:
    app1: myapp1
    tier: frontend
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
      imagePullPolicy: 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-second
  labels:
    app: backend
    tier: db
spec:
    containers:
    - name: busybox
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["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-first
  labels:
    app3: myapp3
    tier: frontend
spec:
    containers:
    - name: myapp
      image: ikubernetes/myapp:v1
      imagePullPolicy: 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-second
  labels:
    app: backend
    tier: db
spec:
    containers:
    - name: busybox
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      command: ["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 does
     not 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-pod
  namespace: default
  labels:
    tomcat:  tomcat-pod
spec:
  containers:
  - name:  taint-pod
    ports:
    - containerPort: 8080
    image: 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: taint
  labels:
    app: taint
spec:
  replicas: 3
  selector:
    matchLabels:
      app: taint
  template:
    metadata:
      labels:
        app: taint
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - name: http
          containerPort: 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-deploy
  namespace: default
  labels:
    app: myapp
    release: canary
spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
      tolerations:
      - 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-pod
  namespace: default
  labels:
    app: myapp
spec:
  restartPolicy: Always
  containers:
  - name:  tomcat-pod-java
    ports:
    - containerPort: 8080
    image: 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-pod
  namespace: default
  labels:
    app: myapp
spec:
  restartPolicy: Never
  containers:
  - name:  tomcat-pod-java
    ports:
    - containerPort: 8080
    image: 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-pod
  namespace: default
  labels:
    app: myapp
spec:
  restartPolicy: OnFailure
  containers:
  - name:  tomcat-pod-java
    ports:
    - containerPort: 8080
    image: 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.coloradmin.cn/o/1677800.html

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

相关文章

直播用什么领夹麦比较好?多款音质出色的无线领夹麦克风推荐

近年来&#xff0c;随着网络直播、短视频、网课等新兴行业的蓬勃发展&#xff0c;大家对领夹麦克风的需求量也在不断增加&#xff0c;因为一款优质的领夹麦克风不仅方便携带&#xff0c;而且能够带来更清晰、更真实的录音效果&#xff0c;让我们在各种场景下都能获得满意的录音…

第二证券股市策略:股票st连续跌停卖不出怎么办啊?

对于接连跌停的st股票买不出&#xff0c;投资者只能早早地挂出跌停托付单等着成交&#xff0c;在当天没有成交&#xff0c;其托付单会被撤销&#xff0c;投资者能够挑选进行隔夜托付卖出时&#xff0c;最好在证券公司清算之后&#xff0c;再进行托付卖出&#xff0c;否则&#…

ORACLE ODAX9-2的一个误告警Affects: /SYS/MB的分析处理

在运维的多套ORACLE ODAX9-2版本&#xff0c;都遇到了一个计算节点的告警&#xff1a;Description: The service Processor poweron selftest has deteced a problem. Probabity;:100, UulD:cd1ebbdf-f099-61de-ca44-ef646defe034, Resource:/SYS/MB,&#xff1b;此告警从描述上…

哪个牌子的超声波清洗机好?四大质量出众超声波清洗机汇众

由于科技的进步&#xff0c;超声波清洗机已经成为了家庭和专业场所不可或缺的高效清洁工具。它利用超声波波动产生的微小气泡来清洁物品表面及细缝中的污渍&#xff0c;实现深层次的清洁效果。特别是对于眼镜这样的精密物品&#xff0c;定期进行深度清洁不仅能够确保视觉的清晰…

【解决】Unity Build 应用程序运行即崩溃问题

开发平台&#xff1a;Unity 2021.3.7f1c1   一、问题描述 编辑器 Build 工程结束&#xff0c;但控制台 未显示 Build completed with a result of Succeeded [时间长度] 信息。该情况下打包流程正常&#xff0c;但应用程序包打开即崩溃。   二、问题测试记录 测试1&#xf…

必背!!2024年软考中级——网络工程师考前冲刺几页纸

距离软考考试的时间越来越近了&#xff0c;趁着这两周赶紧准备起来 今天给大家整理了——软考网络工程师考前冲刺几页纸&#xff0c;都是核心重点&#xff0c;有PDF版&#xff0c;可打印下来&#xff0c;每天背一点。 计算机总线分类 ①总线的分类&#xff1a;数据总线、地址总…

商城免费搭建之java商城 java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

【js刷题:数据结构链表之设计链表】

设计链表 一、题目二、题解 一、题目 二、题解 // 定义节点类&#xff0c;每个节点都有一个值和一个指向下一个节点的引用 class LinkNode{constructor(val,next){ // 构造函数&#xff0c;接收节点值和下一个节点的引用this.valval // 节点的值this.nextnext // 指…

班组建设门道多,企业管理咨询公司助你轻松上手!

班组作为企业的基本单元&#xff0c;其建设水平直接关系到企业的整体运营效率和员工的工作积极性。那么&#xff0c;如何有效地进行班组建设&#xff1f;班组建设又有啥门道呢&#xff1f;本文&#xff0c;深圳天行健企业管理咨询公司将从多个角度探讨这一问题&#xff0c;以期…

牛客热题:二叉树的最大深度

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;二叉树的最大深度题目链接方法一…

算法day06

第一题 1658. 将 x 减到 0 的最小操作数 如题上述&#xff1a; 本题原来的意思给定一个数字x&#xff0c;从数组的左边或者右边 使用x减去数组中的数字&#xff0c;直到减去最后一个数字为0时&#xff0c;返回最小的操作次数&#xff1b;如果最终减去的数组中的数字之后不能得…

ElastiCache Serverless for Redis应用场景和性能成本分析

一. 前言 传统基于实例节点的 Redis 缓存架构中&#xff0c;扩展性是一个重要影响因素。在很多场景中&#xff0c;例如广告投放、电商交易、游戏对战&#xff0c;流量是经常变化的。无论是主从还是集群模式&#xff0c;当大流量进入时&#xff0c;Redis 处理能力达到上限&…

【保姆级介绍下运维】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

爱校对新功能上线:领导人讲话和职务排序校对

我们很高兴地宣布&#xff0c;爱校对网站正式推出两项新功能&#xff1a;领导人讲话校对和领导人职务排序校对。这些新功能旨在帮助用户更准确地引用和整理领导人讲话内容&#xff0c;以及正确排列领导人的职务顺序。 领导人讲话校对 在撰写报告或文章时&#xff0c;引用领导…

数据结构与算法===优先队列

文章目录 前言一、优先队列二、应用场景三、代码实现总结 前言 之前写过很多数据结构与算法相关的了&#xff0c;今天看一个新的数据结构&#xff0c;优先队列。优先队列类似队列&#xff0c;却又优先于队列&#xff0c;是堆实现的。接下来详细看看。 一、优先队列 优先队列一…

Java面试八股之为什么要使用克隆

Java中为什么要使用克隆&#xff1f;怎么实现对象的克隆&#xff1f;深拷贝和浅拷贝的区别是什么 在Java中使用克隆主要有以下几个原因&#xff1a; 创建对象副本&#xff1a;克隆可以快速创建一个与原对象状态完全相同的副本&#xff0c;无需手动逐一复制每个属性。这种情况…

网络故障快速定位的秘诀 - 基于 AnaTraf 全流量回溯分析

网络故障是每个 IT 从业者都深有体会的头疼问题。当网络出现异常时,如何快速定位故障原因,恢复网络正常运行,是考验运维能力的关键所在。借助 AnaTraf 网络流量分析仪的全流量回溯分析功能,您可以轻松应对各种复杂的网络问题,实现快速故障定位。 1. 网络故障分析的痛点 网络故…

STM32_HAL_TIM_通用计时器_实现计时

项目思路 1使用定时器计数每秒一次 2使用一个变量记录定时器响应多少次 3使用UART将记录的次数发出 1STM32Cude设置 1配置时钟源 2打开UART 3打开TIM2 3.1界面介绍 3.2选项介绍 Slave Mode&#xff08;从模式&#xff09;&#xff1a;当设备被设置为从模式时&#xff0c…

flowable工作流设置审批人为指定角色+部门的实现方式

一、绘制流程图页面配置 1、指定固定审批角色组织的实现 如上图红框部分&#xff0c;需要修改此处为需求对应。比如此时红框不支持指定某个部门下的指定角色这种组合判断的审批人。则需要修改页面变成选完角色同时也选择上部门统一生成一个group标识。 修改完后&#xff0c;生…

海思Hi3065H 200MHz 高性能 RISCV32 A² MCU

这是一款海思自研的RISCV32内核的高性能实时控制专用MCU&#xff0c; 具有高性能、高集成度、高可靠性、易开发的特点&#xff0c;同时还有嵌入式AI能力。 CPU • RISC-V200MHzFPU 存储 • Up to 152KB Code Flash • 8KB Data Flash • 16KB SRAM 个人认为这是MCU梯队非常…