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创建的调度

yaml 复制代码
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节点上

yaml 复制代码
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节点添标签

bash 复制代码
kubectl label nodes node02 pji=a
kubectl label nodes node01 pji=b

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

yaml 复制代码
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节点上

yaml 复制代码
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的节点配置如下

yaml 复制代码
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的主机

yaml 复制代码
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 一起调度。反亲和性通常用于避免资源争用或实现高可用性。

亲和性配置

yaml 复制代码
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标签的节点上创建

反亲和性

yaml 复制代码
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策略

bash 复制代码
kubectl taint node node01 ry=87:NoSchedule
yaml 复制代码
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 应该被调度到该节点上。容忍可以有多个键值对,并且可以设置不同的效果和时间范围。

设置容忍

yaml 复制代码
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 分钟前
wsl2中kali linux下的docker使用教程(教程总结)
linux·经验分享·docker·云原生
Python私教1 小时前
ubuntu搭建k8s环境详细教程
linux·ubuntu·kubernetes
运维&陈同学2 小时前
【zookeeper01】消息队列与微服务之zookeeper工作原理
运维·分布式·微服务·zookeeper·云原生·架构·消息队列
O&REO2 小时前
单机部署kubernetes环境下Overleaf-基于MicroK8s的Overleaf应用部署指南
云原生·容器·kubernetes
politeboy2 小时前
k8s启动springboot容器的时候,显示找不到application.yml文件
java·spring boot·kubernetes
运维小文3 小时前
K8S资源限制之LimitRange
云原生·容器·kubernetes·k8s资源限制
登云时刻3 小时前
Kubernetes集群外连接redis集群和使用redis-shake工具迁移数据(二)
redis·容器·kubernetes
wuxingge12 小时前
k8s1.30.0高可用集群部署
云原生·容器·kubernetes
志凌海纳SmartX13 小时前
趋势洞察|AI 能否带动裸金属 K8s 强势崛起?
云原生·容器·kubernetes
锅总13 小时前
nacos与k8s service健康检查详解
云原生·容器·kubernetes