惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

PCI Perspectives
PCI Perspectives
J
Java Code Geeks
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
博客园 - 聂微东
雷峰网
雷峰网
The Cloudflare Blog
V
V2EX
Hacker News: Ask HN
Hacker News: Ask HN
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Hacker News - Newest:
Hacker News - Newest: "LLM"
爱范儿
爱范儿
NISL@THU
NISL@THU
T
The Exploit Database - CXSecurity.com
Project Zero
Project Zero
腾讯CDC
罗磊的独立博客
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
S
Security Affairs
S
SegmentFault 最新的问题
月光博客
月光博客
P
Privacy International News Feed
Last Week in AI
Last Week in AI
博客园 - Franky
C
Cisco Blogs
宝玉的分享
宝玉的分享
Forbes - Security
Forbes - Security
WordPress大学
WordPress大学
博客园 - 叶小钗
L
LINUX DO - 最新话题
博客园_首页
Spread Privacy
Spread Privacy
大猫的无限游戏
大猫的无限游戏
S
Secure Thoughts
IT之家
IT之家
人人都是产品经理
人人都是产品经理
I
Intezer
W
WeLiveSecurity
C
CERT Recently Published Vulnerability Notes
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Cyberwarzone
Cyberwarzone
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
S
Security @ Cisco Blogs
L
Lohrmann on Cybersecurity
美团技术团队

lznauy的技术小屋

Kubernetes 调度器—Pod 如何被分配到节点 Kubernetes Controller 调谐循环的实现原理 Kubernetes 核心资源模型的设计哲学 Gin 路由为什么快:Radix Tree 源码剖析 前路茫茫 NekoCode 深度解析 用AI开发新主题仅需一天 AIAgent开发杂谈 CodeAgent的开发比我想象的难的多 nix语法初入门 记录一次家里老人受骗 nixos美化shell及常用软件安装 皖南川藏线之旅 nixos配置kitty以及桌面美化 nixos安装niri和noctalia nixos-shell及配置优化 nixos-flake和home-manager nixos折腾之旅 claude源码泄漏事件及简单剖析 春季赏花之旅 曲折的离职过程 年味越来越淡了 城市里没有爱情? 日常碎记(三) 利用DeepSeek分析你的隐藏天赋 SELinux技术介绍 我们的认知可能被裹挟了 日常碎记(二)
Kubernetes API Server—请求处理链路
lznauy · 2026-07-24 · via lznauy的技术小屋

阅读时间:9 分钟 4151 字 AI 协作

此文章可能有部分 AI 辅助生成内容,如果您介意可以不再继续阅读。

