ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

创建一个 k8s pod,背后发生了什么

2022-05-08 22:02:52  阅读:234  来源: 互联网

标签:node kubelet 创建 apiserver nginx scheduler pod k8s


本例使用 kubectl 创建、运行了一个 nginx pod:

kubectl run nginx --image=nginx --restart=Never

通过 tcpdump 抓包、分析,得到的交互流程如下图所示:

sequenceDiagram autonumber participant C as kubectl participant AS as kube-apiserver participant S as kube-scheduler participant L as kubelet S ->>+ AS: [REQ] GET /api/v1/pods?watch=true<br>&fieldSelector="status.phase!=Succeeded,<br>status.phase!=Failed" AS -->>- S: [RESP]: 200 OK, chunked, wait for chunks... L ->>+ AS: [REQ] GET /api/v1/pods?watch=true<br>&fieldSelector="fieldSelector=spec.nodeName=node-1" AS -->>- L: [RESP]: 200 OK, chunked, wait for chunks... Note over C,L: After k8s setup C ->>+ AS: [REQ] POST /api/v1/namespaces/default/pods - nginx AS ->> S: [RESP-CHUNK]: Pod Added - nginx AS ->>- C: [RESP] 201 Created S ->>+ AS: [REQ] POST /api/v1/namespaces/default/pods/nginx/binding AS ->> L: [RESP-CHUNK]: Pod Added - nginx AS ->>- S: [RESP] 201 Created L ->>+ AS: [REQ] PUT /api/v1/namespaces/default/pods/nginx/status AS ->>- L: [RESP]: 200 OK

注解:

【1~4】为 k8s 启动时就发生的步骤

【1】scheduler 启动时向 apiserver 请求监听所有pod的列表,使用了参数 fieldSelectorstatus.phase!=Succeeded,status.phase!=Failed ,表明对 phase 为 Succeeded 和 Failed 的 pod 不感兴趣,排除在监听对象之外。事实上 scheduler 对 phase 为 Pending 的 pod 更感兴趣,因为刚创建的 pod 状态为 Pending,而 scheduler 的主要职责就是把 Pending 状态的 pod 调度到某个节点上,由该节点上的 kubelet 把 pod 运行起来。

【2】apiserver 返回的报文如下:

HTTP/1.1 200 OK
...
Transfer-Encoding: chunked

头部 Transfer-Encoding: chunked 表示 response 的 body 是以 chunk 分块的形式推送给 scheduler,当前没有 chunk。换句话说,当 scheduler 请求监听的pod列表有变动时,apiserver 会把相应的pod信息推送给 scheduler,scheduler 只需保持连接、耐心等待就行。

【3】kubelet 启动时 apiserver 请求监听所有pod的列表,使用了参数 fieldSelectorfieldSelector=spec.nodeName=node-1,表明只对 spec.nodeName 设置为 node-1 的 pod 感兴趣。新创建的 pod 不会设置 spec.nodeName 字段,经由 scheduler 调度处理后,pod 的 spec.nodeName 字段会被设置为某个节点的名字,表明应由该节点运行 pod。本例中 kubelet 正是运行在节点 node-1 上,这就是使用参数 fieldSelectorfieldSelector=spec.nodeName=node-1 的意义,因为 kubelet 只对调度到 node-1 上的 pod 感兴趣。

【4】返回的报文和【2】类似。

【5】对应用户执行的kubectl run nginx --image=nginx --restart=Never命令,kubectl 请求 apiserver 创建一个 pod 对象,请求报文 body 如下:

{
  "kind": "Pod",
  "apiVersion": "v1",
  "metadata": {
    "name": "nginx",
    "creationTimestamp": null
  },
  "spec": {
    "containers": [
      {
        "name": "nginx",
        "image": "nginx"
      }
    ],
    "restartPolicy": "Never"
  },
  "status": {}
}

【6】由于【1】scheduler 启动时监听 pod 列表,然后新创建的 pod 满足 scheduler 监听条件,所以这个pod的信息以 chunk 的形式推送到了 scheduler,对应【2】。

【7】pod 的资源创建后,apiserver 便立即返回了,无需等待 pod 运行。

【8】由于在【6】接收到新的 pod 的信息,scheduler 经过一些决策,决定将 pod 调度到 node-1,因此向 apiserver 发送对应的 pod binding 请求,在请求的body中指定了 node-1。

【9】apiserver 收到【8】的请求后,将 pod 的 spec.nodeName 字段设置为 node-1,这刚好满足了【3】kubelet 感兴趣的 pod 条件,所以更新后的pod的信息以 chunk 的形式推送到了 kubelet,对应【4】。

【10】apiserver 返回 pod binding 请求成功。

【11】由于在【9】接收到新的 pod 的信息,kubelet 将 pod 拉起运行,同时将 pod 的最新信息——包括 pod ip ,node 信息,运行状态等同步更新到 apiserver 。

【12】apiserver 返回 pod 信息更新成功。自此流程结束。

标签:node,kubelet,创建,apiserver,nginx,scheduler,pod,k8s
来源: https://www.cnblogs.com/roy2220/p/16247088.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有