Kubernetes学习之高级调度

本文详细介绍了Kubernetes调度器的工作原理,包括节点预选、节点优先级排序和节点选定三个步骤。此外,还探讨了节点亲和性和反亲和性,包括硬亲和性和软亲和性,以及Pod资源的亲和和反亲和性调度,展示如何通过标签选择器实现Pod的智能调度和分布。

一、认识Kubernetes调度器
  Kubernetes系统的核心任务在于创建客户端请求创建的Pod对象并确保其以期望的状态运行。创建Pod对象时,调度器(scheduler)负责为每一个未经调度的Pod资源、基于一系列的规则集从集群中挑选出一个合适的节点来运行它,因此它也可以称作Pod调度器。调度过程中,调度器不会修改Pod资源,而是从中读取数据,并根据配置的策略挑选出最适合的节点,而后通过API调用将Pod绑定至挑选出的节点之上以完成调度过程。
  在这里插入图片描述
  Kubernetes内建了适合绝大多数场景中Pod资源调度需求的默认调度器,它支持同时使用算法基于原生及可定制的工具来选出集群中最合适运行当前Pod资源的一个节点,其核心目标是基于资源可用性将各Pod资源公平地分布于集群节点之上。目前,平台提供的默认调度器也称为"通用调度器",它通过三个步骤完成调度操作:节点预选(Predicate)节点优先级排序(Priority)及节点择优(Select)。
在这里插入图片描述
  节点预选:基于一系列预选规则(如PodFitsResources和MatchNode-Selector等等)对每个节点进行检查,将那些不符合条件的节点过滤掉从而完成节点预选。
  节点优选:对预选出的节点进行优先级排序,以便选出最适合运行Pod对象的节点。
  节点选定:从优先级排序结果中挑出优先级最高的节点运行Pod对象,当此类节点多于一个时,则从中随机选择一个。

二、节点亲和性
  节点亲和性是调度程序用来确定Pod对象调度位置的一组规则,这些规则基于节点上的自定义标签和Pod对象上指定的标签选择器进行定义。节点亲和性允许Pod对象定义针对一组可以调度于其上的节点的亲和性或反亲和性,不过,它无法具体到某个特定的节点。例如,将Pod调度至有着特殊CPU的节点或一个可用区域内的节点之上。
  定义节点亲和性规则时有两种类型的节点亲和性规则:硬亲和性(required)软亲和性(preferred)。硬亲和性实现的是强制性规则,它是Pod调度时必须要满足的条件,而在不存在满足规则的节点时,Pod对象会被置为Pending状态。而软亲和性规则实现的是一种柔性调度限制,它倾向于将Pod对象运行于某类特定的节点之上,而调度器也将尽量满足此需求,但在无法满足调度需求时它将退而求其次地选择一个不匹配规则的节点。
  定义节点亲和性规则的关键点有两个,一是为节点配置合乎需求的标签,另一个是为Pod对象定义合理的标签选择器,从而能够基于标签选择出符合期望的目标节点。不过,如preferredDuringSchedulingIgnoreDuringExecution和requiredDuringSchedulingIgnoredDuringExecution名字中的后半段符串IgnoredDuringExecution隐含的意义所指,在Pod资源基于节点亲和性规则调度至某节点之后,节点标签发生了改变而不再符合此节点亲和性规则时,调度器不会将Pod对象从此节点上移出,因为,它仅对新建的Pod对象生效。
在这里插入图片描述

三、节点硬亲和性
  为Pod对象使用nodeSelector属性可以基于节点表现匹配的方式将Pod对象强制调度至某一类特定的节点之上,不过它仅能够基于简单的等值关系定义标签选择器,而nodeAffinity中支持使用matchExperssions属性构建更为复杂的标签选择机制。
  在定义节点亲和性时,requiredDuringSchedulingIgnoredDuringExecution字段的值是一个对象列表,用于定义节点硬亲和性,它可由一到多个nodeSelectorTerm定义的对象组成,彼此间为"逻辑或"的关系,进行匹配度检查时,在多个nodeSelectTerm之间只要满足其中之一即可。nodeSelectorTerm用于定义节点选择器条目,其值为对象列表,它可由一个或多个matchExpressions对象定义的匹配规则组成,多个规则彼此之间为"逻辑与"的关系,这就意味着某节点的标签需要完成匹配同一个nodeSelectorTerm下所有的matchExpression对象定义的规则才算成功通过节点选择器条目的检查。而matchExmpressions又可由一到多个标签选择器组成,多个标签选择器彼此间为"逻辑与"的关系。

