kubernetes-Pod基于污点、容忍度、亲和性的多种调度策略(一)

Pod调度策略

一.标签

1.什么是标签

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

在k8s中,大部分资源都可以打标签。

2.给Pod资源打标签

创建一个Pod资源,定义标签 app:nginxenv:dev

shell 复制代码
vim test.pod

apiversion: v1
kind: Pod
metadata:
  name: test
  labels:
    app: nginx
    env: dev
spec: 
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

执行YAML文件创建Pod

shell 复制代码
kubectl apply -f test.pod

给Pod打标签

shell 复制代码
kubectl label pod test release=v1

查看Pod标签内容

shell 复制代码
kubectl  get pod test --show-labels

3.给Node节点打标签

1.添加env标签针对node1节点

shell 复制代码
kubectl label nodes node1 env=dev

2.查看标签

shell 复制代码
kubectl get nodes node1 --show-labels

3.删除env节点标签针对node1节点

shell 复制代码
kubectl label nodes node1 env-

4.查看标签资源

1.查看默认空间下所有Pod资源标签内容

shell 复制代码
kubectl get pods --show-labels

2.查看kube-system命名空间下所有Pod资源标签内容:

shell 复制代码
kubectl get pods -n kube-system --show-labels

3.查看默认默认命名空间下,标签Key=app的Pod资源,不显示标签内容:

shell 复制代码
kubectl get pods -l app

4.查看默认默认命名空间下,标签Key=app的Pod资源,并显示标签内容:

shell 复制代码
kubectl get pods -L app

5.查看所有命名空间下,所有Pod资源的标签内容

shell 复制代码
kubectl get pods --all-namespaces --show-labels

6.查看所有Node节点标签

shell 复制代码
kubectl get nodes --show-labels

二.Node选择器

Node选择器是指,我们在创建Pod资源时指定该Pod资源运行在哪台Node节点上,默认schedule会根据资源随机调度到一个工作节点,但是我们可以通过nodeName、nodeSelector在指定运行到那台Node节点。

1.nodeName(指定Pod调度到指定Node节点)

指定Pod资源调度到指定的Node节点

shell 复制代码
vim nn-pod.yaml 

apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    app: nginx
    env: dev
spec:
  nodeName: node1  # 运行在node1节点
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80

执行资源文件

shell 复制代码
kubectl apply -f nn-pod.yaml

可以看到Pod调度到了node1节点上

shell 复制代码
kubectl get pod -owide

2.nodeSelector(指定Pod调度到具有指定标签的Node节点)

指定Pod资源调度到具有哪些标签的节点上,需要注意 当使用nodeSelector 选择了多个标签,会调度到都满足此标签的节点上,并非满足其中一个标签!

如下配置,该Pod资源调度到具有 test=test节点上

shell 复制代码
vim ns-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    app: nginx
    env: dev
spec:
  nodeSelector:
    test: test
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80

执行资源文件,我们查看Pod信息时会发现 当前Pod状态处于Pending 状态,就是带决策调度到那台节点上,因为我们并没有具有 test=test 的节点,下面我们给节点打标签

shell 复制代码
kubectl label  nodes node1 test=test

再次查看,Pod处于Running状态,并调度到了指定节点

shell 复制代码
kubectl get pods -o wide

三.亲和性

1.Node亲和性-nodeAffinity

K8S中的Node亲和性是指将Pod调度到特定的节点上的能力,通过使用Node亲和性,可以将Pod调度到具有特定硬件、软件或其他特定属性的节点上,以满足应用程序的需求。

我们可以使用 explain 帮助命令查看:

shell 复制代码
kubectl explain pod.spec.affinity.nodeAffinity
  • prefered软亲和性:表示有节点尽量满足这个位置定义的亲和性,并不是一个必须的条件。

  • require硬亲和性:表示必须有节点满足这个配置定义的亲和性,这是个硬性条件。

1.定义Node硬亲和性示例如下:

shell 复制代码
cat pod-require-affinity.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx
  namespace: default
  labels:
    app: nginx
    env: dev
spec:
  affinity:
    nodeAffinity:                                     # 定义Node亲和性
      requiredDuringSchedulingIgnoredDuringExecution: # 定义硬亲和性
        nodeSelectorTerms:                           
        - matchExpressions:                 # 根据标签选择Node
          - key: env                        # 定义标签key 
            operator: In                    # IN:等于
            values:                         # 定义标签values(或者关系)
            - dev                           # 调度到具有env=dev 或者 env=test 的标签Node节点
            - test
        
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    ports: 
    - containerPort: 80 

执行后并不会创建Pod,因为没有满足标签的Node节点;给节点打标签 env=test后则会调度到此Node节点上

shell 复制代码
kubectl label node master1  env=test
kubectl get pods

2.定义Node软亲和性

