pod调度策略
- 上篇的知识补充
-
- Pod镜像拉取策略
- Pod资源限制
- Pod重启机制
- Pod健康检查
- Pod调度策略
-
- 创建Pod流程
- 节点亲和性
-
- node 节点亲和性调度:nodeAffinity
- 写在最后
上篇的知识补充
Pod镜像拉取策略
我们以具体实例来说,拉取策略就是 imagePullPolicy
拉取策略主要分为了以下几种
- IfNotPresent:默认,镜像在宿主机上不存在才拉取
- Always:每次创建Pod都会重新拉取一次镜像
- Never:Pod永远不会主动拉取这个镜像
Pod资源限制
也就是我们Pod在进行调度的时候,可以对调度的资源进行限制,例如我们限制 Pod调度是使用的资源是 2C4G,那么在调度对应的node节点时,只会占用对应的资源,对于不满足资源的节点,将不会进行调度
这里分了两个部分
- request:表示调度所需的资源
- limits:表示最大所占用的资源
Pod重启机制
因为Pod中包含了很多个容器,假设某个容器出现问题了,那么就会触发Pod重启机制
重启策略主要分为以下三种
- Always:当容器终止退出后,总是重启容器,用在nginx等,需要不断提供服务的情况。
- OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。
- Never:当容器终止退出,从不重启容器,适用于批量任务(只执行一次的任务)。
Pod健康检查
通过容器检查,原来我们使用下面的命令来检查
kubectl get pod
但是有的时候,程序可能出现了 Java 堆内存溢出,程序还在运行,但是不能对外提供服务了,这个时候就不能通过 容器检查来判断服务是否可用了
这个时候就可以使用应用层面的检查
存活检查,如果检查失败,将杀死容器,根据Pod的restartPolicy【重启策略】来操作
livenessProbe
就绪检查,如果检查失败,Kubernetes会把Pod从Service endpoints中剔除
readinessProbe
Pod调度策略
Pod 是 Kubernetes 中最基本的部署调度单元,可以包含 container,逻辑上表示某种应用的一个实例。例如一个 web 站点应用由前端、后端及数据库构建而成,这三个组件将运行在各自的容器中,那么我们可以创建包含三个 container 的 pod。
创建Pod流程
- 首先创建一个pod,然后创建一个API Server 和 Etcd【把创建出来的信息存储在etcd中】
客户端提交创建 Pod 的请求,可以通过调用 API Server 的 Rest API 接口,也可以通过 kubectl 命令行工具。如 kubectl apply -f filename.yaml(资源清单文件)
apiserver 接收到 pod 创建请求后,会将 yaml 中的属性信息(metadata)写入 etcd。
apiserver 触发 watch 机制准备创建 pod,信息转发给调度器 scheduler,调度器使用调度算法选择 node,调度器将 node 信息给 apiserver,apiserver 将绑定的 node 信息写入 etcd.
- 然后创建 Scheduler,监控API Server是否有新的Pod,如果有的话,会通过调度算法,把pod调度某个node上
调度器用一组规则过滤掉不符合要求的主机。比如 Pod 指定了所需要的资源量,那么可用资源比 Pod 需 要的资源量少的主机会被过滤掉。
scheduler 查看 k8s api ,类似于通知机制。
首先判断:pod.spec.Node == null? 若为 null,表示这个 Pod 请求是新来的,需要创建;因此先进行调度计算,找到最“闲”的 node。
然后将信息在 etcd 数据库中更新分配结果:pod.spec.Node = nodeA (设置一个具体的节点) ps:同样上述操作的各种信息也要写到 etcd 数据库中
- 在node节点,会通过 kubelet -- apiserver 读取etcd 拿到分配在当前node节点上的pod,然后通过docker创建容器
apiserver 又通过 watch 机制,调用 kubelet,指定 pod 信息,调用 Docker API 创建并启动 pod 内的容器。
创建完成之后反馈给 kubelet, kubelet 又将 pod 的状态信息给 apiserver, apiserver 又将 pod 的状态信息写入 etcd。
master 节点:kubectl -> kube-api -> kubelet -> CRI 容器环境初始化
节点亲和性
节点亲和性 nodeAffinity 和 之前nodeSelector 基本一样的,根据节点上标签约束来决定Pod调度到哪些节点上
- 硬亲和性:约束条件必须满足
- 软亲和性:尝试满足,不保证
支持常用操作符:in、NotIn、Exists、Gt、Lt、DoesNotExists
反亲和性:就是和亲和性刚刚相反,如 NotIn、DoesNotExists等
node 节点亲和性调度:nodeAffinity
[root@k8smaster ~]# kubectl explain pods.spec.affinity KIND: Pod VERSION: v1 RESOURCE: affinity <Object> DESCRIPTION: If specified, the pod's scheduling constraints Affinity is a group of affinity scheduling rules. FIELDS: nodeAffinity <Object> podAffinity <Object> podAntiAffinity <Object> [root@k8smaster ~]# kubectl explain pods.spec.affinity.nodeAffinity KIND: Pod VERSION: v1 RESOURCE: nodeAffinity <Object> DESCRIPTION: Describes node affinity scheduling rules for the pod. Node affinity is a group of node affinity scheduling rules. FIELDS: preferredDuringSchedulingIgnoredDuringExecution <[]Object> requiredDuringSchedulingIgnoredDuringExecution <Object> prefered 表示有节点尽量满足这个位置定义的亲和性,这不是一个必须的条件,软亲和性 require 表示必须有节点满足这个位置定义的亲和性,这是个硬性条件,硬亲和性 [root@k8smaster ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution KIND: Pod VERSION: v1 RESOURCE: requiredDuringSchedulingIgnoredDuringExecution <Object> DESCRIPTION: FIELDS: nodeSelectorTerms <[]Object> -required- Required. A list of node selector terms. The terms are ORed. [root@k8smaster ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSe lectorTerms KIND: Pod VERSION: v1 RESOURCE: nodeSelectorTerms <[]Object> DESCRIPTION: Required. A list of node selector terms. The terms are ORed. A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. FIELDS: matchExpressions <[]Object> matchFields <[]Object> matchExpressions:匹配表达式的 matchFields: 匹配字段的 [root@k8smaster ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSe lectorTerms.matchFields KIND: Pod VERSION: v1 RESOURCE: matchFields <[]Object> DESCRIPTION: FIELDS: key <string> -required- values <[]string> [root@k8smaster ~]# kubectl explain pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions KIND: Pod VERSION: v1 RESOURCE: matchExpressions <[]Object> DESCRIPTION: FIELDS: key <string> -required- operator <string> -required- values <[]string> key:检查 label operator:做等值选则还是不等值选则 values:给定值 例 1:使用 requiredDuringSchedulingIgnoredDuringExecution 硬亲和性 在node1和2用docker拉取nginx镜像 [root@k8smaster ~]# vim pod-nodeaffinity-demo.yaml apiVersion: v1 kind: Pod metadata: name: pod-node-affinity-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: nginx affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: zone operator: In values: - foo - bar 我们检查当前节点中有任意一个节点拥有 zone 标签的值是 foo 或者 bar,就可以把 pod 调度到这个 node 节点的 foo 或者 bar 标签上的节点上 [root@k8smaster ~]# kubectl apply -f pod-nodeaffinity-demo.yaml [root@k8smaster ~]# kubectl get pods -o wide | grep pod-node pod-node-affinity-demo 0/1 Pending 0 k8snode status 的状态是 pending,上面说明没有完成调度,因为没有一个拥有 zone 的标签的值是 foo 或者 bar,而且使用的是硬亲和性,必须满足条件才能完成调度 [root@k8smaster ~]# kubectl label nodes xianchaonode1 zone=foo 给这个 node 节点打上标签 zone=foo,在查看 [root@k8smaster ~]# kubectl get pods -o wide 显示如下: pod-node-affinity-demo 1/1 Running 0 k8snode 例 2 使用 preferredDuringSchedulingIgnoredDuringExecution 软亲和性 [root@k8smaster ~]# vim pod-nodeaffinity-demo-2.yaml apiVersion: v1 kind: Pod metadata: name: pod-node-affinity-demo-2 namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - preference: matchExpressions: - key: zone1 operator: In values: - foo1 - bar1 weight: 60 [root@k8smaster ~]# kubectl apply -f pod-nodeaffinity-demo-2.yaml [root@k8smaster ~]# kubectl get pods -o wide |grep demo-2 pod-node-affinity-demo-2 1/1 Running 0 k8snode1 上面说明软亲和性是可以运行这个 pod 的,尽管没有运行这个 pod 的节点定义的 zone1 标签 Node 节点亲和性针对的是 pod 和 node 的关系,Pod 调度到 node 节点的时候匹配的条件
写在最后
创作不易,如果觉得内容对你有帮助,麻烦给个三连关注支持一下我!如果有错误,请在评论区指出,我会及时更改! 目前正在更新的系列:从零开始学k8s 感谢各位的观看,文章掺杂个人理解,如有错误请联系我指出~