1)编写创建Pod硬亲和性的yaml文件

]# cat required-nodeAffinity-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: with-required-nodeaffinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - {
   
   key: zone, operator: In, values: ["foo"] }
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
 
 ]# kubectl apply -f required-nodeAffinity-pod.yaml 
pod/with-required-nodeaffinity created

从配置清单文件中可以看到,其定义的Pod对象使用节点硬亲和性和规则定义可将当前Pod对象调度至拥有zone标签且其值为foo的节点之上。

2)查看Pod资源状态与详细信息

]# kubectl get pods -o wide 
NAME                         READY   STATUS    RESTARTS   AGE    IP       NODE     NOMINATED NODE   READINESS GATES
with-required-nodeaffinity   0/1     Pending   0          109s   <none>   <none>   <none>           <none>

]# kubectl describe pods with-required-nodeaffinity
Name:         with-required-nodeaffinity
Namespace:    default
Priority:     0
Node:         <none>
Labels:       <none>
Annotations:  Status:  Pending
IP:           
IPs:          <none>
Containers:
  myapp:
    Image:        ikubernetes/myapp:v1
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-47pch (ro)
Conditions:
  Type           Status
  PodScheduled   False 
Volumes:
  default-token-47pch:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-47pch
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason            Age        From               Message
  ----     ------            ----       ----               -------
  Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.
  Warning  FailedScheduling  <unknown>  default-scheduler  0/3 nodes are available: 3 node(s) didn't match node selector.

通过查看Pod状态只知,由其状态信息可知它一直处于Pending阶段,这是由于强制性的节点亲和限制场景中不存在能够满足匹配条件的节点所致的。

3)为节点添加标签

]# kubectl label node node1 zone=foo 
node/node1 labeled

]# kubectl label node node2 zone=bar
node/node2 labeled

]# kubectl label node node1 ssd=true 
node/node1 labeled

]# kubectl label node node2 ssd=true 
node/node2 labeled

]# kubectl get nodes --show-labels
NAME     STATUS   ROLES    AGE   VERSION   LABELS
master   Ready    master   66d   v1.18.5   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/master=
node1    Ready    <none>   66d   v1.18.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node1,kubernetes.io/os=linux,ssd=true,zone=foo
node2    Ready    <none>   66d   v1.18.5   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node2,kubernetes.io/os=linux,ssd=true,zone=bar

4)再次查看Pod资源状态

