【k8s应用管理】kubernetes 群集调度管理

Kubernetes 群集调度管理

Kubernetes Pod 创建过程及组件协作

  1. 组件初始化与监听

    • Controller ManagerSchedulerkubelet 在启动时开始监听(Watch)APIServer 发出的事件。
    • 这些组件通过 HTTPS 的 6443 端口与 APIServer 通信。
  2. 用户提交请求

    • 用户通过 kubectl 或其他 API 客户端向 APIServer 提交请求,创建一个 Pod 对象副本。
  3. APIServer 存储与反馈

    • APIServer 尝试将 Pod 对象的相关元信息存入 etcd。
    • 写入操作完成后,APIServer 返回确认信息至客户端。
  4. etcd 发送 Create 事件

    • etcd 接受创建 Pod 信息后,发送一个 Create 事件给 APIServer。
  5. Controller Manager 处理 Create 事件

    • Controller Manager 监听到 Create 事件后,调用 Replication Controller(RC)确保 Node 上需要创建的副本数量。
    • RC 根据定义的副本数量自动创建或删除副本。
  6. APIServer 更新 Pod 信息

    • APIServer 在 etcd 中记录 Pod 的详细信息,如副本数、容器内容等。
    • etcd 将更新信息通过事件发送给 APIServer。
  7. Scheduler 调度 Pod

    • Scheduler 监听到 Pod 创建事件后,根据调度算法和策略将 Pod 绑定到集群中的某个 Node 上。
    • Scheduler 更新 Pod 信息至 APIServer,由 APIServer 更新至 etcd。
  8. APIServer 反映调度结果

    • etcd 将调度成功的事件发送给 APIServer。
    • APIServer 开始反映此 Pod 对象的调度结果。
  9. kubelet 启动容器

    • kubelet 监听到 Pod 更新事件后,在当前 Node 上调用 Docker 启动容器。
    • kubelet 将 Pod 及容器的状态回送至 APIServer。
  10. APIServer 存储状态信息

    • APIServer 将 Pod 状态信息存入 etcd。
    • etcd 确认写入操作成功后,APIServer 将确认信息发送至相关的 kubelet。

Kubernetes 调度过程

Kubernetes 的调度器(Scheduler)负责将定义的 Pod 分配到集群的节点上。调度过程主要关注公平性、资源高效利用、效率和灵活性。调度器运行为一个独立的程序,持续监听 APIServer,并处理 spec.nodeName 为空的 Pod。
调度过程分为以下几个步骤:

  1. Predicate(过滤阶段)

    • 调度器首先会过滤掉不满足条件的节点。
    • 常见的 Predicate 算法包括:PodFitsResources(检查节点资源是否足够)、PodFitsHost(检查节点名称是否与 Pod 指定的 NodeName 匹配)、PodFitsHostPorts(检查节点端口是否与 Pod 请求的端口冲突)、PodSelectorMatches(过滤掉与 Pod 指定的 label 不匹配的节点)和 NoDiskConflict(检查已挂载的 volume 是否与 Pod 指定的 volume 冲突)。
  2. Priorities(优选阶段)

    • 如果有多个节点满足条件,调度器会根据优先级对节点进行排序。
    • 优先级由一系列键值对组成,表示不同的优先级项目和其权重。
    • 常见的优先级选项包括:LeastRequestedPriority(倾向于资源使用比例更低的节点)、BalancedResourceAllocation(倾向于 CPU 和 Memory 使用率更接近的节点)和 ImageLocalityPriority(倾向于已经有要使用镜像的节点)。
  3. Binding(绑定阶段)

    • 调度器选择优先级最高的节点,并创建一个 binding,表明该 Pod 应该被调度到哪个节点上。

Kubernetes Scheduler 工作原理

Scheduler 是 Kubernetes 的核心组件,负责将 Pod 分配到集群的合适节点上。其调度过程主要关注以下方面:

  • 公平性:确保每个节点都能被分配资源。
  • 资源高效利用:最大化集群资源的利用率。
  • 效率:快速调度大批量的 Pod。
  • 灵活性:允许用户根据需求自定义调度逻辑。

