Pod基于污点、容忍度、亲和性的多种调度策略

Pod基于污点、容忍度、亲和性的多种调度策略

labels

# 对已经存在的pod打标签
kubectl label pods tomcat-test release=v1
# 对node打标签
kubectl label nodes node1 disk=ceph

# 删除标签
kubectl label pods tomcat-test release-
kubectl label nodes node1 disk-

# 检查
kubectl get pods tomcat-test --show-leabels

# 过滤出带有该标签的pod,不显示标签
kubectl get pods -l release
kubectl get pods -l release=v1

# 过滤出带有该标签的pod,并打印标签值
kubectl get pods -L release

#查看所有名称空间下的所有pod的标签
kubectl get pods --all-namespaces --show-labels

nodeName和nodeSelector

nodeName:将pod创建到你指定选择的node上

cat > pod-node.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
  namespace: default
  labels:
    app: myapp
    env: dev
spec:
  # 使用nodeName指定创建的node节点
  nodeName: node1
  containers:
  - name:  tomcat-pod-java
    ports:
    - containerPort: 8080
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
  - name: busybox
    image: busybox:latest
    # 在pod中跑一个程序,防止pod启动就结束
    command:
    - "/bin/sh"
    - "-c"
    - "sleep 3600"

nodeSelector:将pod创建到指定标签的node上

cat > pod-node.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
  namespace: default
  labels:
    app: myapp
    env: dev
spec:
  # 使用nodeSelector指定带有ceph标签的node节点
  nodeSelector: 
    disk: ceph
  containers:
  - name:  tomcat-pod-java
    ports:
    - containerPort: 8080
    image: tomcat:8.5-jre8-alpine
    imagePullPolicy: IfNotPresent
  - name: busybox
    image: busybox:latest
EOF

# 如果node标签不存在,pod会创建失败,进入pending状态
# 在同一个yaml文件中,同时声明nodeName和nodeSelector,必须两个条件都满足才能调度成功

node亲和性(nodeAffinity)

针对的是pod在选择不同类型标签的node时,选择匹配成功标签的node。key的匹配参数是node的标签(matchExpressions)或字段(matchFields)

kubectl explain pods.spec.affinity.nodeAffinity

nodeAffinity

​ preferredDuringSchedulingIgnoredDuringExecution(软亲和性)表示有节点尽量满足这个位置定义的亲和性,这不是一个必须的条件

​ requiredDuringSchedulingIgnoredDuringExecution(硬亲和性)表示必须有节点满足这个位置定义的亲和性,这是个硬性条件

 operator	<string> -required-
     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"`
apiVersion: v1
kind: Pod
metadata: 
  name: pod-node-affinity-demo
  namespace: default
  labels: 
    app: myapp
    tier: frontend
spec: 
  affinity: 
    nodeAffinity: 
      requiredDuringSchedulingIgnoredDuringExecution: 
        nodeSelectorTerms:
        - matchExpressions: 
        # 有任意一个节点拥有zone标签的值是foo或者bar,就可以把pod调度到这个node节点的foo或者bar标签上的节点上
          - key:  zone
            # In就类似与等号
            operator: In     
            value: 
            - foo
            - bar
  containers: 
  - name: myapp 
    image: xxx
    imagePullPolicy: IfNotPresent
    
# 如果没有匹配成功,pod不会调度,会进入pending
apiVersion: v1
kind: Pod
metadata: 
  name: pod-node-affinity-demo-2
  namespace: default
  labels: 
    app: myapp2
    tier: frontend
spec: 
  affinity: 
    nodeAffinity: 
      preferredDuringSchedulingIgnoredDuringExecution: 
      - preference:
        # 权重,如果多个key都满足条件,优先选择权重高的preference
        weight: 10
          matchExpressions: 
        # 只要任意一个key value匹配,就调度到该node
          - key:  zone1
            # In就类似与等号
            operator: In     
            value: 
            - foo1
            - bar1
      - preference:
        weight: 20
          - key: zone2
            operator: In
            value: 
            - foo2
            - bar2
  containers: 
  - name: myapp2
    image: xxx
    imagePullPolicy: IfNotPresent
    
# 如果没有匹配成功,pod仍然可以调度

Pod亲和性(podAffinity)

针对的是pod在选择具有相同标签或没有标签的node时,如何去进一步选择node。key的匹配参数是pod的labels信息(labelSelector)

kubectl explain pods.spec.affinity.podAffinity
# 创建一个普通的pod1
apiVersion: v1
kind: Pod
metadata: 
  name: pod-first
  labels: 
    app2: myapp2
    tier: frontend
spec: 
  containers: 
  - name: myapp
    image: xxx
    imagePullPolicy: IfNotPresent
# 创建一个有亲和性的pod2
apiVersion: v1
kind: Pod
metadata: 
  name: pod-second
  labels: 
    app: backend
    tier: db
spec: 
  affinity: 
    porAffinity: 
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector: 
          matchExpressions: 
          - {key: app2, operator: In, values: ["myapp2"]}
    # 指的是通过什么key值匹配到集群存在的node
    # 使用 kubectl get nodes --show-labels,找到kubernetes.io/hostname=
    topologyKey: kubernetes.io/hostname    
  containers: 
  - name: myapp2
    image: xxx
    imagePullPolicy: IfNotPresent
    