基于 Kubernetes v1.37 源码(staging/src/k8s.io/apiserver/

一、API Server 的职责 @

API Server 是 Kubernetes 集群的唯一入口,所有组件都通过它与集群交互:

kubectl → API Server → etcd
kubelet → API Server → etcd
controller-manager → API Server → etcd
scheduler → API Server → etcd

核心职责:

  • REST API 暴露:提供 CRUD 接口
  • 认证 (Authentication):确认请求者身份
  • 授权 (Authorization):确认请求者权限
  • 准入 (Admission):修改/验证请求
  • 存储抽象:封装 etcd 操作

二、整体架构 @

┌─────────────────────────────────────────────────────────────┐
│                     HTTP Server                             │
│  ┌──────────────────────────────────────────────────────┐  │
│  │                  Filter Chain                         │  │
│  │  RequestInfo → Timeout → CORS → AuthN → Audit →     │  │
│  │  Impersonation → MaxInFlight/APF → AuthZ → Handler   │  │
│  └──────────────────────────────────────────────────────┘  │
│                            ↓                                │
│  ┌──────────────────────────────────────────────────────┐  │
│  │            Director (路由分发)                        │  │
│  │  /api/v1/pods → GoRestfulContainer                   │  │
│  │  /healthz → NonGoRestfulMux                          │  │
│  └──────────────────────────────────────────────────────┘  │
│                            ↓                                │
│  ┌──────────────────────────────────────────────────────┐  │
│  │           REST Handlers                               │  │
│  │  Create / Get / Update / Delete / Watch / List       │  │
│  └──────────────────────────────────────────────────────┘  │
│                            ↓                                │
│  ┌──────────────────────────────────────────────────────┐  │
│  │           Storage Layer                               │  │
│  │  Cacher (本地缓存) → etcd3 (持久化存储)              │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

三、启动流程 @

// cmd/kube-apiserver/app/server.go
func Run(ctx context.Context, opts options.CompletedOptions) error {
    // 1. 构建配置并补全默认值
    config, err := NewConfig(opts)
    completed, err := config.Complete()
    
    // 2. 创建 API Server 链(kube-apiserver → apiextensions → aggregator)
    server, err := CreateServerChain(completed)
    
    // 3. 准备运行(初始化存储、安装 API)
    prepared, err := server.PrepareRun()
    
    // 4. 启动服务
    return prepared.Run(ctx)
}
// staging/src/k8s.io/apiserver/pkg/server/genericapiserver.go
func (s preparedGenericAPIServer) Run(stopCh <-chan struct{}) error {
    // 1. 非阻塞启动 HTTPS 服务器
    //    内部调用 s.SecureServingInfo.Serve(s.Handler, ...)
    stoppedCh, err := s.NonBlockingRun(stopCh, shutdownTimeout)
    
    // 2. 执行 PostStartHooks
    
    // 3. 阻塞等待关闭信号,收到后优雅关停
    <-stopCh
    ...
}

四、Filter Chain(过滤器链) @

API Server 使用责任链模式处理请求,每个 Filter 负责一个职责:

HTTP Request
    ↓
WithRequestInfo (请求信息解析,最前端)
    ↓
WithWaitGroup (跟踪在途请求,配合优雅关停)
    ↓
WithRequestDeadline / WithTimeoutForNonLongRunningRequests (超时控制)
    ↓
WithWarningRecorder (告警头)
    ↓
WithCORS (跨域处理)
    ↓
WithAuthentication (认证)
    ↓
WithTracing (链路追踪)
    ↓
WithAudit (审计日志)
    ↓
WithImpersonation (用户伪装)
    ↓
WithMaxInFlightLimit / WithPriorityAndFairness (限流)
    ↓
WithAuthorization (授权)
    ↓
Director (路由分发)
    ↓
REST Handler(准入 Admission 在 Handler 内部执行,见 4.3 节)

注意:准入(Admission)不在 HTTP 过滤器链中,而是在 Create/Update 等 Handler 内部调用——Mutating 由 Handler 直接调用 MutationInterface.Admit,Validating 经 rest.AdmissionToValidateObjectFunc 包装后传入存储层。

4.1 认证 Filter (Authentication) @

// staging/src/k8s.io/apiserver/pkg/authentication/authenticator/interfaces.go
type Request interface {
    AuthenticateRequest(req *http.Request) (*Response, bool, error)
}

type Response struct {
    User user.Info  // 认证后的用户信息
    Audiences Audiences
}

认证方式链(按顺序尝试,见 pkg/kubeapiserver/authenticator/config.go):

方式 说明
RequestHeader 前置代理(front-proxy)通过请求头传递的客户端证书身份
Client Certificate X.509 客户端证书
Bearer Token Token 链依次尝试:Token File → ServiceAccount → Bootstrap Token → OIDC → Webhook
Anonymous 匿名用户(以上都未认证时兜底)
// 认证链实现
// staging/src/k8s.io/apiserver/pkg/authentication/request/union/union.go
type unionAuthRequestHandler struct {
    Handlers []authenticator.Request
}

// 链式调用,任一成功即返回
func (authHandler *unionAuthRequestHandler) AuthenticateRequest(req *http.Request) (*authenticator.Response, bool, error) {
    for _, authenticator := range authHandler.Handlers {
        if resp, ok, err := authenticator.AuthenticateRequest(req); ok {
            return resp, ok, err
        }
    }
    return nil, false, aggregateErr
}

4.2 授权 Filter (Authorization) @

// staging/src/k8s.io/apiserver/pkg/authorization/authorizer/interfaces.go
type Authorizer interface {
    Authorize(ctx context.Context, a Attributes) (Decision, string, error)
}

type Decision int
const (
    DecisionDeny Decision = iota
    DecisionAllow
    DecisionNoOpinion
)

授权方式

方式 说明
RBAC 基于角色的访问控制(最常用)
Node 节点专用授权(kubelet)
Webhook 外部授权服务
ABAC 基于属性的访问控制
// 授权链实现
// staging/src/k8s.io/apiserver/pkg/authorization/union/union.go
func (authzHandler unionAuthzHandler) Authorize(ctx context.Context, a Attributes) (Decision, string, error) {
    for _, authz := range authzHandler.chain {
        decision, reason, err := authz.Authorizer.Authorize(ctx, a)
        if decision == DecisionAllow || decision == DecisionDeny {
            return decision, reason, err
        }
        // DecisionNoOpinion:记录 reason,继续尝试下一个
    }
    // 没有任何插件给出 Allow/Deny:返回 NoOpinion,并拼接各插件的 reason
    return DecisionNoOpinion, strings.Join(reasonList, "\n"), aggregateErr
}

4.3 准入控制 (Admission) @

准入不在 HTTP Filter Chain 中,而是在 REST Handler(Create/Update/Delete 等)内部执行。

// staging/src/k8s.io/apiserver/pkg/admission/interfaces.go
// Interface 只有 Handles;Admit 在 MutationInterface,Validate 在 ValidationInterface
type Interface interface {
    Handles(operation Operation) bool
}

type MutationInterface interface {
    Interface
    Admit(ctx context.Context, a Attributes, o ObjectInterfaces) error
}

type ValidationInterface interface {
    Interface
    Validate(ctx context.Context, a Attributes, o ObjectInterfaces) error
}

准入插件执行顺序

  1. MutatingAdmission(变更型):修改请求对象

    • 添加默认值
    • 注入 Sidecar 容器
    • 设置资源限制
  2. ValidatingAdmission(验证型):验证请求对象

    • 检查约束条件
    • 验证业务规则
// 准入链执行
func (h *AdmissionHandler) Admit(ctx context.Context, a Attributes, o ObjectInterfaces) error {
    // 1. 执行所有 Mutating 插件
    for _, plugin := range h.mutatingPlugins {
        if plugin.Handles(a.GetOperation()) {
            if err := plugin.Admit(ctx, a, o); err != nil {
                return err
            }
        }
    }
    
    // 2. 执行所有 Validating 插件
    for _, plugin := range h.validatingPlugins {
        if plugin.Handles(a.GetOperation()) {
            if err := plugin.Validate(ctx, a, o); err != nil {
                return err
            }
        }
    }
    return nil
}

五、REST Handler @

请求通过 Filter Chain 后,Director 根据 URL 分发到对应的 REST Handler。

5.1 路由注册 @

// staging/src/k8s.io/apiserver/pkg/endpoints/installer.go
func (a *APIInstaller) Install() ([]metav1.APIResource, []*storageversion.ResourceInfo, *restful.WebService, []error) {
    // 注册 /api/v1/pods
    ws.Path(a.prefix).Doc("...")
    
    // 注册 Create
    routes := []restful.RouteBuilder{}
    routes = append(routes, restful.POST(a.prefix).
        To(handler).
        Operation("create").
        ...
    )
    
    // 注册 Get
    routes = append(routes, restful.GET(a.prefix).
        To(handler).
        Operation("get").
        ...
    )
    
    // 注册 List
    routes = append(routes, restful.GET(a.prefix).
        To(handler).
        Operation("list").
        ...
    )
    
    // 注册 Update
    routes = append(routes, restful.PUT(a.prefix).
        To(handler).
        Operation("update").
        ...
    )
    
    // 注册 Delete
    routes = append(routes, restful.DELETE(a.prefix).
        To(handler).
        Operation("delete").
        ...
    )
    
    // 注册 Watch
    routes = append(routes, restful.GET(a.prefix).
        To(handler).
        Operation("watch").
        ...
    )
}

5.2 REST Storage 接口 @

// staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go
type Storage interface {
    New() runtime.Object
    Destroy()
}

type Creater interface {
    Storage
    Create(ctx context.Context, obj runtime.Object, createValidation ValidateObjectFunc, opts *metav1.CreateOptions) (runtime.Object, error)
}

type Getter interface {
    Storage
    Get(ctx context.Context, name string, opts *metav1.GetOptions) (runtime.Object, error)
}

type Updater interface {
    Storage
    Update(ctx context.Context, name string, objInfo UpdatedObjectInfo, createValidation ValidateObjectFunc, updateValidation ValidateObjectUpdateFunc, forceAllowCreate bool, opts *metav1.UpdateOptions) (runtime.Object, bool, error)
}

// 删除单个对象
type GracefulDeleter interface {
    Storage
    Delete(ctx context.Context, name string, deleteValidation ValidateObjectFunc, opts *metav1.DeleteOptions) (runtime.Object, bool, error)
}

// 删除整个集合
type CollectionDeleter interface {
    Storage
    DeleteCollection(ctx context.Context, deleteValidation ValidateObjectFunc, opts *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error)
}

type Watcher interface {
    Storage
    Watch(ctx context.Context, opts *metainternalversion.ListOptions) (watch.Interface, error)
}

5.3 Create Handler 示例 @

// staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go
func createHandler(r rest.NamedCreater, scope *RequestScope, admit admission.Interface, includeName bool) http.HandlerFunc {
    return func(w http.ResponseWriter, req *http.Request) {
        // 1. 解析请求
        namespace, name, _ := scope.Namer.Name(req)
        
        // 2. 内容协商(JSON/Protobuf)
        outputMediaType, _, _ := negotiation.NegotiateOutputMediaType(req, scope.Serializer, scope)
        
        // 3. 反序列化请求体(解码到内部版本)
        obj := r.New()
        decoder := scope.Serializer.DecoderToVersion(decodeSerializer, scope.HubGroupVersion)
        obj, gvk, err := decoder.Decode(body, &defaultGVK, obj)
        
        // 4. 执行 Mutating 准入
        if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
            err = mutatingAdmission.Admit(ctx, admissionAttributes, scope)
        }
        
        // 5. 执行创建(Validating 准入经 AdmissionToValidateObjectFunc 传入存储层)
        obj, err = r.Create(ctx, name, obj,
            rest.AdmissionToValidateObjectFunc(admit, admissionAttributes, scope),
            options)
        
        // 6. 返回结果
        responsewriters.WriteObject(ctx, outputMediaType, scope.Serializer, obj, w, req, statusCode)
    }
}

