k8s节点调度

调度算法

在这里插入图片描述


node标签

# 查看节点标签
kubectl get node --show-labels=true

# 添加标签 key=value
kubectl label nodes node1 node=node1

# 去除标签 key-
kubectl label nodes node1 node-

node标签选择器

如果同时指定了 nodeSelectornodeAffinity,两者必须都要满足, 才能将 Pod 调度到候选节点上。
如果指定了多个与 nodeAffinity 类型关联的 nodeSelectorTerms,满足一个 nodeSelectorTerms ,pod将可以调度到节点上。
指定了多个与 nodeSelectorTerms 关联的 matchExpressions,满足所有 matchExpressions ,Pod 才会可以调度到节点上。
由于IgnoredDuringExecution,改变labels不会影响已运行的pod.

在这里插入图片描述


nodeSelector

参考: 将 Pod 分配给节点

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  # 选择node标签为disktype=ssd的node  
  nodeSelector:
    disktype: ssd

Node亲和性调度affinity

理解 Kubernetes 的亲和性调度

官方doc-节点亲和性

K8S高级调度方式

requiredDuringSchedulingIgnoredDuringExecution: 硬策略/硬需求–必须满足
preferredDuringSchedulingIgnoredDuringExecution: 软策略/软需求–尽量满足

支持的操作符有:
In , 包含
NotIn , 不包含,一般用来做反亲和(Anti-Affinity)
Exists , 存在
DoesNotExist ,不存在
Gt , (greater than), label 的值大于某个值,int类型
Lt , (less than),label 的值小于某个值,int类型
在这里插入图片描述

name in( redis-master, redis-salve)# 匹配所有带有标签name=master或者name=salve的资源

name not in ( php)#匹配所有不具有标签name=php的资源对象

亲和度示例yaml

pod 亲和性 的示例

apiVersion: v1
kind: Pod
metadata:
  name: myapp
  labels:
    name: myapp
spec:
# 亲和性
  affinity:
    # 节点亲和度
    nodeAffinity:
      # 硬策略/硬需求
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
          - matchExpressions:
              # 匹配所有带有标签disktype=ssd或者disktype=shd的资源
              - key: disktype
                operator: In
                values:
                  - ssd
                  - shd
      # 软策略/软需求(尽量匹配标签的资源,不满足时会找其他的资源)
      preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1  # 权重值/(加分项,1-100,100是最高分),能提高匹配概率,不用太关注
          preference:  # 固定语法,意为偏爱
            matchExpressions:
              # 尽可能匹配标签为disktye=ssd2的资源
              - key: disktype
                operator: In
                values:
                  - ssd2
  containers:
  - name: myapp
    image: <Image>
    resources:
      limits:
        memory: "128Mi"
        cpu: "500m"
    ports:
      - containerPort: <Port>

nodeName

参考: pod 调度到一个指定节点

nodeName不会通过调度器,即使node有污点也能直接运行pod.一般用于测试.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  nodeName: node1 # 让pod运行在指定node上,nodeName不会通过调度器
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent

node污点与容忍

参考: 官方污点文档

三只兔子的故事来了解k8s污点与容忍

为什么Node要使用污点:

  • 安全考虑
  • Node职责角色分工不同
  • 硬件不同

污点也类似于在node上打一个标签.例如专用节点,比如GPU,SSD等,一般pod不会运行在这种专用节点,如果pod想运行在这种专用节点上,需要配置污点容忍.

Taint: 污点,避免pod调度到特定Node上,相当于排斥Pod
Tolerations: 污点容忍,允许pod调度到带有特定Taints的Node上


污点容忍yaml示例

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
    - name: nginx
      image: nginx
      imagePullPolicy: IfNotPresent
  # 污点容忍
  tolerations:
    # 容忍key=example-key 等effect值存在NoSchedule
    - key: "example-key"
      operator: "Exists"
      # value: "example-value"  # 可不配置
      effect: "NoSchedule"

容忍放大

k8s的一些基础静态pod,比如apiserver,配置的就是容忍放大,下方是示例
容忍放大,只要keyeffect存在即容忍.

apiVersion: v1
kind: Pod
metadata:
  name: apiserver
  labels:
    env: test
spec:
  containers:
    - name: apiserver
      image: apiserver
      imagePullPolicy: IfNotPresent
  # 污点容忍
  tolerations:
    # 容忍所有effect值为NoSchedule的污点
    - effect: NoSchedule
      operator: Exists
    # 容忍污点key值CriticaAddonsOnly存在
    - key: CriticaAddonsOnly
      operator: Exists
    # 容忍所有effect值为NoExecute的污点
    - effect: NoExecute
      operator: Exists

基于污点的驱逐

参考: 官方文档

kubelet 驱逐策略详解

污点的 effect 值 NoExecute会影响(驱逐)已经在节点上运行的 Pod,如果Pod没有配置容忍 effect 值为 NoExecute 的污点,会被立即驱逐.

Pod配置了容忍NoExecute,但在容忍度定义中没有指定 tolerationSeconds(宽限期),则 Pod 还会一直在这个节点上运行。

Pod配置了容忍NoExecute,,而且指定了 tolerationSeconds(宽限期), 则 Pod 还能在这个节点上继续运行这个指定的时间长度。

