暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Kubernetes创建Pod工作流程,看这篇就够了

CloudNativeX 2021-04-29
4530

在提到Kubernetes时,您肯定会联想到Pod

Pod,它是 Kubernetes项目的原子调度单位,关于Pod最重要的一个事实是:它只是一个逻辑概念。也就是说,Kubernetes真正处理的,还是宿主机操作系统上 Linux 容器的Namespace和Cgroups,而并不存在一个所谓的 Pod 的边界或者隔离环境。

那,Pod又是怎么被“创建”出来的呢?本次内容就是针对Kubernetes创建Pod流程来进行分析。

                            

一般来说,Kubernetes创建Pod的工作流程有如下图所示的几个阶段,如下图:



第一步:用户通过kubectl等接口提交创建Pod的yaml文件,向Kubernetes系统发起资源请求


第二步:Api-server接收到用户请求之后,会做出相应的认证,然后检查信息并且将元数据信息存储到etcd中,创建Pod资源初始化,这是第一次写etcd动作


第三步:Scheduler通过list-watch的监听机制,查看要创建Pod资源,APIServer会立即把创建Pod的消息通知Scheduler,Scheduler发现Pod的属性中Dest Node为空时(Dest Node=””),便会立即触发调度流程进行调度。而调度流程分为以下几个步骤,如下图

    3.1. 过滤:首先是kube-scheduler调度器用一组规则过滤掉不满足条件的主机,这个过程称为predicate,比如明确指定所需要的资源类型,这样就可以过滤掉不满足条件的主机。

    Predicate有一系列的算法可以使用:

  • PodToleratesNodeTaints:检查Pod是否容忍Node Taints

  • CheckNodeMemoryPressure:检查Pod是否可以调度到MemoryPressure的节点上

  • CheckNodeDiskPressure:检查Pod是否可以调度到DiskPressure的节点上

  • NoVolumeNodeConflict:检查节点是否满足Pod所引用的Volume的条件

  • PodFitsPorts:同PodFitsHostPorts

  • PodFitsHostPorts:检查是否有Host Ports冲突

  • PodFitsResources:检查Node的资源是否充足,包括允许的Pod数量、CPU、内存、GPU个数以及其他的OpaqueIntResources

  • HostName: 检查Pod.Spec.NodeName是否与候选节点一致

  • MatchNodeSelector:检查候选节点的Pod.Spec.NodeSelector 是否匹配

  • NoVolumeZoneConflict:检查 volume zone是否冲突

  • MaxEBSVolumeCount:检查AWS EBS Volume数量是否过多(默认不超过 39)

  • MaxGCEPDVolumeCount:检查GCE PD Volume数量是否过多(默认不超过 16)

  • MaxAzureDiskVolumeCount:检查Azure Disk Volume数量是否过多(默认不超过 16)

  • MatchInterPodAffinity:检查是否匹配Pod的亲和性要求

  • NoDiskConflict:检查是否存在Volume冲突,仅限于GCE PD、AWS EBS、Ceph RBD以及ISCSI

  • GeneralPredicates:

    分noncriticalPredicates和EssentialPredicates


    3.2. 评分:对第一步筛选出的符合要求的主机进行打分,这个过程称为 priority,在此阶段,如果在 predicate过程中没有合适的节点,Pod 会一直处于pending状态,不断重试调度,直到有节点满足条件。

经过这个步骤,如果有多个节点满足条件,就继续 priorities 过程:按照优先级大小对节点排序。

    Priorities优先级选项包括: 

  • LeastRequestedPriority:优先调度到请求资源少的节点上

  • NodePreferAvoidPodsPriority: alpha.kubernetes.io/preferAvoidPods 字段判断, 权重为10000,避免其他优先级策略的影响

  • NodeAffinityPriority:优先调度到匹配 NodeAffinity 的节点上

  • TaintTolerationPriority:优先调度到匹配 TaintToleration 的节点上

  • ServiceSpreadingPriority:尽量将同一个 service 的 Pod 分布到不同节点上

  • MostRequestedPriority:尽量调度到已经使用过的 Node 上,特别适用于

  • SelectorSpreadPriority: 优先减少节点上属于同一个Service或Replication Controller的Pod数量

  • InterPodAffinityPriority:优先将 Pod 调度到相同的拓扑上(如同一个节点、Rack、Zone 等)

  • BalancedResourceAllocation:优先平衡各节点的资源使用


    3.3. 选择优先级最高的节点:选择得分最高的主机,进行binding操作,结果存储到Etcd中。


第四步:kubelet根据调度结果执行Pod创建操作,绑定成功后,会启动容器运行时,container, docker run, scheduler会调用API Server的API在etcd中创建一个bound Pod对象,它描述在一个工作节点上绑定运行的所有pod信息。

运行在每个工作节点上的kubelet也会定期与api-server同步bound Pod的信息,一旦发现在该工作节点上运行的bound Pod对象没有更新,则调用Docker API创建并启动pod内的容器.


第五步:kube-proxy为新创建的pod注册动态DNS到CoreOS,然后给pod的service添加对应的iptables规则,用于服务发现和负载均衡。


第六步:至此,Pod创建完成。


最后,还有一个过程,就是controller通过controller loop将当前Pod状态与定义所需求的状态作对比,如果当前状态与定义的期望状态不同,则controller会将Pod修改为定义的期望状态值,如果Pod运行出现问题,那将删除该Pod,然后重新创建。


喜欢就点赞关注吧,更多精彩内容持续分享中......

文章转载自CloudNativeX,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论