六、Storage Layer(存储层) @

6.1 Cacher(缓存层) @

API Server 使用 Cacher 作为存储抽象层,减少 etcd 压力:

// staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go
type Cacher struct {
    storage    storage.Interface // 底层 etcd3 存储
    watchCache *watchCache       // 近期事件的滑动窗口 + 对象当前状态
    reflector  *cache.Reflector  // 持续 watch etcd,异步填充 watchCache
}

func (c *Cacher) Get(ctx context.Context, key string, opts storage.GetOptions, out runtime.Object) error {
    // 等待 watchCache 同步到足够新的版本后,直接从缓存读取
    obj, exists, readRV, err := c.watchCache.WaitUntilFreshAndGet(ctx, getRV, key)
    if err != nil {
        return err
    }
    if !exists {
        return storage.NewKeyNotFoundError(key, int64(readRV))
    }
    // 将缓存对象写入 out
    ...
}

func (c *Cacher) Watch(ctx context.Context, opts storage.ListOptions) (watch.Interface, error) {
    // 通过 watchCache 实现高效 Watch
    ...
}

6.2 etcd3 存储 @

// staging/src/k8s.io/apiserver/pkg/storage/etcd3/store.go
type store struct {
    client    *clientv3.Client
    codec     runtime.Codec
    versioner storage.Versioner
}

