k8s中的集群调度

k8s中的集群调度

Kubernetes 是通过 List-Watch 的机制进行每个组件的协作,保持数据同步的,每个组件之间的设计实现了解耦

在 Kubernetes 集群中,Pod 是最小的部署单元,它包含一个或多个容器。Pod 的创建和调度是由 Kubernetes 的多个组件共同完成的,包括 API Server、Controller Manager、Scheduler 和 kubelet。本文将带您深入了解这一过程。

Pod 创建流程

  1. 用户请求:用户通过 kubectl 或其他 API 客户端向 API Server 发送创建 Pod 的请求。
  2. 存储请求:API Server 将 Pod 的元数据存储到 etcd 中。一旦存储成功,API Server 向客户端确认请求完成。
  3. 事件通知:etcd 在存储操作完成后,会向 API Server 发送一个创建事件。
  4. Controller Manager 监听:Controller Manager 通过 List-Watch 机制监听 API Server 的事件。当它接收到 Pod 创建事件时,会检查是否有对应的 Replication Controller (RC) 或其他控制器来确保所需的 Pod 副本数量。
  5. 调度准备:如果 Pod 副本数量不足,Controller Manager 会创建新的 Pod 副本,并在 API Server 中记录详细信息。
  6. Scheduler 监听:Scheduler 也通过 List-Watch 机制监听 API Server 的事件。当它接收到新的 Pod 创建事件时,它将决定将该 Pod 调度到哪个 Node 上。
  7. 调度决策:Scheduler 根据一系列的调度算法和策略(如资源需求、节点亲和性等)来选择最佳的 Node。
  8. 绑定 Pod:Scheduler 更新 Pod 的信息,包括其被调度到的 Node,并将这些信息写回 API Server,由 API Server 更新到 etcd。
  9. kubelet 监听:在每个 Node 上运行的 kubelet 通过 List-Watch 机制监听 API Server,等待被调度到该 Node 上的 Pod 事件。
  10. 容器启动:当 kubelet 发现有一个新的 Pod 被调度到它所在的 Node 时,它会调用 Docker(或其他容器运行时)来启动 Pod 中的容器。
  11. 状态反馈:kubelet 将 Pod 及其容器的状态反馈给 API Server,API Server 再将这些状态信息存储到 etcd 中。

通过指定节点来创建pod所在的node节点

没有设置指定节点时会通过调度器来进行pod创建的调度

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web1
  labels:
    app: web1
spec:
  replicas: 4
  selector:
    matchLabels:
      app: web1
  template:
    metadata:
      labels:
        app: web1
    spec:
      containers:
      - name: nginx
        image: nginx:1.16
        ports:
          - containerPort: 80

在这里插入图片描述

可以看到pod节点会平均创建在node01 和 node02 上

通过指定节点来指定创建在node01节点上

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web1
  labels:
    app: web1
spec:
  replicas: 4
  selector:
    matchLabels:
      app: web1
  template:
    metadata:
      labels:
        app: web1
    spec:
      nodeName: node01                           # 添加nodeName: node01 
      containers:
      - name: nginx
        image: nginx:1.16
        ports:
          - containerPort: 80

在这里插入图片描述

不通过调度器,直接通过指定节点将所有pod节点都部署在了node01节点上了

通过标签来指定pod创建在哪个节点上

给node节点添标签

kubectl label nodes node02 pji=a
kubectl label nodes node01 pji=b

在这里插入图片描述

可以看见node02 的标签为 pji=a ,node01 的标签为pji=b

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web1
  labels:
    app: web1
spec:
  replicas: 4
  selector:
    matchLabels:
      app: web1
  template:
    metadata:
      labels:
        app: web1
    spec:
      nodeSelector:         #添加标签
        pji: a              #标签值pji: a
      containers:
      - name: nginx
        image: nginx:1.16
        ports:
          - containerPort: 80

以上配置可以将pod节点部署到node02节点上

在这里插入图片描述

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web1
  labels:
    app: web1
spec:
  replicas: 4
  selector:
    matchLabels:
      app: web1
  template:
    metadata:
      labels:
        app: web1
    spec:
      nodeSelector:       
        pji: b
      containers:
      - name: nginx
        image: nginx:1.16
        ports:
          - containerPort: 80

以上配置可以将pod部署到node01上

在这里插入图片描述

pod 的亲和性

在 Kubernetes 中,Pod 亲和性(Pod Affinity)是一种调度策略,用于确保 Pod 调度到特定的节点上。这种策略可以通过标签选择器(Label Selector)来实现,使得具有特定标签的 Pod 倾向于调度到具有相同标签的节点上。
Pod 亲和性可以分为以下几种类型:

  1. 软亲和性(Soft Affinity)
    • podAffinityTerm:指定 Pod 应该调度的节点集合。
    • preferredDuringSchedulingIgnoredDuringExecution:定义 Pod 应该优先调度到哪些节点上。
  2. 硬亲和性(Hard Affinity)
    • podAffinityTerm:指定 Pod 必须调度的节点集合。
    • requiredDuringSchedulingIgnoredDuringExecution:定义 Pod 必须调度到哪些节点上。
      例如,如果您有一个包含两个节点的集群,并且希望将特定的 Pod 调度到具有标签 node-role.kubernetes.io/master: "" 的节点上,

