K8s的资源调度

K8s整体架构

Kubernetes属于主从分布式架构,主要由Master Node和Worker Node,以及客户端命令行工具kubectl等附加项组成。

  • Master Node:作为控制节点,对集群进行调度管理; Master Node由API Server、Scheduler、Cluster State Store和controller manager server组成;

  • Worker Node:作为真正的工作节点,是运行业务应用的容器; Worker Node包括kubelet、kube proxy和Container Runtime;

  • kubectl:用于通过命令行与API Server交互,操作Kubernetes,对集群中的各种资源进行增删改查;

  • Add on:是对Kubernetes核心功能的扩展,比如增加网络和网络策略能力。

  • Replication 用于缩放副本数量

  • 端点用于管理网络请求

  • 调度器调度器

典型流程

创建Pod的整个过程如下:

1、用户可以通过API Server的REST API或者Kubectl命令行工具提交创建Pod的请求,支持Json和Yaml两种格式;

2、API Server处理用户请求,将Pod数据存储到Etcd;

  1. schedule 通过 API Server 的 watch 机制查看新的 Pod,并尝试为 Pod 绑定 Node;

4.过滤主机:调度器使用一组规则过滤掉不合格的主机。比如Pod指定了需要的资源,它必须过滤掉资源不足的主机;

5.主机评分:对第一步选出的合格主机进行评分。在主机评分阶段,调度器会考虑一些整体的优化策略,比如将一份 Replication Controller 分配给不同的主机,使用负载最低的主机等;

6、选择主机:选择得分最高的主机,进行绑定,并将结果存入Etcd;

7、kubelet根据调度结果进行pod创建:绑定成功后会启动容器和docker run,调度器会调用API Server的API在etcd中创建一个绑定的pod对象来描述所有的pod信息在工作节点上绑定并运行。运行在每个工作节点上的 kubelet 也会定期将绑定的 pod 信息与 etcd 同步。一旦发现应该在工作节点上运行的绑定的 pod 对象没有更新,就会调用 Docker API 在 pod 中创建并启动容器。

节点选择器

nodeSelector 是最简单的约束方式。 nodeSelector 是 pod spec 的一个字段

使用--show labels查看指定节点的标签

[root@master ~]# kubectl 获取节点 node1.example.com --show-labels

名称状态角色年龄版本标签

node1.example.com 就绪 <none> 4d6h v1.23.1 beta.kubernetes.io/archu003damd64,beta.kubernetes.io/osu003dlinux,kubernetes.io/archu003damd64,kubernetes.io/hostnameu003dnode1。 example.com,kubernetes.io/osu003dlinux

如果没有添加额外的节点标签,您将看到如上所示的默认标签。我们可以通过 kubectl label node 命令给指定节点添加标签:

[root@master ~]# kubectl 标签节点 node1.example.com disktypeu003dssd

节点/node1.example.com 标记

[root@master ~]# kubectl 获取节点 node1.example.com --show-labels

名称状态角色年龄版本标签

node1.example.com 就绪 <none> 4d6h v1.23.1 beta.kubernetes.io/archu003damd64,beta.kubernetes.io/osu003dlinux,disktypeu003dssd,kubernetes.io/archu003damd64,kubernetes.io/主机名u003dnode1.example.com,kubernetes.io/osu003dlinux

当然也可以通过 kubectl label node 删除指定的标签

[root@master ~]# kubectl label node node1.example.com disktype-

node/node1.example.com 未标记

[root@master ~]# kubectl 获取节点 node1.example.com --show-labels

名称状态角色年龄版本标签

node1.example.com 就绪 <none> 4d6h v1.23.1 beta.kubernetes.io/archu003damd64,beta.kubernetes.io/osu003dlinux,kubernetes.io/archu003damd64,kubernetes.io/hostnameu003dnode1。 example.com,kubernetes.io/osu003dlinux

创建一个测试 pod 并指定 nodeSelector 选项来绑定节点:

[root@master ~]# kubectl 标签节点 node1.example.com disktypeu003dssd

节点/node1.example.com 标记

[root@master ~]# kubectl 获取节点 node1.example.com --show-labels

名称状态角色年龄版本标签