Scheduler 启动后会持续监听 APIServer,获取 spec.nodeName 为空的 Pod,并为每个 Pod 创建一个 binding,指明其应部署的节点。

调度流程

调度过程主要分为以下步骤:

  1. Predicate(过滤):首先排除不满足条件的节点。常见的 Predicate 算法包括检查节点资源是否充足、端口是否冲突、标签是否匹配等。

  2. Priorities(优选):对通过 Predicate 的节点按照优先级排序。优先级由一系列键值对组成,键是优先级项的名称,值是权重。常见的优先级选项有资源使用率、资源均衡度、镜像本地性等。

  3. 选择节点:从排序后的节点中选择优先级最高的节点作为 Pod 的部署节点。

指定调度节点的方式

  1. pod.spec.nodeName:直接将 Pod 调度到指定的 Node 节点上,跳过 Scheduler 的调度策略。这种方式是强制匹配。

  2. pod.spec.nodeSelector:通过 Kubernetes 的 label-selector 机制选择节点。Scheduler 会根据 Pod 的 nodeSelector 和节点的标签进行匹配,然后将 Pod 调度到目标节点。这种方式属于强制约束。

示例操作

使用 nodeName 指定调度节点
  • 创建一个 Deployment,指定 nodeNamenode01
  • 应用 YAML 文件后,所有 Pod 都会被调度到 node01 上。
  • 通过 kubectl describe pod 查看 Pod 事件,发现未经过 Scheduler 调度分配。

使用 pod.spec.nodeName

  • 通过在 Pod 定义中指定 nodeName,可以直接将 Pod 调度到指定的节点上,这会跳过调度器的调度策略。
  • 示例 YAML 配置如下:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: myapp
      template:
        metadata:
          labels:
            app: myapp
        spec:
          nodeName: node01
          containers:
          - name: myapp
            image: soscscs/myapp:v1
            ports:
            - containerPort: 80
    
  • 应用此配置后,Pod 会被调度到 node01 上。
使用 nodeSelector 指定调度节点
  • 给节点 node01node02 分别设置标签 myname=amyname=b
  • 创建一个 Deployment,指定 nodeSelectormyname=a
  • 应用 YAML 文件后,所有 Pod 都会被调度到标签为 myname=a 的节点上(即 node01)。
  • 通过 kubectl describe pod 查看 Pod 事件,发现先经过 Scheduler 调度分配。

使用 pod.spec.nodeSelector

  • 通过为节点和 Pod 设置 label,并使用 nodeSelector 选择具有特定 label 的节点,调度器会将 Pod 调度到匹配的节点上。
  • 为节点设置 label 的命令如下:
    kubectl label nodes node01 myname=a
    kubectl label nodes node02 myname=b
    
  • 在 Pod 定义中使用 nodeSelector 的 YAML 配置如下:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp1
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: myapp1
      template:
        metadata:
          labels:
            app: myapp1
        spec:
          nodeSelector:
            myname: a
          containers:
          - name: myapp1
            image: soscscs/myapp:v1
            ports:
            - containerPort: 80
    
  • 应用此配置后,Pod 会被调度到具有 label myname=a 的节点上(即 node01)。
修改和删除Label
  • 使用 kubectl label 命令修改和删除节点标签。
  • 修改节点的 label 需要使用 --overwrite 参数:
    kubectl label nodes node02 myname=a --overwrite
    
  • 删除节点的 label 只需在命令行最后指定 label 的 key 名,并在其后加上减号:
    kubectl label nodes node02 myname-
    
  • 可以使用 -l 参数根据 label 查询节点:
    kubectl get node -l myname=a
    

亲和性

亲和性概述

在 Kubernetes 中,亲和性(Affinity)和反亲和性(Anti-Affinity)用于定义 Pod 调度到节点的规则。主要分为两类:

  1. 节点亲和性(Node Affinity):定义 Pod 与节点的关系。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值