前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Kubernetes(k8s)-Pod创建流程

Kubernetes(k8s)-Pod创建流程

作者头像
运维小路
发布2025-02-25 08:29:46
发布2025-02-25 08:29:46
11800
代码可运行
举报
文章被收录于专栏:运维小路运维小路
运行总次数:0
代码可运行

作者介绍:简历上没有一个精通的运维工程师。下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

我们上一章介绍了Docker基本情况,目前在规模较大的容器集群基本都是Kubernetes,但是Kubernetes涉及的东西和概念确实是太多了,而且随着版本迭代功能在还增加,笔者有些功能也确实没用过,所以只能按照我自己的理解来讲解。

Pod是整个Kubernetes的最核心的资源,当我们完成部署集群部署以后,我们对集群的维护实际上主要的就是针对Pod维护,其他资源很少会修改调整,但是Pod却会因为版本发布而经常调整,所以我们用了单独一小节来介绍Pod的创建过程。该问题也是面试Kubernetes相关岗位最常问的问题之一。

下图来源于网络

  1. 通过 kubectl 或其他 API 方式向 Kubernetes API 服务器发出请求
    • 用户使用 kubectl apply -f <pod-definition.yaml> 或其他 Kubernetes API 客户端工具提交创建 Pod 的请求。
  2. Kubernetes API 服务器 (kube-apiserver)
    • 接收并验证请求:API 服务器检查请求的语法、用户权限、资源配额等。
    • 写入 etcd:验证通过后,API 服务器将 Pod 的定义写入 etcd,确保状态一致性和持久化。
    • 返回响应:API 服务器向用户返回一个确认信息,表明 Pod 已成功创建。
  3. Kubernetes 调度器 (kube-scheduler)
    • 监听 API 服务器:调度器通过 watch 机制持续监听 API 服务器上 Pod 的新建事件。
    • 调度决策:一旦检测到新的 Pod,调度器开始执行调度逻辑,包括预选(过滤不符合 Pod 要求的节点)和优选(选择最适合运行 Pod 的节点)。
    • 绑定节点:确定最佳节点后,调度器将 Pod 绑定到该节点,并通过 API 服务器更新 Pod 的状态。
  4. 调度结果反馈
    • 调度器将调度结果反馈给 API 服务器,API 服务器更新 Pod 的节点绑定信息,并将结果写入 etcd。
  5. Kubelet 操作
    • 容器运行时接口 (CRI):用于创建和管理容器。
    • 容器网络接口 (CNI):用于配置 Pod 的网络。
    • 容器存储接口 (CSI):如果 Pod 需要持久化存储,Kubelet 将调用 CSI 接口。
    • 监听 API 服务器:每个节点上的 Kubelet 组件也通过 watch 机制监听 API 服务器,等待分配到本节点的 Pod。
    • 容器创建:当 Kubelet 发现有一个 Pod 被调度到它所在的节点,它将调用以下标准接口来创建 Pod:
  6. 健康检查和状态更新
    • 容器启动后,Kubelet 执行 Pod 的健康检查(如 livenessProbe 和 readinessProbe)。
    • 一旦容器通过健康检查,Kubelet 将更新 Pod 的状态为“运行中” (1/1这样的状态),并将状态反馈给 API 服务器。
    • API 服务器将最新的 Pod 状态写入 etcd,确保集群状态的一致性。

基本上目前能看到的讲解Pod创建流程的图基本上都是以此图或者以此图为原型的一些改进版,所以我也会用该图来讲解,并且结合日志。

1.调整Kube-apiserver和Kube-scheduler的日志

代码语言:javascript
代码运行次数:0
复制
#在静态pod的yaml文件启动参数添加一行
#这个是最大日志级别会显示很多的内容,需要过滤才比较容易查看
- --v=10

2.准备一个Pod

代码语言:javascript
代码运行次数:0
复制
apiVersion: v1            # API 版本
kind: Pod                 # 资源类型
metadata:
  name: example-pod       # Pod 名称
  labels:
    app: example          # 标签,用于标识和选择相关的资源
