← 返回上一页

tech

Kubernetes API Server 如何与其他组件协作

理解 API Server、etcd、Scheduler、Controller Manager 和 Watch 的协作关系

Kubernetes 控制面由多个独立进程组成:

kube-apiserver
kube-scheduler
kube-controller-manager
etcd

它们(包括 Kubelet)之间的关系:

Scheduler ───────────────┐
Controller Manager ──────┤
Kubelet ─────────────────┤
                         ▼
                    API Server
                         │
                         ▼
                        etcd

一、各组件的职责

API Server:
    提供 API、认证、授权、校验、Watch 和对象存储

etcd:
    保存 Kubernetes 集群状态

Scheduler:
    为未绑定节点的 Pod 选择 Node

Controller Manager:
    根据当前状态和期望状态执行控制循环

Kubelet:
    在节点上启动和管理容器

API Server 不负责调度 Pod,也不负责启动容器。

二、各组件是独立进程

每个核心组件都是独立的 Go 程序。

cmd/kube-apiserver/apiserver.go
cmd/kube-scheduler/scheduler.go
cmd/kube-controller-manager/controller-manager.go
cmd/kubelet/kubelet.go

但 main() 通常只负责启动命令,不包含主要业务逻辑。

拿 API Server 的启动结构举例(几乎所有组件的启动代码类似):

// cmd/kube-apiserver/apiserver.go

package main

func main() {
    command := app.NewAPIServerCommand()
    code := cli.Run(command)
    os.Exit(code)
}

实际调用链:

main()
  ↓
NewAPIServerCommand()
  ↓
RunE()
  ↓
加载配置
  ↓
创建 API Server
  ↓
创建 Storage 和 etcd client
  ↓
启动 HTTP Server

三、API Server 处理请求

以创建 Pod 为例:

HTTP 请求
  ↓
认证 / 授权 / Admission
  ↓
对象解析和校验
  ↓
资源 Storage
  ↓
通用 Store
  ↓
etcd

简化代码:

func Create(obj Object) {
    validate(obj)

    key := makeKey(obj)
    data := encode(obj)

    etcd.Put(key, data)
    notifyWatchers(obj)
}

实际 API Server 会处理:

默认值
API 版本转换
字段校验
ResourceVersion
并发冲突
Admission
序列化
Watch 事件

四、API Server 如何连接 etcd

API Server 启动时读取 etcd 配置:--etcd-servers=https://127.0.0.1:2379

启动流程:

--etcd-servers
  ↓
EtcdOptions
  ↓
StorageBackendConfig
  ↓
创建 etcd client
  ↓
创建 Storage
  ↓
各资源复用 Storage

API Server 不会为每个请求重新创建 etcd 连接,而是在启动时创建并复用客户端。(其实就是平时写后端时候连接数据库那样)

在 kubeadm 集群中,这个参数通常出现在:/etc/kubernetes/manifests/kube-apiserver.yaml

示例:

command:
- kube-apiserver
- --etcd-servers=https://127.0.0.1:2379

五、其他组件如何找到 API Server

Scheduler、Controller Manager 和 Kubelet 通常使用 kubeconfig。

Scheduler:--kubeconfig=/etc/kubernetes/scheduler.conf

Controller Manager:--kubeconfig=/etc/kubernetes/controller-manager.conf

各个组件的 kubeconfig 中保存 API Server 地址:

clusters:
- cluster:
    server: https://127.0.0.1:6443

因此:

scheduler.conf
  ↓
kube-scheduler
  ↓
https://127.0.0.1:6443
  ↓
kube-apiserver

Controller Manager 也是同样的方式。

六、创建 Pod 的完整流程

  1. 客户端请求 API Server
  2. API Server 校验 Pod
  3. API Server 将 Pod 写入 etcd
  4. API Server 产生 Pod 事件
  5. Scheduler Watch 到 Pod
  6. Scheduler 选择 Node
  7. Scheduler 通过 API Server 绑定 Pod
  8. API Server 更新 etcd
  9. Kubelet Watch 到分配给自己的 Pod
  10. Kubelet 启动容器
  11. Kubelet 更新 Pod Status
  12. API Server 将 Status 写入 etcd

七、Watch 是什么

Watch 是一个长期保持的 HTTP 请求:GET /api/v1/pods?watch=true

它不是多次 HTTP 响应,而是:

一次请求
  ↓
一次响应
  ↓
响应 Body 不关闭
  ↓
持续写入事件

事件类似:

{"type":"ADDED","object":{}}
{"type":"MODIFIED","object":{}}
{"type":"DELETED","object":{}}

简化代码:

func Watch(w http.ResponseWriter, events <-chan Event) {
    flush := w.(http.Flusher)

    for event := range events {
        writeJSON(w, event)
        flush.Flush()
    }
}

Kubernetes Watch 不是标准 SSE,而是 HTTP Streaming。

八、Watch 的事件链路

etcd
  ↓
API Server Watch Cache
  ↓
API Server 内部 Go channel
  ↓
HTTP Watch 长连接
  ↓
Scheduler / Controller Manager / Kubelet

不同层使用的通信方式:

API Server 内部:
    Go channel

API Server 与其他组件之间:
    HTTP 长连接

API Server 与 etcd 之间:
    etcd client / gRPC

Scheduler 和 Controller Manager 不直接监听 etcd,而是监听 API Server。

九、Scheduler 的逻辑

for event := range watchPods() {
    pod := event.Object

    if pod.NodeName == "" {
        node := chooseNode(pod)
        bindPod(pod, node)
    }
}

实际链路:

Scheduler Watch Pod
  ↓
发现 Pod 没有 Node
  ↓
选择 Node
  ↓
通过 API Server 更新 Pod
  ↓
API Server 写入 etcd

十、Controller Manager 的逻辑

Controller Manager 内部运行多个 Controller:

Deployment Controller
ReplicaSet Controller
Node Controller
Job Controller

控制循环:

for event := range watchResources() {
    desired := calculateDesiredState(event)
    updateThroughAPIServer(desired)
}

例如副本不足:

Controller Watch Deployment
  ↓
发现副本数不足
  ↓
创建或调整 ReplicaSet
  ↓
ReplicaSet 创建 Pod
  ↓
API Server 写入 etcd

十一、最终模型

etcd:
    保存集群状态

API Server:
    提供统一 API
    读写 etcd
    维护 Watch
    分发资源变化

Scheduler:
    监听未调度 Pod
    选择 Node

Controller Manager:
    Watch 各类资源
    执行控制循环
    通过 API Server 创建、修改、删除对象

Kubelet:
    执行 Pod
    更新运行状态

完整链路:

etcd
  ↓
API Server
  ↓ HTTP Watch
Scheduler / Controller Manager / Kubelet
  ↓
控制逻辑
  ↓ HTTP REST
API Server
  ↓
etcd

一句话:

API Server 是控制面的中枢,etcd 保存状态,Scheduler 和 Controller Manager 是独立的 Go 进程。它们通过 kubeconfig 找到 API Server,通过 HTTP Watch 获取事件,再通过 API Server 修改集群状态。