<think>我们正在讨论Kubernetes集群中的网络配置和调度机制。根据用户的问题,我们需要分别解释这两个核心机制。 首先,关于Kubernetes集群的网络配置,主要目标是确保Pod之间可以相互通信,无论它们位于哪个节点上。Kubernetes本身不提供网络实现,而是通过CNI(容器网络接口)插件来实现。常见的网络模型要求每个Pod拥有唯一的IP地址,并且这些IP地址在集群内是可达的。 其次,调度机制指的是Kubernetes如何将Pod分配到合适的节点上运行。调度器(kube-scheduler)负责根据资源需求、节点亲和性、污点与容忍等条件进行决策。 根据引用[1]和[2]的内容,我们可以了解到一些关于调度优化的实践,比如支持分布式训练的调度增强(如gang-scheduling)以及弹性调度(如自动扩缩容)。此外,引用[3]提到了在KubeSphere中部署Redis集群的实例,这涉及到存储卷的创建和应用的配置,但网络配置部分没有详细说明。 因此,我们将分为两个部分来回答:网络配置和调度机制。 ### Kubernetes集群网络配置 在Kubernetes中,网络配置需要满足以下基本要求: 1. 所有Pod之间可以在没有NAT的情况下相互通信。 2. 所有节点可以与所有Pod通信(反之亦然)。 3. Pod所看到的自己的IP地址与其他Pod看到的该Pod的IP地址是同一个。 网络模型通常由CNI插件实现,常见的插件包括: - Calico:基于BGP协议,提供高性能的网络和网络策略。 - Flannel:提供简单的覆盖网络,使用VXLAN或host-gw等后端。 - Weave Net:提供覆盖网络,支持加密通信。 此外,Kubernetes还支持网络策略(NetworkPolicy),用于控制Pod之间的网络流量。 ### Kubernetes调度机制 Kubernetes调度器负责为新创建的Pod选择一个合适的节点。调度过程分为两个阶段: 1. **过滤(Filtering)**:根据节点资源、污点(Taints)和Pod的容忍(Tolerations)等条件筛选出可用的节点。 2. **评分(Scoring)**:对过滤后的节点进行评分,选择最优节点(如资源最均衡的节点)。 调度器还支持高级调度特性: - **亲和性与反亲和性(Affinity/Anti-affinity)**:控制Pod与Pod、Pod与节点之间的亲和关系。 - **污点与容忍(Taints and Tolerations)**:允许节点排斥某些Pod,除非这些Pod明确声明容忍该污点。 - **Pod间亲和性(Inter-pod affinity)**:根据其他Pod的分布来调度Pod。 引用[1]中提到了一些优化,如gang-scheduling(确保一组Pod同时被调度)和弹性调度(根据工作负载动态调整资源)。这些优化通常通过自定义调度器或扩展默认调度器来实现。 ### 相关问题 1. 如何为Kubernetes集群选择合适的CNI插件? 2. Kubernetes调度器如何进行资源平衡? 3. 如何配置Kubernetes网络策略以增强安全性? 4. 在Kubernetes中如何实现跨节点的Pod通信? 5. 如何利用亲和性规则优化Pod的调度位置? 以上内容基于Kubernetes的一般知识,并结合了引用中提到的部分优化点。希望这些信息能帮助您理解Kubernetes的网络和调度机制。</think>### Kubernetes集群网络配置 Kubernetes集群的网络模型基于以下核心原则: 1. **Pod间直接通信**:所有Pod可不经NAT直接通信,无论是否在同一节点 2. **节点-Pod互通**:节点能与所有Pod直接通信(反之亦然) 3. **IP一致性**:Pod看到的自身IP与其他Pod看到的其IP一致 #### 关键网络组件 1. **CNI插件**(容器网络接口) Kubernetes通过CNI插件实现网络功能,常见方案包括: - Calico:基于BGP协议,支持网络策略 - Flannel:使用VXLAN或host-gw的简单覆盖网络 - Weave Net:提供加密通信的覆盖网络 ```mermaid graph LR A[Pod] -->|CNI插件| B[虚拟网桥] B --> C[主机网络] C --> D[其他节点] ``` 2. **服务发现** 通过`kube-proxy`实现: - iptables/IPVS模式:将Service的虚拟IP映射到后端Pod - CoreDNS:提供集群内服务域名解析(如`my-svc.default.svc.cluster.local`) 3. **网络策略** 使用NetworkPolicy对象实现微隔离: ```yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-db-access spec: podSelector: matchLabels: role: db ingress: - from: - podSelector: matchLabels: role: api-server ports: - protocol: TCP port: 5432 ``` ### Kubernetes调度机制 调度器(kube-scheduler)工作流程: ```mermaid sequenceDiagram participant A as API Server participant S as Scheduler participant N as Node A->>S: 新Pod创建事件 S->>S: 过滤(Filtering) S->>S: 评分(Scoring) S->>N: 绑定Pod到最优节点 ``` #### 核心调度策略 1. **基础调度** - 资源请求检查:确保节点满足Pod的CPU/Memory请求 - 节点选择器:`nodeSelector`匹配节点标签 2. **高级调度** - **亲和性/反亲和性**(Affinity/Anti-affinity): ```yaml affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: gpu-type operator: In values: [a100] ``` - **污点与容忍**(Taints and Tolerations): ```bash # 给节点添加污点 kubectl taint nodes node1 key=value:NoSchedule ``` ```yaml # Pod声明容忍 tolerations: - key: "key" operator: "Equal" value: "value" effect: "NoSchedule" ``` 3. **调度优化扩展** - **Gang调度**:确保关联Pod组同时调度(如MPI作业)[^1] - **弹性调度**:基于工作负载动态调整资源分配[^1] - **拓扑感知**:优化跨可用区/机架的Pod放置 ### 典型应用场景 1. **分布式训练优化** 如Dragon系统通过增强调度器支持: - Gang调度避免资源死锁 - 位置感知放置减少网络延迟 - 自动扩缩容应对计算波动[^1] 2. **有状态应用部署** 参考Redis-Cluster部署案例[^3]: - 使用StatefulSet保障Pod稳定网络标识 - 通过Headless Service实现直接Pod访问 - 存储卷动态供给保证数据持久化 ### 相关问题 1. 如何选择适合AI工作负载的Kubernetes CNI插件? 2. Kubernetes调度器如何处理资源碎片化问题? 3. 如何实现跨多个可用区的Kubernetes网络配置? 4. 在Kubernetes中如何优化深度学习训练任务的任务调度? 5. 如何通过NetworkPolicy实现微服务间的零信任网络? [^1]: 弹性调度框架通过SideCar进程实现GPU动态重分配,支持分布式训练工作负载的gang-scheduling和位置感知放置优化 [^2]: Pod作为基础调度单元,通过Service抽象提供网络访问入口 [^3]: Redis-Cluster部署展示了有状态应用的网络配置和存储卷管理实践
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值