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
相关推荐
云和数据.ChenGuang6 分钟前
微服务技术栈
微服务·云原生·架构
syty202011 分钟前
K8s是什么
容器·kubernetes·dubbo
江团1io01 小时前
微服务雪崩问题与系统性防御方案
微服务·云原生·架构
Evan Wang2 小时前
使用Terraform管理阿里云基础设施
阿里云·云原生·terraform
向上的车轮3 小时前
基于go语言的云原生TodoList Demo 项目,验证云原生核心特性
开发语言·云原生·golang
灵犀物润3 小时前
Kubernetes 配置检查与发布安全清单
安全·容器·kubernetes
360智汇云4 小时前
k8s交互桥梁:走进Client-Go
golang·kubernetes·交互
xy_recording4 小时前
Day20 K8S学习
学习·容器·kubernetes
衍余未了5 小时前
k8s 内置的containerd配置阿里云个人镜像地址及认证
java·阿里云·kubernetes
九章云极AladdinEdu5 小时前
Kubernetes设备插件开发实战:实现GPU拓扑感知调度
人工智能·机器学习·云原生·容器·kubernetes·迁移学习·gpu算力