# 这样pod2就会去找 app2=myapp2的pod1,并调度到在pod1运行的node节点进行pod2的创建

pod反亲和性(podAntiAffinity)

# 这样pod2就会去找 app2=myapp2的pod1,并调度到不在pod1运行的node节点进行pod2的创建
# 修改topologyKey
# 首先给所有工作node打标签
kubectl label nodes node1 zone=foo
kubectl label nodes node2 zone=foo

# 配置反亲和的pod
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"]}
           # 表示带有zone标签的反亲和
           topologyKey:  zone
           
# 这样该pod会调度失败 

污点、容忍度

给节点打一个污点,不容忍的pod就运行不起来,简言之就是可以排斥哪些pod运行。容忍度就是可以允许污点存在的pod运行。

  • 污点taints:针对node,定义污点
  • 容忍度tolerations:针对pod,定义容忍度
kubectl explain node.spec.taints
kubectl explain node.spec.tolerations

# 查看污点
kubectl describe node node1 | grep -i taints
# 查看容忍度
kubectl describe pods kube-apiserver-master1 -n kube-system |grep -i toleration
# 定义污点 key是node-type,value是production,污点标签是NoSchedule
kubectl taint node node1 node-type=production:NoSchedule
# 删除污点
kubectl taint node node1 node-type-

### effect参数。 表示排斥等级
# NoSchedule:
仅影响pod调度过程,当pod能容忍这个节点污点,就可以调度到当前节点,后来这个节点的污点改了,加了一个新的污点,使得之前调度的pod不能容忍了,那这个pod会怎么处理,对现存的pod对象不产生影响

# NoExecute:
既影响调度过程,又影响现存的pod对象,如果现存的pod不能容忍节点后来加的污点,这个pod就会被驱逐

# PreferNoSchedule:
最好不,也可以,是NoSchedule的柔性版本
# 定义容忍度,在pod的配置文件添加配置
cat > pod-demo.yaml << EOF
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
EOF

# operator参数
# 一次匹配(Exist),类似for循环,只要有相同的就可以容忍
# 完全匹配(Equal),必须全部相同

Pod常见状态和重启策略

### 第一阶段
# Pending (挂起)
1、正在创建Pod但是Pod中的容器还没有全部被创建完成,处于此状态的Pod应该检查Pod依赖的存储是否有权限挂载、镜像是否可以下载、调度是否正常等

2、我们在请求创建pod时,条件不满足,调度没有完成,没有任何一个节点能满足调度条件,已经创建了pod但是没有适合它运行的节点叫做挂起,调度没有完成。

# Failed (失败)
Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止(非正常退出)。

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

# Error (错误)
Pod 启动过程中发生了错误

# Successed 
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
容器曾经启动了,但可能又异常退出了

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

### Pod 的 spec 中包含一个 restartPolicy 字段,其可能取值包括 Always、OnFailure 和 Never。默认值是 Always。
# Always:只要容器异常退出,kubelet就会自动重启该容器。(这个是默认的重启策略)
# OnFailure:当容器终止运行且退出码不为0时,由kubelet自动重启该容器。
# Never:不论容器运行状态如何,kubelet都不会重启该容器。

# 正常停止pod的容器
# 状态会变成Completed
kubectl exec -it demo-pod -- /bin/bash /usr/local/tomcat/bin/shutdown.sh

# 非正常停止pod的容器
kubectl exec -it demo-pod -- /bin/bash kill 1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kubernetes中,亲和性(Affinity)和反亲和性(Anti-Affinity)是用于定义Pod如何与其他Pod或节点进行调度策略。而污点(Taint)和容忍(Toleration)则用于控制哪些Pod可以被调度到特定的节点上。 亲和性和反亲和性: - 亲和性:通过亲和性规则,可以指定Pod与其他Pod或节点之间的关系。例如,可以让一个Pod亲和于具有特定标签的节点,这样它就会更有可能被调度到这些节点上。 - 反亲和性:与亲和性相反,反亲和性规则可以指定Pod与某些Pod或节点之间的冲突关系。例如,可以让一个Pod反亲和于具有特定标签的节点,这样它就不会被调度到这些节点上。 亲和性和反亲和性规则可以通过使用Pod的`spec.affinity`字段来定义。 污点容忍: - 污点污点是节点上的一个属性,可以将其应用于节点,以阻止一些Pod调度到该节点上。污点可以指定键值对形式的标签,并具有可选的效果(effect),如NoSchedule、PreferNoSchedule、NoExecute等。当节点上有一个或多个污点时,只有具有对应容忍规则的Pod才能被调度到该节点上。 - 容忍容忍Pod的一个属性,用于声明Pod可以容忍哪些污点。通过在Pod的`spec.tolerations`字段中定义容忍规则,Pod可以在具有相应污点的节点上进行调度污点容忍规则可以通过使用Pod的`spec.tolerations`字段来定义。 使用亲和性、反亲和性污点容忍规则,可以更精确地控制Pod调度和部署策略,以满足特定的应用需求和资源限制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值