硬策略 匹配标签pji=a的node的节点配置如下

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web1
  labels:
    app: web1
spec:
  replicas: 4
  selector:
    matchLabels:
      app: web1
  template:
    metadata:
      labels:
        app: web1
    spec:
      containers:
      - name: nginx
        image: nginx:1.16
        ports:
          - containerPort: 80
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: pji
                operator: In
                values:
                - a

在这里插入图片描述

若是配置一个不存在的标签这会如下

在这里插入图片描述

出现Pending状态

软策略

设置标签为bcde但是此集群没有标签bcde的主机

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web1
  labels:
    app: web1
spec:
  replicas: 20
  selector:
    matchLabels:
      app: web1
  template:
    metadata:
      labels:
        app: web1
    spec:
      containers:
      - name: nginx
        image: nginx:1.16
        ports:
        - containerPort: 80
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: pji
                operator: In
                values:
                - bcde

在这里插入图片描述

则会调度在node01 (b)和 node02©上

Pod的亲和性和反亲和性

在 Kubernetes 中,亲和性(Affinity)和反亲和性(Anti-Affinity)是调度策略的一部分,用于影响 Kubernetes 调度器如何将 Pod 调度到集群中的节点上。这些特性可以帮助您确保 Pod 之间或 Pod 与节点之间保持特定的关系。

亲和性(Affinity)

亲和性是指调度器倾向于将 Pod 调度到满足特定条件的节点上。它包括以下几种类型:

  1. 节点亲和性(Node Affinity)
    • 软亲和性(Soft Affinity):如果节点不满足条件,调度器可以忽略亲和性。
    • 硬亲和性(Hard Affinity):如果节点不满足条件,调度器将不会调度 Pod。
  2. Pod 亲和性(Pod Affinity)
    • 软亲和性:如果其他 Pod 不满足条件,调度器可以忽略亲和性。
    • 硬亲和性:如果其他 Pod 不满足条件,调度器将不会调度 Pod。
  3. Pod 反亲和性(Pod Anti-Affinity)
    • 软反亲和性:如果其他 Pod 不满足条件,调度器可以忽略反亲和性。
    • 硬反亲和性:如果其他 Pod 不满足条件,调度器将不会调度 Pod。

反亲和性(Anti-Affinity)

反亲和性是亲和性的对立面。与亲和性不同,反亲和性用于防止 Pod 调度到某些节点上,或者避免与某些 Pod 一起调度。反亲和性通常用于避免资源争用或实现高可用性。

亲和性配置

apiVersion: v1
kind: Pod
metadata:
  name: web5
  labels:
    app: web2
spec:
  containers:
  - name: nginx
    image: nginx:1.16
    ports:
    - containerPort: 80
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - web2                      # 在有pod标签app=web2的标签上创建
        topologyKey: pji                #在拥有pji标签的节点上创建

在这里插入图片描述

反亲和性

apiVersion: v1
kind: Pod
metadata:
  name: web5
  labels:
    app: web1
spec:
  containers:
  - name: nginx
    image: nginx:1.14
    ports:
    - containerPort: 80
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: "app"
              operator: In
              values:
              - web2
          topologyKey: "kubernetes.io/hostname"

之前的pod标签为web2 ,设置非亲缘性后 web5创建会避开node02

在这里插入图片描述

当然可以。

污点与容忍

污点(Taint)

污点是向节点添加的一个标签,它告诉 Kubernetes 调度器不要将 Pod 调度到具有该污点的节点上。这通常用于防止 Pod 调度到不希望它们运行的节点上,例如,当节点正在进行维护或出现问题时。
污点可以具有以下三个属性:

  • 键(Key):污点的键,用于标识污点。
  • 值(Value):与键关联的值。
  • 效果(Effect):当污点匹配时,Pod 应该受到的影响。有效果包括 NoSchedulePreferNoScheduleNoExecute

污点的创建

给node01创建一个键值对为ry=87的污点,使用NoSchedule策略

kubectl taint node node01 ry=87:NoSchedule

在这里插入图片描述

apiVersion: v1
kind: Pod
metadata:
  name: nginx4
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80

创建新的Pod都创建在node02下,而不会创建在node01上

在这里插入图片描述

容忍(Tolerations)

容忍是 Pod 上的一个标签,它告诉 Kubernetes 调度器,尽管节点具有某个污点,但该 Pod 应该被调度到该节点上。容忍可以有多个键值对,并且可以设置不同的效果和时间范围。

设置容忍

apiVersion: v1
kind: Pod
metadata:
  name: nginx4
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
  tolerations:
  - key: "ry"
    operator: "Equal"
    value: "87"
    effect: "NoSchedule"


在这里插入图片描述

可以看见,node01的污点被无视了

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值