kubernetes调度

艺帆风顺 发布于 2025-04-02 16 次阅读


创建一个pod 的工作流程

kubectl run pod2 --image=nginx

1、kubectl向apiserver发起创建pod请求,apiserver将创建pod配置写入etcd

2、scheduler收到apiserver有新pod的事件,scheduler根据自身调度算法选择一个合适的节点,并打标记 pod=k8s-node1

3、kubelet收到分配到自己节点的pod,调用docker api创建容器,并获取容器状态汇报给apiserver

controller-manager  负责控制器的创建,例如deployment

kube-proxy 负责service的创建

1、requests:最小的申请值,limits:容器最大使用上限

2、requests 必须小于limits,小于limits 20%-30%(良性)

3、limits尽量不要超过宿主机实际物理配置,不然限制没意义

4、requests会影响pod调度,必须有节点能够满足该配置pod才能运行

5、requests只是一个预留性质,并非实际占用

requests值设置太大,会发生什么现象?节点资源空闲

requests值设置太小,会发生什么现象?节点资源紧张

Kubernetes基于list-watch机制的控制器架构,实现组件间交互的解耦。

其他组件监控自己负责的资源,当这些资源发生变化时, kubeapiserver会通知这些组件,这个过程类似于发布与订阅。

编辑

Pod中影响调度的主要属性

编辑

资源限制对Pod调度的影响

容器资源限制:

resources.limits.cpu

resources.limits.memory

容器使用的最小资源需求,作为容器调度时资源分配的依据:

resources.requests.cpu

resources.requests.memory

CPU单位:可以写m也可以写浮点数,例如0.5=500m, 1=1000m

编辑

nodeSelector & nodeAffinity的区别

nodeSelector: 

用于将Pod调度到匹配Label的Node上,如果没有匹配的标签会调度失败。

作用:

• 约束Pod到特定的节点运行

• 完全匹配节点标签

应用场景:

• 专用节点:根据业务线将Node分组管理

• 配备特殊硬件:部分Node配有SSD硬盘、 GPU

案例:确保Pod分配到具有SSD硬盘的节点上

第一步:给节点添加标签

格式:kubectl label nodes =

例如:kubectl label nodes k8s-node1 disktype=ssd

验证:kubectl get nodes --show-labels

#yaml文件

    apiVersion: v1kind: Podmetadata:name: my-podspec:nodeSelector:disktype: “ssd”containers:- name: nginximage: nginx:1.19

    第二步:添加nodeSelector字段到Pod配置中

    最后,验证:

    kubectl get pods -o wide

    删除节点标签:kubectl label node k8s-node1

    nodeAffinity: 

    节点亲和类似于nodeSelector,可以根据节点上的标签来约束Pod可以调度到哪些节点。

    相比nodeSelector

    • 匹配有更多的逻辑组合,不只是字符串的完全相等,支持的操作

    符有:In、 NotIn、 Exists、 DoesNotExist、 Gt、 Lt

    • 调度分为软策略和硬策略,而不是硬性要求

    • 硬(required):必须满足

    • 软(preferred):尝试满足,但不保证

    编辑


    Taint(污点)与Tolerations(污点容忍)

    基于节点标签分配是站在Pod的角度上,通过在Pod上添加属性,来确定Pod是否要调度到指定的Node上,其实我们也可以站在Node的角度上,通过在Node上添加污点属性,来避免Pod被分配到不合适的节点上。

    Taints: 避免Pod调度到特定Node上

    Tolerations: 允许Pod调度到持有Taints的Node上

    第一步:给节点添加污点

    格式:kubectl taint node [node] key=value:[effect]

    例如:kubectl taint node k8s-node1 gpu=yes:NoSchedule

    验证:kubectl describe node k8s-node1 |grep Taint

    其中[effect] 可取值:

    • NoSchedule :一定不能被调度

    • PreferNoSchedule:尽量不要调度,非必须配置容忍

    • NoExecute:不仅不会调度,还会驱逐Node上已有的Pod

    编辑

    编辑

    第二步:

    如果希望Pod可以被分配到带有污点的节点上,要在Pod配置

    中添加污点容忍(tolrations)字段

    删除污点:kubectl taint node [node] key:[effect]-

    nodeName:指定节点名称,用于将Pod调度到指定的Node上,不经过调度器。

    #yaml案例

      apiVersion: v1kind: Podmetadata:name: my-podspec:nodeName: k8s-node2containers:- name: webimage: nginx

      1、nodeselector与taint是分别独立,两者都用都必须满足

      2、这两个完美组合,指哪打哪

      3、如果加污点容忍,该pod会肯定分配到带有污点的节点上嘛?

      不会

      master节点为什么打污点?

      1、管理节点

      2、安全

      tolerations:

              # Make sure calico-node gets scheduled on all nodes.

              - effect: NoSchedule

                operator: Exists

              # Mark the pod as a critical add-on for rescheduling.

              - key: CriticalAddonsOnly

                operator: Exists

              - effect: NoExecute

                operator: Exists

      deployment特点:用镜像可以启动多个pod副本,一模一样,会分散到集群节点上。


      DaemonSet功能

      • 在每一个Node上运行一个Pod

      • 新加入的Node也同样会自动运行一个Pod

      应用场景:网络插件、监控Agent、日志Agent

      编辑

      示例:部署一个日志采集程序

      编辑

      调度失败原因分析

      #查看调度结果:

      kubectl get pod -o wide

      查看调度失败原因: kubectl describe pod

      节点CPU/内存不足

      有污点,没容忍

      没有匹配到节点标签

      1、多个pod副本如何统一对外提供服务?

      增加负载均衡器

      2、pod短暂的,如何保障这一组pod的准确性?

      可以指定pod ip、pod名称