func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object, ttl uint64) error {
    // 1. 校验 RV 必须为 0(Create 不允许对象自带 RV)
    if version, err := s.versioner.ObjectResourceVersion(obj); err == nil && version != 0 {
        return storage.ErrResourceVersionSetOnCreate
    }
    // 写入前清空 resourceVersion / selfLink
    s.versioner.PrepareObjectForStorage(obj)
    
    // 2. 序列化
    data, err := runtime.Encode(s.codec, obj)
    
    // 3. 乐观写入 etcd(仅当 key 不存在时成功)
    txnResp, err := s.client.Kubernetes.OptimisticPut(ctx, key, data, 0, ...)
    if !txnResp.Succeeded {
        return storage.NewKeyExistsError(key, 0)
    }
    
    return err
}

func (s *store) Get(ctx context.Context, key string, opts storage.GetOptions, out runtime.Object) error {
    // 1. 从 etcd 读取
    resp, err := s.client.Get(ctx, key)
    
    // 2. 反序列化
    return runtime.Decode(s.codec, resp.Kvs[0].Value, out)
}

七、Resource Version(资源版本) @

Resource Version (RV) 是 API Server 实现乐观并发控制的关键机制:

7.1 作用 @

  • 并发控制:防止多个客户端同时修改同一对象
  • Watch 机制:客户端可以通过 RV 获取增量更新
  • 一致性保证:保证读取到的数据是最新的

