写点什么

【云原生 | 从零开始学 Kubernetes】六、Pod 的镜像拉取策略与各种机制

作者:泡泡
  • 2022 年 9 月 23 日
    河北
  • 本文字数:3961 字

    阅读完需:约 13 分钟

【云原生 | 从零开始学Kubernetes】六、Pod的镜像拉取策略与各种机制

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.requiredDuringSchedulingIgnoredDuringExecutionKIND: 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.nodeSelectorTerms 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.nodeSelectorTerms.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 感谢各位的观看,文章掺杂个人理解,如有错误请联系我指出~

发布于: 刚刚阅读数: 4
用户头像

泡泡

关注

做最好的知识分享 云计算/云原生 2022.08.25 加入

CSDN万粉博主

评论

发布
暂无评论
【云原生 | 从零开始学Kubernetes】六、Pod的镜像拉取策略与各种机制_Docker_泡泡_InfoQ写作社区