node1.example.com 就绪 <none> 4d6h v1.23.1 beta.kubernetes.io/archu003damd64,beta.kubernetes.io/osu003dlinux,disktypeu003dssd,kubernetes.io/archu003damd64,kubernetes.io/主机名u003dnode1.example.com,kubernetes.io/osu003dlinux

[root@master ~]# vi test.yml

[root@master ~]# cat test.yml

api版本:v1

种类:豆荚

元数据:

名称:测试

标签:

环境:测试

规格:

容器:

  • 名称:测试

图片:nginx

imagePullPolicy: IfNotPresent

节点选择器:

磁盘类型:ssd

检查 pod 调度的节点。 test 将 pod 强制调度到标签为 disktypeu003dssd 的节点上。

[root@master ~]# kubectl 获取 pod -o 宽

名称就绪状态重新启动年龄 IP 节点提名节点就绪门

httpd1-57c7b6f7cb-sk86h 1/1 运行 4 (173m 前) 2d 10.244.1.93 node2.example.com <none> <none>

nginx1-7cf8bc594f-8j8tv 1/1 运行 1(173m 前)3h40m 10.244.1.94 node2.example.com <none> <none>

节点亲和性

nodeAffinity 表示节点亲和性调度策略。是替代nodeSelector的新调度策略。目前有两种节点亲和度表达方式:

RequiredDuringSchedulingIgnoredDuringExecution:

必须满足规则才能将 pod 调度到节点。相当于硬限制

PreferredDuringSchedulingIgnoreDuringExecution:

强调要优先满足既定规则。调度器会尝试将 pod 调度到 Node 上,但不是强制的,相当于软限制。多个优先级规则还可以设置权重值来定义执行顺序。

执行期间忽略意味着:

如果 Pod 所在节点的标签在 Pod 运行过程中发生变化,不满足 Pod 的节点亲和性要求,系统会忽略该节点上的标签变化,Pod 可以运行在机器节点。

NodeAffinity 语法支持的运算符包括:

  • In:label的值是In a list

  • NotIn:标签的值不在列表中

  • Exists:标签存在

  • DoesNotExit:标签不存在

  • gt:label的值大于某个值

  • Lt:label的值小于某个值

nodeAffinity规则设置注意事项如下:

如果同时定义了 nodeSelector 和 nodeAffinity,则 name 必须同时满足这两个条件,pod 才能最终在指定节点上运行。

如果 nodeasffinity 指定了多个 nodeSelectorTerms,其中一个可以匹配成功。

如果 nodeSelectorTerms 中有多个 matchExpressions,则一个节点必须满足所有 matchExpressions 才能运行 Pod。

api版本:v1

种类:豆荚

元数据:

名称:test1

标签:

应用程序:nginx

规格:

容器:

  • 名称:test1

图片:nginx

imagePullPolicy: IfNotPresent

亲和力:

节点亲和性:

requiredDuringSchedulingIgnoredDuringExecution: # 硬策略

节点选择器条款:

  • 匹配表达式:
  • 键:磁盘类型

价值观:

  • 固态硬盘

运算符:在

preferredDuringSchedulingIgnoredDuringExecution: # 软策略

  • 重量:10

偏好:

匹配表达式:

  • 键:名称

价值观:

  • 测试

运算符:在

使用 disktypeu003dssd 标记 node2

[root@master ~]# kubectl 标签节点 node2.example.com disktypeu003dssd

节点/node2.example.com 标记

[root@master ~]# kubectl 获取节点 node2.example.com --show-labels

名称状态角色年龄版本标签

node2.example.com 就绪 <none> 4d7h v1.23.1 beta.kubernetes.io/archu003damd64,beta.kubernetes.io/osu003dlinux,disktypeu003dssd,kubernetes.io/archu003damd64,kubernetes.io/主机名u003dnode2.example.com,kubernetes.io/osu003dlinux

给node1加上nameu003dtest的标签,删除nameu003dtest的标签,查看测试结果

[root@master ~]# kubectl 标签节点 node1.example.com nameu003dtest

节点/node1.example.com 标记

[root@master ~]# kubectl 获取节点 node1.example.com --show-labels