shell 复制代码
cat pod-prefered-affinity.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx-prefered
  namespace: default
  labels:
    env: uat
    app: nginx
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:   # 软亲和性
      - preference:
          matchExpressions:                           # 根据标签选择Node
          - key: zone                  
            operator: In
            values:
            - foo
            - bar
        weight: 10                                    # 权重值

  containers:
  - name: pod-nginx-prefered
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80

执行后 会看到创建的Pod资源,即使没有满足标签的Node节点,也会找一台Node创建Pod资源

shell 复制代码
kubectl apply -f pod-prefered-affinity.yaml
kubectl get pods

权重值表示:weight 是相对权重,权重值越高,pod被调度到指定的node节点几率就越大

2.Pod亲和性-pod-Affinity

Pod亲和性是指将一组Pod调度到同一台物理主机或逻辑分区中的能力。这种亲和性可以用于确保相关的Pod在同一台主机上运行,以便它们可以更快地进行通信,或者为了提高可靠性,以便它们可以共享相同的存储或网络资源。

我们可以使用 explain 帮助命令查看:

shell 复制代码
kubectl explain pod.spec.affinity.podAffinity
  • prefered软亲和性:表示有节点尽量满足这个位置定义的亲和性,并不是一个必须的条件。

  • require硬亲和性:表示必须有节点满足这个配置定义的亲和性,这是个硬性条件。

1、定义两个Pod,第二个Pod调度到第一个Pod所在节点上。

第一个Pod资源清单如下:

shell 复制代码
cat pod-podaffinity-1.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-affinity-1
  namespace: default
  labels:
    app: nginx
    env: dev

spec:
  containers:
  - name: nginx
    image: nginx

第二个Pod资源清单如下

shell 复制代码
cat pod-podaffinity-2.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-affinity-2
  namespace: default
  labels:
    app: nginx
    env: dev
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:  # 硬亲和性
      - labelSelector: 
          matchExpressions:
          - key: app             # 定义 Pod的key
            operator: In         # In = =
            values: 
            - nginx              # 定义Pod的value,意思指调度到具有app=nginx标签的Pod所在节点
        topologyKey: kubernetes.io/hostname # 定义Node节点key,用于匹配节点判断是否在同一台服务器

  containers:
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command: ["sh","-c","sleep 3600"]

按照顺序执行,第二个Pod会调度到第一个Pod所在Node节点上。

shell 复制代码
kubectl apply -f pod-podaffinity-1.yaml
kubectl apply -f pod-podaffinity-2.yaml

3.Pod反亲和性-podAntiAffinity

和上面Pod亲和性相反,两组Pod不会调度到同一台物理服务器上。

1、定义两个Pod,第二个Pod,禁止调度到第一个Pod所在节点。

第一个Pod资源清单:

shell 复制代码
cat pod-1.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-1
  namespace: default
  labels:
    app: nginx
    env: dev

spec:
  containers:
  - name: nginx
    image: nginx

第二个Pod资源清单:

shell 复制代码
cat pod-2.yaml 
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-2
  namespace: default

spec:
  affinity:
    podAntiAffinity:   # Pod反亲和性
      requiredDuringSchedulingIgnoredDuringExecution:
      - topologyKey: kubernetes.io/hostname
        labelSelector: # 标签匹配 app=nginx
          matchExpressions:
          - key: app
            operator: In
            values: 
            - nginx
  containers:
  - name: nginx
    image: nginx

执行文件,两个Pod不会调度到同一个节点

shell 复制代码
kubectl apply -f pod-1.yaml
kubectl apply -f pod-2.yaml
相关推荐
史努比.1 分钟前
HPA - k8s自动伸缩机制
云原生·容器·kubernetes
运维&陈同学1 小时前
【kafka01】消息队列与微服务之Kafka详解
运维·分布式·后端·微服务·云原生·容器·架构·kafka
菜鸟小灰灰2 小时前
搭建私有docker仓库
运维·docker·容器
csdn_金手指2 小时前
docker 通过Dockerfile自定义的镜像部署Springboot项目
spring boot·docker·容器
Karoku0663 小时前
【docker集群应用】Docker网络与资源控制
运维·数据库·docker·容器
Jacket Li3 小时前
Kubeadm 安装 Kubernetes 高可用集群 v1.30.0
云原生·容器·kubernetes
泰山小张只吃荷园4 小时前
期末Python复习-输入输出
java·前端·spring boot·python·spring cloud·docker·容器
亚林瓜子6 小时前
BC-Linux8.6上面离线手动安装Docker引擎
linux·运维·docker·容器·bc-linux
kaiyuanheshang15 小时前
docker 中的entrypoint和cmd指令
运维·docker·容器·cmd·entrypoint
Python私教16 小时前
除了 Docker,还有哪些类似的容器技术?
运维·docker·容器