spec:
  containers:             # 容器列表
  - name: example-container  # 容器名称
    image: 192.168.31.43:5000/busybox      # 容器镜像
    imagePullPolicy: IfNotPresent
    command: ["sh", "-c", "tail -f /dev/null"]
    ports:
    - containerPort: 80      # 容器内的端口号

3.创建pod

代码语言:javascript
代码运行次数:0
复制
kubectl  apply -f pod.yaml

4.日志分析

这个时候应该是上图写入了数据库,并且返回给用户,但是这个还没有调度,因为提示的是没有Node节点。

代码语言:javascript
代码运行次数:0
复制
#kube-apiserver日志
I0119 02:34:02.844378 graph_populator.go:148] updatePod default/example-pod, no node

kube-scheduler通过watch 到kube-server有Pod被创建。并且没有被调度,然后它就开始根据算法调度到了node01节点

代码语言:javascript
代码运行次数:0
复制
#kube-scheduler调度日志
I0119 02:34:02.844026       1 eventhandlers.go:118] "Add event for unscheduled pod" pod="default/example-pod"
I0119 02:34:02.844065       1 scheduling_queue.go:933] "About to try and schedule pod" pod="default/example-pod"
I0119 02:34:02.844073       1 scheduler.go:443] "Attempting to schedule pod" pod="default/example-pod"
I0119 02:34:02.844232       1 default_binder.go:52] "Attempting to bind pod to node" pod="default/example-pod" node="node01"
I0119 02:34:02.856122       1 eventhandlers.go:161] "Delete event for unscheduled pod" pod="default/example-pod"
I0119 02:34:02.856221       1 cache.go:385] "Finished binding for pod, can be expired" pod="default/example-pod"
I0119 02:34:02.856251       1 scheduler.go:623] "Successfully bound pod to node" pod="default/example-pod" node="node01" evaluatedNodes=2 feasibleNodes=1

kube-apiserver也显示调度到node01

代码语言:javascript
代码运行次数:0
复制
#kube-apiserver日志
I0121 02:34:02.855314       1 graph_populator.go:158] updatePod default/example-pod for node node01

kubelet感知到他分配了Pod,他开始执行创建Pod操作。

代码语言:javascript
代码运行次数:0
复制
#kubelet日志
Feb 15 16:37:57 node01 kubelet[3408]: I0215 16:37:57.087517    3408 config.go:383] "Receiving a new pod" pod="default/example-pod"
Feb 15 16:37:57 node01 kubelet[3408]: I0215 16:37:57.087602    3408 kubelet.go:2114] "SyncLoop ADD" source="api" pods=[default/example-pod]
Feb 15 16:37:57 node01 kubelet[3408]: I0215 16:37:57.087724    3408 pod_workers.go:571] "Pod is being synced for the first time" pod="default/example-pod" podUID=18736566-533b-4afa-99c5-b2471fe6b6e3
Feb 15 16:37:57 node01 kubelet[3408]: I0215 16:37:57.087760    3408 pod_workers.go:888] "Processing pod event" pod="default/example-pod" podUID=18736566-533b-4afa-99c5-b2471fe6b6e3 updateType=0
Feb 15 16:37:57 node01 kubelet[3408]: I0215 16:37:57.087774    3408 kubelet.go:1554] "syncPod enter" pod="default/example-pod" podUID=18736566-533b-4afa-99c5-b2471fe6b6e3
Feb 15 16:37:57 node01 kubelet[3408]: I0215 16:37:57.087785    3408 kubelet_pods.go:1441] "Generating pod status" pod="default/example-pod"
Feb 15 16:37:57 node01 kubelet[3408]: I0215 16:37:57.087811    3408 kubelet_pods.go:1453] "Got phase for pod" pod="default/example-pod" oldPhase=Pending phase=Pending
Feb 15 16:37:57 node01 kubelet[3408]: I0215 16:37:57.087850    3408 status_manager.go:529] "updateStatusInternal" version=1 pod="default/example-pod" podUID=18736566-533b-4afa-99c5-b2471fe6b6e3 containers="(example-container state=waiting previous=<none>)"

我们前面讲解RBAC权限的时候也提到了watch,这里的watch实际上就是我监听你,然后你有变化我就能感知到,然后我会根据你的变化做对应的操作。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-02-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维小路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档