名称状态角色年龄版本标签

node1.example.com 就绪 <none> 4d7h v1.23.1 beta.kubernetes.io/archu003damd64,beta.kubernetes.io/osu003dlinux,disktypeu003dssd,kubernetes.io/archu003damd64,kubernetes.io/主机名u003dnode1.example.com,kubernetes.io/osu003dlinux,nameu003dtest

[root@master ~]# kubectl apply -f test.yml

pod/测试已创建

[root@master ~]# kubectl 获取 pod -o 宽

名称就绪状态重新启动年龄 IP 节点提名节点就绪门

httpd1-57c7b6f7cb-sk86h 1/1 运行 4(178m 前)2d 10.244.1.93 node2.example.com <none> <none>

nginx1-7cf8bc594f-8j8tv 1/1 运行 1(178m 前)3h45m 10.244.1.94 node2.example.com <none> <none>

测试 1/1 运行 0 13s 10.244.1.95 node2.example.com <none> <none>

删除node1上nameu003dtest的标签

[root@master ~]# kubectl 标签节点 node1.example.com 名称-

node/node1.example.com 未标记

[root@master ~]# kubectl 获取 pod -o 宽

名称就绪状态重新启动年龄 IP 节点提名节点就绪门

httpd1-57c7b6f7cb-sk86h 1/1 运行 4(179m 前)2d1h 10.244.1.93 node2.example.com <none> <none>

nginx1-7cf8bc594f-8j8tv 1/1 运行 1(179m 前)3h46m 10.244.1.94 node2.example.com <none> <none>

测试 1/1 运行 0 44s 10.244.1.95 node2.example.com <none> <none>

上面的 pod 首先需要在标签为 disktypeu003dssd 的节点上运行。如果有多个带有这个标签的节点,最好在nameu003dtest的标签上创建

污点和加速度

污点:避免点调度到特定节点

加速:允许 Pod 被调度到持有 Taints 的节点

应用场景:

  • Private Node:按业务线对节点进行分组管理。希望这个Node不会被默认调度。仅当配置了污点容限时才允许分配

  • 配备特殊硬件:部分节点配备SSD、硬盘和GPU。希望Node不会被默认调度。仅在配置了污点容差时才允许分配

  • 基于污点的驱逐

# 污点(污点)

[root@master haproxy]# kubectl 描述节点主节点

名称:master.example.com

角色:控制平面、主控

标签:beta.kubernetes.io/archu003damd64

beta.kubernetes.io/osu003dlinux

kubernetes.io/archu003damd64

kubernetes.io/hostnameu003dmaster.example.com

kubernetes.io/osu003dlinux

节点角色.kubernetes.io/control-planeu003d

节点角色.kubernetes.io/masteru003d

node.kubernetes.io/exclude-from-external-load-balancersu003d

注释:flannel.alpha.coreos.com/backend-data: {"VNI":1,"VtepMAC":"8e:50:ba:7a:30:2b"}

flannel.alpha.coreos.com/backend-type: vxlan

flannel.alpha.coreos.com/kube-subnet-manager: true

flannel.alpha.coreos.com/public-ip: 192.168.240.30

kubeadm.alpha.kubernetes.io/cri-socket:/var/run/dockershim.sock

node.alpha.kubernetes.io/ttl:0

volumes.kubernetes.io/controller-managed-attach-detach: true

创建时间戳:2021 年 12 月 19 日星期日 02:41:49 -0500

Taints: node-role.kubernetes.io/master:NoSchedule #aints: 避免 Pod 调度到特定节点

不可调度:假

Tolerances(污渍容限)

[root@master ~]# kubectl 描述 pod httpd1-57c7b6f7cb-sk86h

名称:httpd1-57c7b6f7cb-sk86h

命名空间:默认

·····

Tolerations: node.kubernetes.io/not-ready:NoExecute opu003dExists for 300s

node.kubernetes.io/unreachable:NoExecute opu003dExists for 300s # Blemishes tolerance 允许 Pod 调度到持有 Taints 的节点

活动:

从消息中输入原因年龄


