当你在 Kubernetes 中创建 Pod 时会发生什么?一个令人惊讶的简单任务揭示了一个复杂的工作流程,该工作流涉及集群中的多个组件。

1、kubectl执行YAML文件

让我们从显而易见的开始:kubectl 将 YAML 定义发送到 API 服务器。在此步骤中,kubectl执行如下步骤:

  • 使用 OpenAPI (Swagger) 发现 API Endpoints
  • 协商资源版本
  • 验证 YAML
  • 发出请求

当请求到达 API 时,它会经历以下过程:

  • 身份验证和授权(Authentication & authorization)
  • 准入控制器(Admission controllers)

在最后一步中,它最终存储在 etcd 中。

2、etcd存储

k8s-etcd
k8s-etcd

在此之后,Pod 将添加到调度程序队列中。调度程序对节点进行过滤和评分,以找到最佳节点。它最终将 Pod 绑定到节点,绑定信息同样写到 etcd 里。

k8s pod etcd
k8s pod etcd

此时,pod 仅作为记录存在于 etcd 中,尚未创建任何容器在Node上。

3、任务管理调度

k8s管理面执行任务调度,将任务下发给对应的Node节点:

k8s-kubelet-execute
k8s-kubelet-execute

Node节点上的kubelet 拉取 Pod ,并继续向CNI、CRI、CSI接口执行任务委托:

  • 调用 CNI 创建的网络(例如 Cilium)
  • 调用 CRI 创建容器(例如容器)
  • 调用 CSI 创建存储(例如 OpenEBS)

除此之外,Kubelet 将执行 Pod 的探测,并在 Pod 运行时将其 IP 地址报告给控制平面。该 IP 和容器的端口作为endpoint存储在 etcd 中。

kubelet-endpoints
kubelet-endpoints

Endpoints是什么?在 Kubernetes 中:

  • Endpoint是 10.0.0.2:3000(IP:端口)对
  • Endpoints是endpoint的集合(IP:端口对的列表)

对于集群中的每个服务,Kubernetes 都会创建一个包含endpoint的endpoint对象。

k8s-service-endpoint-objects
k8s-service-endpoint-objects

ndpoints (IP:port) 在以下地方使用:

  • kube-proxy 设置 iptables 规则
  • CoreDNS 更新 DNS 记录
  • Ingress controllers 设置后端请求
  • 服务网格 (Service meshes)
  • 更多其他操作

添加Endpoint后,将立即通知以上对应的组件。

k8s-componente-update-data
k8s-componente-update-data

当 Endpoint(IP:端口)传播时,你终于可以开始使用 Pod 了! 哪删除 Pod 时会发生什么情况?

过程相反,对应的顺序是:

  • 应用停止接受连接
  • 控制器(kube-proxy、ingress等)来删除Endpoints
  • 等待现有连接完成
  • 关闭应用程序

k8s-delete-pod
k8s-delete-pod

翻译自 Daniele Polencic 的文章,翻译过程中部分内容做了描述改动。