7.2 工作原理 @

# 客户端读取 Pod
GET /api/v1/namespaces/default/pods/my-pod
# 返回: metadata.resourceVersion = "12345"

# 客户端更新 Pod
PUT /api/v1/namespaces/default/pods/my-pod
{
  "metadata": {
    "resourceVersion": "12345"  # 必须匹配当前 RV
  },
  "spec": { ... }
}

如果 RV 不匹配,API Server 返回 409 Conflict

{
  "kind": "Status",
  "apiVersion": "v1",
  "status": "Failure",
  "message": "Operation cannot be fulfilled on pods \"my-pod\": the object has been modified; please apply your changes to the latest version and try again",
  "reason": "Conflict",
  "code": 409
}

7.3 实现 @

// staging/src/k8s.io/apiserver/pkg/storage/api_object_versioner.go
type APIObjectVersioner struct{}

func (v APIObjectVersioner) PrepareObjectForStorage(obj runtime.Object) error {
    // 写入 etcd 前清空 resourceVersion 和 selfLink;
    // 新对象的 RV 来自 etcd 写入成功后的 revision,并非固定为 1
    accessor, _ := meta.Accessor(obj)
    accessor.SetResourceVersion("")
    accessor.SetSelfLink("")
    return nil
}

func (v APIObjectVersioner) ObjectResourceVersion(obj runtime.Object) (uint64, error) {
    accessor, _ := meta.Accessor(obj)
    version := accessor.GetResourceVersion()
    if version == "" {
        return 0, nil
    }
    return strconv.ParseUint(version, 10, 64)
}

八、Watch 机制 @

Watch 是 Kubernetes 实现事件驱动的核心机制:

8.1 客户端 Watch @

// client-go 中的 Watch(由 gentype 生成的类型化客户端)
// staging/src/k8s.io/client-go/gentype/type.go
func (c *Client[T]) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
    opts.Watch = true
    // 发送 Watch 请求
    // GET /api/v1/namespaces/default/pods?watch=true&resourceVersion=12345
    return c.client.Get().
        NamespaceIfScoped(c.namespace, c.namespace != "").
        Resource(c.resource).
        VersionedParams(&opts, c.parameterCodec).
        Watch(ctx)
}