Warning FailedCreatePodSandBox 12m kubelet Failed to create pod sandbox: rpc error: code u003d Unknown desc u003d failed to set up sandbox container "2126da4117ba6ce45ddff8a2e0b9de59bac65f05c7be343249d50edea2cacf37" network for pod "httpd1-57c7b6f7cb-sk86h": networkPlugin cni failed to set up pod "httpd1-57c7b6f7cb -sk86h_default" 网络:打开/run/flannel/subnet.env:没有这样的文件或目录

警告 FailedCreatePodSandBox 12m kubelet 无法创建 pod "best2001/httpd"

正常拉取11m kubelet 16.175310708s成功拉取镜像“best2001/httpd”

正常创建 11m kubelet 创建容器 httpd1

正常启动 11m kubelet 启动容器 httpd1

节点添加污点

格式:kubectl taint node [node] keyu003dvalue:[effect]

例如:kubectl taint node k8s-node1 gpuu003dyes:NoSchedule 验证:kubectl describe node k8s-node1 |grep Taint

其中 [effect] 可以被视为:

  • NoSchedule:不能被调度

  • PreferNoSchedule:尽量不要调度。必须配置公差

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

将污点容差字段添加到 Pod 配置

# 添加污点disktype类型

[root@master haproxy]# kubectl taint node node1.example.com disktype:NoSchedule

node/node1.example.com 被污染

[root@master haproxy]# kubectl 描述节点 node1.example.com

名称:node1.example.com

角色:<无>

标签:beta.kubernetes.io/archu003damd64

beta.kubernetes.io/osu003dlinux

kubernetes.io/archu003damd64

kubernetes.io/hostnameu003dnode1.example.com

kubernetes.io/osu003dlinux

注释:flannel.alpha.tsoreos.tsum/backend-date: {"ВНИ":1,"Втепмац":"12:яе:чз:яя:21:бд"}

flannel.alpha.coreos.com/backend-type: vxlan

flannel.alpha.coreos.com/kube-subnet-manager: true

flannel.alpha.coreos.com/public-ip: 192.168.240.50

kubeadm.alpha.kubernetes.io/cri-socket:/var/run/dockershim.sock

node.alpha.kubernetes.io/ttl:0

volumes.kubernetes.io/controller-managed-attach-detach: true

创建时间戳:2021 年 12 月 19 日星期日 03:27:16 -0500

Taints: disktype:NoSchedule #Stain 添加成功

测试创建一个pod

[root@master haproxy]# kubectl apply -f nginx.yml

部署.apps/nginx1 创建

服务/nginx1 创建

[root@master haproxy]# kubectl 获取 pods -o wide

名称就绪状态重新启动年龄 IP 节点提名节点就绪门

nginx1-7cf8bc594f-8j8tv 1/1 Running 0 14s 10.244.1.92 node2.example.com <none> <none> #因为node1上有污点,所以创建的容器会在node2上运行

去除污渍:

kubectl taint node [node] key:[effect]-

[root@master haproxy]# kubectl taint node node1.example.com disktype-

node/node1.example.com 未受污染

[root@master haproxy]# kubectl 描述节点 node1.example.com

名称:node1.example.com

角色:<无>

标签:beta.kubernetes.io/archu003damd64

beta.kubernetes.io/osu003dlinux

kubernetes.io/archu003damd64

kubernetes.io/hostnameu003dnode1.example.com

kubernetes.io/osu003dlinux

注释:flannel.alpha.tsoreos.tsum/backend-date: {"ВНИ":1,"Втепмац":"12:яе:чз:яя:21:бд"}

flannel.alpha.coreos.com/backend-type: vxlan

flannel.alpha.coreos.com/kube-subnet-manager: true

flannel.alpha.coreos.com/public-ip: 192.168.240.50

kubeadm.alpha.kubernetes.io/cri-socket:/var/run/dockershim.sock

node.alpha.kubernetes.io/ttl:0

volumes.kubernetes.io/controller-managed-attach-detach: true

创建时间戳:2021 年 12 月 19 日星期日 03:27:16 -0500

Taints: <none> # 污点已成功删除

不可调度:假

Logo

云原生社区为您提供最前沿的新闻资讯和知识内容

更多推荐