节点故障时,节点控制器会自动给节点添加一个(内置)污点.如果异常状态恢复正常,kubelet 或节点控制器能够移除相关的污点。


effect标记值

effect标记值

  • NoSchedule 不会将 Pod 分配到该节点(不驱逐已运行pod)
  • PreferNoSchedule 尽量不将 Pod 分配到该节点(不驱逐已运行pod)
  • NoExecute 不会将 Pod 分配到该节点,还会将 已运行Pod 从该节点驱逐

查看污点

对于k8s1.24+,master节点将不再添加node-role.kubernetes.io/master 标签, 只会添加node-role.kubernetes.io/control-plane标签。更多信息请参考 KEP-2067:重命名 kubeadm “master” 标签和污点。
https://kubernetes.io/zh-cn/blog/2022/04/07/upcoming-changes-in-kubernetes-1-24/

# 查看污点
kubectl describe nodes node名 |grep Taints
# Taints:   node.kubernetes.io/unreachable:NoSchedule

在这里插入图片描述


添加污点

# 添加污点
kubectl taint nodes node名 key=value:effect值

## effect是标记值
kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:PreferNoSchedule

# 给master1机器加NoSchedule污点--k8s1.23
kubectl taint nodes m1 node-role.kubernetes.io/control-plane:NoSchedule

在这里插入图片描述


删除污点

# 去除污点
kubectl taint nodes node名 key:effec值-
## 或 
kubectl taint nodes node名 key=value-
## 建议
kubectl taint nodes node名 key-

在这里插入图片描述


设置master调度


设置master尽量不调度

尽量不调度的污点PreferNoSchedule;
禁止调度并驱逐的污点NoExecute

# master添加 尽量不调度 PreferNoSchedule 
kubectl taint nodes k8s-master02 node-role.kubernetes.io/master:PreferNoSchedule

允许master节点调度pod

# 去除污点NoSchedule,最后一个"-"代表删除污点

# 允许所有master节点调度pod
kubectl taint nodes --all node-role.kubernetes.io/master-

# 允许master2节点调度pod;
kubectl taint nodes k8s-master02 node-role.kubernetes.io/master:NoSchedule-

恢复Master Only状态

参考: https://cloud.tencent.com/developer/article/1788356

# 指定master1为Only状态(加污点,不允许pod调度)
kubectl taint node maser1 node-role.kubernetes.io/master="":NoSchedule

将node标记为不可调度状态(节点警戒)

# 将node标记为不可调度状态(节点警戒)
kubectl cordon node名

设置node不可用并驱逐节点上的所有pod(腾空节点)

当节点磁盘空间不足时,Pod被驱逐的顺序为: BestEffort先于 Burstable

# 切换到名为ek8s的集群
kubectl config use-context ek8s

# 查看node状态
kubectl get nodes

# 设置节点不可用并驱逐节点上的所有pod(腾空节点)
## 节点排水(驱逐节点上的所有pod)
## 忽略节点上不能杀死的特定系统Pod,例如:CNI插件,daemonSet
## --delete-local-data 清空本地数据
## --ignore-daemonsets 忽略daemonsets错误
## --force 强制执行
kubectl drain ek8s-node-1 --ignore-daemonsets --force # 考试执行
## 如果报错,加--delete-local-data 清空本地数据
kubectl drain ek8s-node-1 --delete-local-data --ignore-daemonsets --force # 练习执行

# 查看node状态
kubectl get nodes

# 查看污点
kubectl describe nodes node名 |grep Taints
# Taints:   node.kubernetes.io/unreachable:NoSchedule

设置node为可用

# 标记my-node 节点为可以调度
kubectl uncordon node名

# 取消污点
## 如果已存在具有指定键和效果的污点,则替换其值为指定值。
kubectl taint nodes node名 dedicated=special-user:NoSchedule

# 去除污点NoSchedule,最后一个"-"代表删除
kubectl taint nodes node名 node-role.kubernetes.io/master:NoSchedule-

# 查看污点是否去除
kubectl describe nodes node名 |grep Taints

node调度故障诊断排查

# 显示给定节点的度量值                                            
kubectl top node my-node                                             

# 显示主控节点和服务的地址
kubectl cluster-info

# 将当前集群状态转储到标准输出                                                  
kubectl cluster-info dump

# 将当前集群状态输出到 /path/to/cluster-state                                            
kubectl cluster-info dump --output-directory=/path/to/cluster-state   

常见调度失败原因

  • CPU不足
  • 没有匹配到节点标签
  • 所有的节点有污点,但你没有配置污点容忍

pod一直是pending

参考: https://cloud.tencent.com/document/product/457/42948

当Pod处在Pending的时候,可能是由于如下哪个问题造成的。
资源不足,造成无法调度;
Pod尚未进入调度阶段;
Pod正在拉取镜像;
看kubelet日志.

# 查看pod详情
kubectl describe po pod名
## 显示pod已经调度到node2,但一直是pending

查看node资源是否足够
# 查看node资源是否足够
kubectl describe node <node-name>

# 或kubectl top node

在返回信息中,请注意关注以下内容:
Allocatable:表示此节点能够申请的资源总和。
Allocated resources:表示此节点已分配的资源(Allocatable 减去节点上所有 Pod 总的 Request)。

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

识途老码

赞赏是第一生产力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值