8.2 服务端 WatchCache @

// staging/src/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go
type watchCache struct {
    sync.RWMutex
    cond            *sync.Cond               // 等待缓存推进到足够新的 RV
    resourceVersion uint64                   // 缓存已推进到的 RV
    history         *watchCacheHistory       // 近期事件历史(滑动窗口)
    storage         *store.WatchCacheStorage // 对象当前状态
}

func (w *watchCache) Add(obj interface{}) error {
    // 事件 RV 取自事件对象自身的 resourceVersion
    object, resourceVersion, err := w.objectToVersionedRuntimeObject(obj)
    event := watch.Event{Type: watch.Added, Object: object}
    return w.processEvent(event, resourceVersion)
}

// 从指定 RV 开始返回事件(未导出方法,需在锁内调用)
func (w *watchCache) getAllEventsSinceLocked(resourceVersion uint64, key string, opts storage.ListOptions) (*watchCacheInterval, error) {
    ...
    return w.history.GetIntervalLocked(resourceVersion, ...)
}

8.3 Watch 事件流 @

客户端 Watch → API Server → etcd Watch
                    ↓
            WatchCache (本地缓存)
                    ↓
            事件推送给客户端

九、请求处理完整流程 @

kubectl create -f pod.yaml 为例:

1. kubectl 发送 POST 请求
   POST /api/v1/namespaces/default/pods
   Content-Type: application/json
   Authorization: Bearer <token>
   
   {
     "apiVersion": "v1",
     "kind": "Pod",
     "metadata": { "name": "my-pod" },
     "spec": { ... }
   }
       ↓
2. API Server 接收请求
       ↓
3. Filter Chain 处理:
   - WithRequestInfo: 解析请求信息
   - WithTimeout: 设置超时
   - WithCORS: 检查跨域头
   - WithAuthentication: 认证(验证 Token)
   - WithAudit: 记录审计日志
   - WithMaxInFlight/APF: 限流检查
   - WithAuthorization: 授权(检查 RBAC)
       ↓
4. Director 路由分发:
   URL 匹配 /api/v1/namespaces/{namespace}/pods → Create Handler
       ↓
5. Create Handler 处理:
   - 内容协商(JSON)
   - 反序列化请求体
   - 执行准入控制(Mutating 直接调用;Validating 传入存储层)
     - Mutating: 添加默认值
     - Validating: 验证约束
   - 调用 Storage.Create()
       ↓
6. Storage Layer:
   - Cacher: 写操作直接委托底层 etcd3 store 写入 etcd
   - 本地缓存由 reflector 对 etcd 的 watch 异步填充
       ↓
7. 返回响应:
   201 Created
   {
     "metadata": {
       "name": "my-pod",
       "namespace": "default",
       "resourceVersion": "12345",
       "creationTimestamp": "..."
     },
     "spec": { ... },
     "status": {}
   }

十、设计亮点总结 @

  • 责任链模式:Filter Chain 设计使得每个职责解耦,易于扩展。
  • 读写分离:Cacher 层实现读写分离——读从本地缓存读取(微秒级),写写入 etcd(毫秒级)。
  • 乐观并发控制:Resource Version 实现无锁并发,避免数据竞争。
  • Watch 机制:客户端通过 Watch 实时感知变化,实现事件驱动架构。
  • 插件化架构:认证、授权、准入均可插拔,支持自定义扩展。

十一、总结 @

API Server 的设计体现了几个核心思想:

  • 单一入口:所有组件通过 API Server 交互,便于审计和控制
  • 分层架构:Filter Chain → Handler → Storage,职责清晰
  • 高性能:Cacher 缓存 + Watch 机制,减少 etcd 压力
  • 可扩展:插件化架构,认证/授权/准入均可自定义
  • 一致性:Resource Version 保证并发安全

理解 API Server,就掌握了 Kubernetes 集群的"咽喉"。后续的控制器、调度器、kubelet,都是 API Server 的客户端。