kube-apiserver 核心架构与启动流程超深度分析
基于 Kubernetes 源码(
cmd/kube-apiserver、pkg/controlplane、staging/src/k8s.io/apiserver)逐行拆解
一、模块定位
1.1 API Server 的业务职责
kube-apiserver 是 Kubernetes 控制平面的唯一入口,是整个集群的"大脑皮层"。它承担以下核心职责:
| 职责 | 说明 |
|---|---|
| REST API 网关 | 对外暴露 /api、/apis 等 HTTP 端点,是所有客户端(kubectl、controller-manager、scheduler、kubelet)的唯一交互入口 |
| 认证(Authentication) | 支持 X509客户端证书、Bearer Token、Bootstrap Token、OIDC、Webhook等多种认证方式,识别请求者身份 |
| 授权(Authorization) | 支持 RBAC、ABAC、Node、Webhook 等授权模式,判定请求者是否有权执行操作 |
| 准入控制(Admission) | 在对象持久化前执行深度检查与修改,包括 Mutating 和 Validating 两大类,支持内置插件与 Webhook |
| 数据持久化 | 将所有资源对象序列化后存入 etcd,是 etcd 的唯一直接消费者 |
| Watch 机制 | 基于 HTTP 长连接实现资源的变更通知,驱动控制器模式运行 |
| API 聚合(Aggregation) | 通过 kube-aggregator 将自定义 API Server(如 metrics-server)的 API 透明代理到统一入口 |
| CRD 管理 | 通过 apiextensions-apiserver 动态注册和管理 CustomResourceDefinition |
| 服务发现 | 提供 /apis 端点列举所有已注册的 API Group 和 Version |
| 安全策略 | 限流(MaxInFlight / PriorityAndFairness)、审计(Audit)、HSTS、CORS 等 |
1.2 在 Kubernetes 架构中的位置
┌─────────────────────────────────────────────────────┐
│ 外部客户端 │
│ (kubectl / SDK / curl / UI) │
└──────────────────────┬──────────────────────────────┘
│ HTTPS
▼
┌─────────────────────────────────────────────────────┐
│ ★ kube-apiserver ★ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Aggregator Layer (kube-aggregator) │ │
│ │ ┌────────────────────────────────────────┐ │ │
│ │ │ APIExtensions Layer (CRD) │ │ │
│ │ │ ┌──────────────────────────────────┐ │ │ │
│ │ │ │ KubeAPIServer Core (内置资源) │ │ │ │
│ │ │ │ GenericAPIServer (通用框架) │ │ │ │
│ │ │ └──────────────────────────────────┘ │ │ │
│ │ └────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────┘
│ gRPC / etcd v3 client
▼
┌─────────────────────────────────────────────────────┐
│ etcd 集群 │
└─────────────────────────────────────────────────────┘
kube-apiserver 处于所有组件的中心:
- 上行:所有客户端通过它读写集群状态
- 下行:它通过 etcd client 持久化数据
- 横向:controller-manager 和 scheduler 通过 Watch 机制获取变更通知
- 它是唯一直接与 etcd 通信的组件,保证了数据一致性
二、模块整体结构
2.1 Server Chain 三层委托结构
kube-apiserver 并非单一服务器,而是三层嵌套的委托链(Delegation Chain),每一层都是一个独立的 GenericAPIServer 实例:
Aggregator Server ──delegate──▶ KubeAPIServer ──delegate──▶ APIExtensions Server ──delegate──▶ EmptyDelegate
(最外层) (核心层) (CRD层) (链尾)
请求从最外层(Aggregator)进入,逐层向内委托处理:
- Aggregator:检查是否为已注册的 APIService,若是则代理到对应的后端 API Server
- APIExtensions:检查是否为 CRD 资源,若是则由 CRD handler 处理
- KubeAPIServer:处理所有 Kubernetes 内置资源(Pod、Service、Deployment 等)
- EmptyDelegate:返回 404,链尾哨兵
#mermaid-svg-rVcPGxbSx4DbTnW6{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rVcPGxbSx4DbTnW6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rVcPGxbSx4DbTnW6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rVcPGxbSx4DbTnW6 .error-icon{fill:#552222;}#mermaid-svg-rVcPGxbSx4DbTnW6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rVcPGxbSx4DbTnW6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rVcPGxbSx4DbTnW6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rVcPGxbSx4DbTnW6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rVcPGxbSx4DbTnW6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rVcPGxbSx4DbTnW6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rVcPGxbSx4DbTnW6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rVcPGxbSx4DbTnW6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rVcPGxbSx4DbTnW6 .marker.cross{stroke:#333333;}#mermaid-svg-rVcPGxbSx4DbTnW6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rVcPGxbSx4DbTnW6 p{margin:0;}#mermaid-svg-rVcPGxbSx4DbTnW6 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rVcPGxbSx4DbTnW6 .cluster-label text{fill:#333;}#mermaid-svg-rVcPGxbSx4DbTnW6 .cluster-label span{color:#333;}#mermaid-svg-rVcPGxbSx4DbTnW6 .cluster-label span p{background-color:transparent;}#mermaid-svg-rVcPGxbSx4DbTnW6 .label text,#mermaid-svg-rVcPGxbSx4DbTnW6 span{fill:#333;color:#333;}#mermaid-svg-rVcPGxbSx4DbTnW6 .node rect,#mermaid-svg-rVcPGxbSx4DbTnW6 .node circle,#mermaid-svg-rVcPGxbSx4DbTnW6 .node ellipse,#mermaid-svg-rVcPGxbSx4DbTnW6 .node polygon,#mermaid-svg-rVcPGxbSx4DbTnW6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rVcPGxbSx4DbTnW6 .rough-node .label text,#mermaid-svg-rVcPGxbSx4DbTnW6 .node .label text,#mermaid-svg-rVcPGxbSx4DbTnW6 .image-shape .label,#mermaid-svg-rVcPGxbSx4DbTnW6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-rVcPGxbSx4DbTnW6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rVcPGxbSx4DbTnW6 .rough-node .label,#mermaid-svg-rVcPGxbSx4DbTnW6 .node .label,#mermaid-svg-rVcPGxbSx4DbTnW6 .image-shape .label,#mermaid-svg-rVcPGxbSx4DbTnW6 .icon-shape .label{text-align:center;}#mermaid-svg-rVcPGxbSx4DbTnW6 .node.clickable{cursor:pointer;}#mermaid-svg-rVcPGxbSx4DbTnW6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rVcPGxbSx4DbTnW6 .arrowheadPath{fill:#333333;}#mermaid-svg-rVcPGxbSx4DbTnW6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rVcPGxbSx4DbTnW6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rVcPGxbSx4DbTnW6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rVcPGxbSx4DbTnW6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rVcPGxbSx4DbTnW6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rVcPGxbSx4DbTnW6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rVcPGxbSx4DbTnW6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rVcPGxbSx4DbTnW6 .cluster text{fill:#333;}#mermaid-svg-rVcPGxbSx4DbTnW6 .cluster span{color:#333;}#mermaid-svg-rVcPGxbSx4DbTnW6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rVcPGxbSx4DbTnW6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rVcPGxbSx4DbTnW6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-rVcPGxbSx4DbTnW6 .icon-shape,#mermaid-svg-rVcPGxbSx4DbTnW6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rVcPGxbSx4DbTnW6 .icon-shape p,#mermaid-svg-rVcPGxbSx4DbTnW6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rVcPGxbSx4DbTnW6 .icon-shape .label rect,#mermaid-svg-rVcPGxbSx4DbTnW6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rVcPGxbSx4DbTnW6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rVcPGxbSx4DbTnW6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rVcPGxbSx4DbTnW6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Delegation Chain(委托链)
/apis/...匹配APIService
不匹配
/api/v1/...
不匹配
CRD资源
不匹配
Aggregator Server
kube-aggregator
处理 APIService 代理
KubeAPIServer
controlplane
处理内置资源
APIExtensions Server
apiextensions-apiserver
处理 CRD 资源
EmptyDelegate
返回 404
客户端请求
外部 API Server
(metrics-server等)
Core REST Storage
CRD Handler
CreateServerChain 函数解析
go
func CreateServerChain(completedOptions completedServerRunOptions, stopCh <-chan struct{}) (*aggregatorapiserver.APIAggregator, error) {
// Step 1: 创建 NodeDialer(用于 SSH 隧道或代理连接 Kubelet)
nodeTunneler, proxyTransport, err := CreateNodeDialer(completedOptions)
// Step 2: 构建 KubeAPIServer 的 Config(最核心的配置)
kubeAPIServerConfig, serviceResolver, pluginInitializer, err := CreateKubeAPIServerConfig(...)
// Step 3: 构建 APIExtensions Server 的 Config
apiExtensionsConfig, err := createAPIExtensionsConfig(...)
// Step 4: 创建 APIExtensions Server(委托给 EmptyDelegate)
apiExtensionsServer, err := createAPIExtensionsServer(apiExtensionsConfig, genericapiserver.NewEmptyDelegate())
// Step 5: 创建 KubeAPIServer(委托给 APIExtensions Server)
kubeAPIServer, err := CreateKubeAPIServer(kubeAPIServerConfig, apiExtensionsServer.GenericAPIServer)
// Step 6: 构建 Aggregator Config
aggregatorConfig, err := createAggregatorConfig(...)
// Step 7: 创建 Aggregator Server(委托给 KubeAPIServer)
aggregatorServer, err := createAggregatorServer(aggregatorConfig, kubeAPIServer.GenericAPIServer, apiExtensionsServer.Informers)
return aggregatorServer, nil
}
关键设计原则 :委托链从内到外构建,但请求从外到内流转。这种设计实现了关注点分离 和可扩展性。
2.2 Config / CompletedConfig 全字段
genericapiserver.Config(通用服务器配置)
go
type Config struct {
// ===== 核心安全配置 =====
SecureServing *SecureServingInfo // TLS 服务配置
Authentication AuthenticationInfo // 认证配置
Authorization AuthorizationInfo // 授权配置
LoopbackClientConfig *restclient.Config // 回环客户端配置(用于 PostStartHook)
EgressSelector *egressselector.EgressSelector // 出站连接选择器
// ===== 访问控制 =====
RuleResolver authorizer.RuleResolver // 规则解析器
AdmissionControl admission.Interface // 准入控制器
FlowControl utilflowcontrol.Interface // 优先级与公平性限流
// ===== 服务能力 =====
CorsAllowedOriginList []string // CORS 允许的源
HSTSDirectives []string // HSTS 指令
EnableIndex bool // 启用 / 索引页
EnableProfiling bool // 启用 pprof
EnableDiscovery bool // 启用 API 发现
EnableContentionProfiling bool // 启用锁竞争分析
EnableMetrics bool // 启用 metrics 端点
// ===== 限流与超时 =====
MaxRequestsInFlight int // 最大非变更请求并发数(默认400)
MaxMutatingRequestsInFlight int // 最大变更请求并发数(默认200)
RequestTimeout time.Duration // 请求超时(默认60s)
MinRequestTimeout int // 最小请求超时(默认1800s,用于watch)
LivezGracePeriod time.Duration // 存活检查宽限期
ShutdownDelayDuration time.Duration // 关闭延迟时长
// ===== 请求限制 =====
JSONPatchMaxCopyBytes int64 // JSON Patch 最大复制字节数(默认3MB)
MaxRequestBodyBytes int64 // 最大请求体字节数(默认3MB)
GoawayChance float64 // HTTP/2 GOAWAY 概率(0~0.02)
LongRunningFunc apirequest.LongRunningRequestCheck // 长运行请求判断函数
// ===== Handler 构建 =====
BuildHandlerChainFunc func(apiHandler http.Handler, c *Config) http.Handler
HandlerChainWaitGroup *utilwaitgroup.SafeWaitGroup
// ===== API 资源 =====
Serializer runtime.NegotiatedSerializer // 序列化器
MergedResourceConfig *serverstore.ResourceConfig // 合并的资源启用配置
RESTOptionsGetter genericregistry.RESTOptionsGetter // REST 存储选项获取器
EquivalentResourceRegistry runtime.EquivalentResourceRegistry // 等价资源注册表
// ===== OpenAPI =====
OpenAPIConfig *openapicommon.Config // OpenAPI 规范配置
SkipOpenAPIInstallation bool // 跳过 OpenAPI 安装
// ===== 健康检查 =====
HealthzChecks []healthz.HealthChecker // healthz 检查
LivezChecks []healthz.HealthChecker // livez 检查
ReadyzChecks []healthz.HealthChecker // readyz 检查
// ===== Hook =====
PostStartHooks map[string]PostStartHookConfigEntry
DisabledPostStartHooks sets.String
// ===== 元数据 =====
Version *version.Info // 版本信息
ExternalAddress string // 外部访问地址
APIServerID string // API Server 唯一标识
StorageVersionManager storageversion.Manager // 存储版本管理器
DiscoveryAddresses discovery.Addresses // 发现地址
PublicAddress net.IP // 公网地址
LegacyAPIGroupPrefixes sets.String // 旧版 API 前缀
RequestInfoResolver apirequest.RequestInfoResolver // 请求信息解析器
// ===== 审计 =====
AuditBackend audit.Backend // 审计后端
AuditPolicyChecker auditpolicy.Checker // 审计策略检查器
}
controlplane.Config / ExtraConfig(KubeAPIServer 专属配置)
go
type Config struct {
GenericConfig *genericapiserver.Config // 通用配置
ExtraConfig ExtraConfig // KubeAPIServer 扩展配置
}
type ExtraConfig struct {
// ===== 集群认证 =====
ClusterAuthenticationInfo clusterauthenticationtrust.ClusterAuthenticationInfo
// ===== 存储与资源 =====
APIResourceConfigSource serverstorage.APIResourceConfigSource
StorageFactory serverserver.StorageFactory
EventTTL time.Duration
// ===== Kubelet 通信 =====
KubeletClientConfig kubeletclient.KubeletClientConfig
Tunneler tunneler.Tunneler
// ===== 服务网络 =====
ServiceIPRange net.IPNet // Service ClusterIP 范围
APIServerServiceIP net.IP // kubernetes Service 的 ClusterIP
SecondaryServiceIPRange net.IPNet // 双栈场景的二级 Service IP 范围
APIServerServicePort int // API Server Service 端口(默认443)
ServiceNodePortRange utilnet.PortRange // NodePort 范围
KubernetesServiceNodePort int // kubernetes Service 的 NodePort
// ===== Endpoint 协调 =====
MasterCount int // Master 数量
EndpointReconcilerType reconcilers.Type // Endpoint 协调器类型
EndpointReconcilerConfig EndpointReconcilerConfig
// ===== ServiceAccount =====
ServiceAccountIssuer serviceaccount.TokenGenerator
ServiceAccountMaxExpiration time.Duration
ExtendExpiration bool
ServiceAccountIssuerURL string
ServiceAccountJWKSURI string
ServiceAccountPublicKeys []interface{}
// ===== 其他 =====
EnableLogsSupport bool
ProxyTransport http.RoundTripper
VersionedInformers informers.SharedInformerFactory
IdentityLeaseDurationSeconds int
IdentityLeaseRenewIntervalSeconds int
}
completedConfig 模式
Kubernetes 使用 private struct + public wrapper 模式来强制"Complete→New"调用顺序:
go
// 私有结构体,外部无法直接构造
type completedConfig struct {
GenericConfig genericapiserver.CompletedConfig
ExtraConfig *ExtraConfig
}
// 公开包装,嵌入私有指针
type CompletedConfig struct {
*completedConfig // 外部只能通过 Config.Complete() 获得
}
// 同理,genericapiserver 也有相同模式:
type completedConfig struct { *Config; SharedInformerFactory informers.SharedInformerFactory }
type CompletedConfig struct { *completedConfig }
这种设计确保:你必须先调用 Complete() 填充默认值,然后才能用 New() 创建服务器实例------在编译期而非运行期强制约束。
2.3 ServerRunOptions 全字段
go
type ServerRunOptions struct {
// ===== 通用服务选项 =====
GenericServerRunOptions *genericoptions.ServerRunOptions
// 包含:AdvertiseAddress, CorsAllowedOriginList, HSTSDirectives, ExternalHost,
// MaxRequestsInFlight, MaxMutatingRequestsInFlight, RequestTimeout,
// GoawayChance, LivezGracePeriod, MinRequestTimeout, ShutdownDelayDuration,
// JSONPatchMaxCopyBytes, MaxRequestBodyBytes, EnablePriorityAndFairness
// ===== 存储选项 =====
Etcd *genericoptions.EtcdOptions
// 包含:StorageConfig(ServerList, Prefix, Codec等), EnableWatchCache, WatchCacheSizes等
// ===== 安全服务选项 =====
SecureServing *genericoptions.SecureServingOptionsWithLoopback
// 包含:BindAddress, BindPort, ServerCert, SNICertKeys等
// ===== 功能选项 =====
Features *genericoptions.FeatureOptions
// 包含:EnableWatchCache, APIEnablement等
// ===== 审计选项 =====
Audit *genericoptions.AuditOptions
// 包含:LogOptions, WebhookOptions, PolicyFile等
// ===== 准入控制选项 =====
Admission *kubeoptions.AdmissionOptions
// 包含:RecommendedAdmissionOptions(插件名列表、配置文件等)
// ===== 认证选项 =====
Authentication *kubeoptions.BuiltInAuthenticationOptions
// 包含:ClientCert, TokenFile, OIDC, ServiceAccounts, RequestHeader等
// ===== 授权选项 =====
Authorization *kubeoptions.BuiltInAuthorizationOptions
// 包含:Modes(RBAC,ABAC,Node,Webhook), PolicyFile, WebhookConfigFile等
// ===== 云提供商选项 =====
CloudProvider *kubeoptions.CloudProviderOptions
// ===== API 启用选项 =====
APIEnablement *genericoptions.APIEnablementOptions
// 包含:RuntimeConfig(map[string]bool)
// ===== 出站选择器 =====
EgressSelector *genericoptions.EgressSelectorOptions
// ===== 监控与日志 =====
Metrics *metrics.Options
Logs *logs.Options
// ===== KubeAPIServer 专属 =====
AllowPrivileged bool
EnableLogsHandler bool
EventTTL time.Duration // 默认 1h
KubeletConfig kubeletclient.KubeletClientConfig
KubernetesServiceNodePort int
MaxConnectionBytesPerSec int64
ServiceClusterIPRanges string // 用户输入
PrimaryServiceClusterIPRange net.IPNet // 解析后的主范围
SecondaryServiceClusterIPRange net.IPNet // 解析后的次范围
ServiceNodePortRange utilnet.PortRange // 默认 30000-32767
SSHKeyfile string // 已废弃
SSHUser string // 已废弃
ProxyClientCertFile string
ProxyClientKeyFile string
EnableAggregatorRouting bool
MasterCount int // 默认 1
EndpointReconcilerType string // 默认 "lease"
IdentityLeaseDurationSeconds int // 默认 3600
IdentityLeaseRenewIntervalSeconds int // 默认 10
ServiceAccountSigningKeyFile string
ServiceAccountIssuer serviceaccount.TokenGenerator
ServiceAccountTokenMaxExpiration time.Duration
ShowHiddenMetricsForVersion string
}
2.4 依赖注入关系
#mermaid-svg-nuZSotO9MP7ynQAs{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-nuZSotO9MP7ynQAs .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nuZSotO9MP7ynQAs .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nuZSotO9MP7ynQAs .error-icon{fill:#552222;}#mermaid-svg-nuZSotO9MP7ynQAs .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nuZSotO9MP7ynQAs .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nuZSotO9MP7ynQAs .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nuZSotO9MP7ynQAs .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nuZSotO9MP7ynQAs .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nuZSotO9MP7ynQAs .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nuZSotO9MP7ynQAs .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nuZSotO9MP7ynQAs .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nuZSotO9MP7ynQAs .marker.cross{stroke:#333333;}#mermaid-svg-nuZSotO9MP7ynQAs svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nuZSotO9MP7ynQAs p{margin:0;}#mermaid-svg-nuZSotO9MP7ynQAs .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-nuZSotO9MP7ynQAs .cluster-label text{fill:#333;}#mermaid-svg-nuZSotO9MP7ynQAs .cluster-label span{color:#333;}#mermaid-svg-nuZSotO9MP7ynQAs .cluster-label span p{background-color:transparent;}#mermaid-svg-nuZSotO9MP7ynQAs .label text,#mermaid-svg-nuZSotO9MP7ynQAs span{fill:#333;color:#333;}#mermaid-svg-nuZSotO9MP7ynQAs .node rect,#mermaid-svg-nuZSotO9MP7ynQAs .node circle,#mermaid-svg-nuZSotO9MP7ynQAs .node ellipse,#mermaid-svg-nuZSotO9MP7ynQAs .node polygon,#mermaid-svg-nuZSotO9MP7ynQAs .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-nuZSotO9MP7ynQAs .rough-node .label text,#mermaid-svg-nuZSotO9MP7ynQAs .node .label text,#mermaid-svg-nuZSotO9MP7ynQAs .image-shape .label,#mermaid-svg-nuZSotO9MP7ynQAs .icon-shape .label{text-anchor:middle;}#mermaid-svg-nuZSotO9MP7ynQAs .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-nuZSotO9MP7ynQAs .rough-node .label,#mermaid-svg-nuZSotO9MP7ynQAs .node .label,#mermaid-svg-nuZSotO9MP7ynQAs .image-shape .label,#mermaid-svg-nuZSotO9MP7ynQAs .icon-shape .label{text-align:center;}#mermaid-svg-nuZSotO9MP7ynQAs .node.clickable{cursor:pointer;}#mermaid-svg-nuZSotO9MP7ynQAs .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-nuZSotO9MP7ynQAs .arrowheadPath{fill:#333333;}#mermaid-svg-nuZSotO9MP7ynQAs .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-nuZSotO9MP7ynQAs .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-nuZSotO9MP7ynQAs .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nuZSotO9MP7ynQAs .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-nuZSotO9MP7ynQAs .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nuZSotO9MP7ynQAs .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-nuZSotO9MP7ynQAs .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-nuZSotO9MP7ynQAs .cluster text{fill:#333;}#mermaid-svg-nuZSotO9MP7ynQAs .cluster span{color:#333;}#mermaid-svg-nuZSotO9MP7ynQAs div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-nuZSotO9MP7ynQAs .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-nuZSotO9MP7ynQAs rect.text{fill:none;stroke-width:0;}#mermaid-svg-nuZSotO9MP7ynQAs .icon-shape,#mermaid-svg-nuZSotO9MP7ynQAs .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nuZSotO9MP7ynQAs .icon-shape p,#mermaid-svg-nuZSotO9MP7ynQAs .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-nuZSotO9MP7ynQAs .icon-shape .label rect,#mermaid-svg-nuZSotO9MP7ynQAs .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nuZSotO9MP7ynQAs .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-nuZSotO9MP7ynQAs .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-nuZSotO9MP7ynQAs :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Server 层
Config 层
Options 层
ApplyTo
ApplyWithStorageFactoryTo
ApplyTo
ApplyTo
BuildAuthorizer→
ApplyTo
ApplyTo
Complete().New()
shallow copy
shallow copy
Complete().New()
Complete().NewWithDelegate()
ServerRunOptions
GenericServerRunOptions
EtcdOptions
SecureServingOptions
BuiltInAuthenticationOptions
BuiltInAuthorizationOptions
AdmissionOptions
FeatureOptions
genericapiserver.Config
controlplane.ExtraConfig
controlplane.Config
apiextensionsapiserver.Config
aggregatorapiserver.Config
GenericAPIServer
controlplane.Instance
(KubeAPIServer)
CustomResourceDefinitions
APIAggregator
关键依赖注入点:
- StorageFactory →
EtcdOptions→Config.RESTOptionsGetter→ 各 RESTStorage - Authenticator →
AuthenticationOptions.ApplyTo()→Config.Authentication.Authenticator - Authorizer →
AuthorizationOptions.ToAuthorizationConfig().New()→Config.Authorization.Authorizer - AdmissionControl →
AdmissionOptions.ApplyTo()→Config.AdmissionControl - VersionedInformers →
LoopbackClientConfig→clientgoclientset→Config.ExtraConfig.VersionedInformers - FlowControl →
BuildPriorityAndFairness()→Config.FlowControl(需 APIPriorityAndFairness FeatureGate) - ServiceResolver →
buildServiceResolver()→AggregatorConfig.ExtraConfig.ServiceResolver
2.5 核心方法清单
| 方法 | 位置 | 作用 |
|---|---|---|
NewAPIServerCommand() |
server.go | 创建 cobra.Command,定义 CLI 入口 |
Complete() |
server.go | 填充默认值,返回 completedServerRunOptions |
Run() |
server.go | 启动入口:CreateServerChain→PrepareRun→Run |
CreateServerChain() |
server.go | 构建三层委托链 |
CreateNodeDialer() |
server.go | 创建 SSH 隧道/代理传输 |
CreateKubeAPIServerConfig() |
server.go | 构建 KubeAPIServer 配置 |
buildGenericConfig() |
server.go | 构建通用配置(认证/授权/存储/准入等) |
BuildAuthorizer() |
server.go | 构建授权器 |
BuildPriorityAndFairness() |
server.go | 构建限流器 |
createAPIExtensionsConfig() |
apiextensions.go | 构建 CRD Server 配置 |
createAPIExtensionsServer() |
apiextensions.go | 创建 CRD Server |
createAggregatorConfig() |
aggregator.go | 构建 Aggregator 配置 |
createAggregatorServer() |
aggregator.go | 创建 Aggregator Server + 自动注册控制器 |
Config.Complete() |
config.go | 完善通用配置 |
completedConfig.New() |
config.go | 创建 GenericAPIServer 实例 |
GenericAPIServer.PrepareRun() |
genericapiserver.go | 安装健康检查、OpenAPI |
preparedGenericAPIServer.Run() |
genericapiserver.go | 启动 HTTP 服务 |
GenericAPIServer.InstallLegacyAPIGroup() |
genericapiserver.go | 安装 /api/v1 资源 |
GenericAPIServer.InstallAPIGroups() |
genericapiserver.go | 安装 /apis/* 资源 |
controlplane.Config.Complete() |
instance.go | 完善 KubeAPIServer 配置 |
completedConfig.New() |
instance.go | 创建 KubeAPIServer 实例+注册 PostStartHook |
2.6 数据流入流出
┌─────────────┐
│ 外部客户端 │──HTTPS──▶┌──────────────────────────────────────────────┐
│ (kubectl等) │ │ kube-apiserver │
└─────────────┘ │ │
│ 请求流向: │
│ Client ──▶ FullHandlerChain ──▶ Director │
│ │ │ │
│ │ Filter Chain: │ │
│ │ RequestReceivedTimestamp │ │
│ │ → PanicRecovery │ │
│ │ → RequestInfo │ │
│ │ → WaitGroup │ │
│ │ → RequestDeadline │ │
│ │ → TimeoutForNonLongRunning │ │
│ │ → CORS │ │
│ │ → Authentication ◄─── 认证信息 │ │
│ │ → Audit ◄───────── 审计策略 │ │
│ │ → Impersonation │ │
│ │ → MaxInFlight/PriorityAndFairness │ │
│ │ → Authorization ◄─── 授权信息 │ │
│ │ → StorageVersionPrecondition │ │
│ │ │ │
│ │ Director 路由: │ │
│ │ GoRestfulContainer ──▶ REST Storage │ │
│ │ NonGoRestfulMux ──▶ 其他 Handler │ │
│ │
│ 数据持久化: │
│ REST Storage ──▶ etcd3 ──▶ etcd 集群 │
│ │
│ Watch 通知: │
│ etcd Watch ──▶ Cacher ──▶ HTTP Chunked │
└──────────────────────────────────────────────┘
响应流向:
etcd ──▶ Decoder ──▶ Serializer ──▶ HTTP Response ──▶ Client
审计流向:
Request ──▶ Audit Policy Check ──▶ Audit Backend(Log/Webhook)
三、核心业务逻辑深度解析
3.1 main() → NewAPIServerCommand → Run → CreateServerChain 完整流程逐行解析
3.1.1 入口函数(隐式 main)
Kubernetes 的 cmd/kube-apiserver/apiserver.go 中:
go
func main() {
command := app.NewAPIServerCommand()
code := cli.Run(command)
os.Exit(code)
}
3.1.2 NewAPIServerCommand --- 创建 Cobra 命令
go
func NewAPIServerCommand() *cobra.Command {
// 1. 创建默认 ServerRunOptions(所有配置的默认值在此确定)
s := options.NewServerRunOptions()
// 具体默认值:
// - MaxRequestsInFlight = 400
// - MaxMutatingRequestsInFlight = 200
// - RequestTimeout = 60s
// - MinRequestTimeout = 1800
// - EventTTL = 1h
// - MasterCount = 1
// - EndpointReconcilerType = "lease"
// - Etcd.DefaultStorageMediaType = "application/vnd.kubernetes.protobuf"
// - ServiceNodePortRange = 30000-32767
cmd := &cobra.Command{
Use: "kube-apiserver",
Long: `The Kubernetes API server validates and configures data...`,
SilenceUsage: true,
// PersistentPreRunE: 静默 client-go 警告(回环客户端不应产生自生警告)
PersistentPreRunE: func(*cobra.Command, []string) error {
rest.SetDefaultWarningHandler(rest.NoWarnings{})
return nil
},
// RunE: 核心执行逻辑
RunE: func(cmd *cobra.Command, args []string) error {
verflag.PrintAndExitIfRequested() // 处理 --version
cliflag.PrintFlags(fs) // 打印所有 flag 值(调试用)
checkNonZeroInsecurePort(fs) // 确保 insecure-port=0(已废弃)
// ★ Complete:填充默认值,转换选项
completedOptions, err := Complete(s)
// ★ Validate:校验所有选项
if errs := completedOptions.Validate(); len(errs) != 0 {
return utilerrors.NewAggregate(errs)
}
// ★ Run:启动服务器
return Run(completedOptions, genericapiserver.SetupSignalHandler())
// ↑ SetupSignalHandler() 返回 stopCh,
// 监听 SIGINT/SIGTERM 信号
},
}
// 注册所有 flag
fs := cmd.Flags()
namedFlagSets := s.Flags() // 分组注册:generic/etcd/secure serving/authentication/...
// 添加版本flag、全局flag、自定义全局flag
for _, f := range namedFlagSets.FlagSets {
fs.AddFlagSet(f)
}
return cmd
}
3.1.3 Complete --- 选项补全
go
func Complete(s *options.ServerRunOptions) (completedServerRunOptions, error) {
// 1. 设置默认 AdvertiseAddress(若未指定,从 SecureServing 获取)
s.GenericServerRunOptions.DefaultAdvertiseAddress(s.SecureServing.SecureServingOptions)
// 2. 解析 ServiceClusterIPRanges → Primary + Secondary
// 支持双栈:如 "10.0.0.0/24,fd00::/108"
apiServerServiceIP, primaryRange, secondaryRange, err := getServiceIPAndRanges(s.ServiceClusterIPRanges)
s.PrimaryServiceClusterIPRange = primaryRange
s.SecondaryServiceClusterIPRange = secondaryRange
// 3. 若未提供 TLS 证书,自动生成自签名证书
s.SecureServing.MaybeDefaultWithSelfSignedCerts(
s.GenericServerRunOptions.AdvertiseAddress.String(),
[]string{"kubernetes.default.svc", "kubernetes.default", "kubernetes"},
[]net.IP{apiServerServiceIP},
)
// 4. 确定 ExternalHost
if len(s.GenericServerRunOptions.ExternalHost) == 0 {
if len(s.GenericServerRunOptions.AdvertiseAddress) > 0 {
s.GenericServerRunOptions.ExternalHost = s.GenericServerRunOptions.AdvertiseAddress.String()
} else {
hostname, _ := os.Hostname()
s.GenericServerRunOptions.ExternalHost = hostname
}
}
// 5. Authentication.ApplyAuthorization --- 让认证选项知道授权模式
s.Authentication.ApplyAuthorization(s.Authorization)
// 6. ServiceAccount 签名密钥处理
// 若未设置 ServiceAccountSigningKeyFile,尝试使用 TLS 私钥
if s.ServiceAccountSigningKeyFile == "" {
if len(s.Authentication.ServiceAccounts.KeyFiles) == 0 && s.SecureServing.ServerCert.CertKey.KeyFile != "" {
if kubeauthenticator.IsValidServiceAccountKeyFile(s.SecureServing.ServerCert.CertKey.KeyFile) {
s.Authentication.ServiceAccounts.KeyFiles = []string{s.SecureServing.ServerCert.CertKey.KeyFile}
}
}
}
// 7. 构建 ServiceAccount Issuer(JWT Token Generator)
if s.ServiceAccountSigningKeyFile != "" && s.Authentication.ServiceAccounts.Issuer != "" {
sk, _ := keyutil.PrivateKeyFromFile(s.ServiceAccountSigningKeyFile)
// 校验 MaxExpiration 范围:[1h, 2^32s]
s.ServiceAccountIssuer, _ = serviceaccount.JWTTokenGenerator(s.Authentication.ServiceAccounts.Issuer, sk)
s.ServiceAccountTokenMaxExpiration = s.Authentication.ServiceAccounts.MaxExpiration
}
// 8. WatchCache 大小配置
if s.Etcd.EnableWatchCache {
sizes := kubeapiserver.DefaultWatchCacheSizes()
userSpecified, _ := serveroptions.ParseWatchCacheSizes(s.Etcd.WatchCacheSizes)
for resource, size := range userSpecified {
sizes[resource] = size // 用户覆盖默认值
}
s.Etcd.WatchCacheSizes, _ = serveroptions.WriteWatchCacheSizes(sizes)
}
// 9. 规范化 RuntimeConfig 中的 v1 前缀
// "v1" → "/v1", "api/v1" → "/v1", 删除 "api/legacy"
return completedServerRunOptions{ServerRunOptions: s}, nil
}
3.1.4 Run --- 启动服务器
go
func Run(completeOptions completedServerRunOptions, stopCh <-chan struct{}) error {
klog.Infof("Version: %+v", version.Get()) // 打印版本信息
// ★ Step 1: 创建 Server Chain(三层委托链)
server, err := CreateServerChain(completeOptions, stopCh)
// ★ Step 2: 准备运行(安装健康检查、OpenAPI等)
prepared, err := server.PrepareRun()
// ★ Step 3: 运行服务器(阻塞直到 stopCh 关闭)
return prepared.Run(stopCh)
}
3.1.5 CreateServerChain --- 构建三层委托链
这是最核心的函数,下面逐步拆解:
执行顺序:
1. CreateNodeDialer → 创建节点通信基础设施
2. CreateKubeAPIServerConfig → 构建核心配置
3. createAPIExtensionsConfig → 构建CRD配置
4. createAPIExtensionsServer → 创建CRD Server(delegate=EmptyDelegate)
5. CreateKubeAPIServer → 创建核心Server(delegate=CRD Server)
6. createAggregatorConfig → 构建聚合配置
7. createAggregatorServer → 创建聚合Server(delegate=KubeAPIServer)
Step 1: CreateNodeDialer --- 创建节点拨号器
go
func CreateNodeDialer(s completedServerRunOptions) (tunneler.Tunneler, *http.Transport, error) {
var nodeTunneler tunneler.Tunneler
var proxyDialerFn utilnet.DialFunc
// 如果配置了 SSHUser,则建立 SSH 隧道
if len(s.SSHUser) > 0 {
// 初始化云提供商(获取 AddSSHKeyToAllInstances 方法)
cloud, _ := cloudprovider.InitCloudProvider(s.CloudProvider.CloudProvider, ...)
// 创建 Tunneler
nodeTunneler = tunneler.New(s.SSHUser, s.SSHKeyfile, healthCheckPath, installSSHKey)
proxyDialerFn = nodeTunneler.Dial
}
// 创建代理 Transport(InsecureSkipVerify=true,因为代理目标IP不可预知主机名)
proxyTransport := &http.Transport{
DialContext: proxyDialerFn,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
return nodeTunneler, proxyTransport, nil
}
Step 2: CreateKubeAPIServerConfig --- 构建核心配置
go
func CreateKubeAPIServerConfig(s completedServerRunOptions, nodeTunneler tunneler.Tunneler, proxyTransport *http.Transport) (...) {
// ★ 核心调用:buildGenericConfig
genericConfig, versionedInformers, serviceResolver, pluginInitializers, admissionPostStartHook, storageFactory, err := buildGenericConfig(s.ServerRunOptions, proxyTransport)
// etcd 连接预检(重试60次,间隔1秒)
utilwait.PollImmediate(etcdRetryInterval, etcdRetryLimit*etcdRetryInterval,
preflight.EtcdConnection{ServerList: ...}.CheckEtcdServers)
// 初始化 capabilities(AllowPrivileged 等)
capabilities.Initialize(capabilities.Capabilities{...})
// 应用 metrics 和 logs 配置
s.Metrics.Apply()
s.Logs.Apply()
// 解析 Service IP 范围
serviceIPRange, apiServerServiceIP, _ := controlplane.ServiceIPRange(s.PrimaryServiceClusterIPRange)
// 构建 controlplane.Config
config := &controlplane.Config{
GenericConfig: genericConfig,
ExtraConfig: controlplane.ExtraConfig{
APIResourceConfigSource: storageFactory.APIResourceConfigSource,
StorageFactory: storageFactory,
EventTTL: s.EventTTL,
ServiceIPRange: serviceIPRange,
APIServerServiceIP: apiServerServiceIP,
// ... 其他字段
},
}
// 提取 ClientCA 和 RequestHeader 配置到 ClusterAuthenticationInfo
clientCAProvider, _ := s.Authentication.ClientCert.GetClientCAContentProvider()
config.ExtraConfig.ClusterAuthenticationInfo.ClientCA = clientCAProvider
requestHeaderConfig, _ := s.Authentication.RequestHeader.ToAuthenticationRequestHeaderConfig()
config.ExtraConfig.ClusterAuthenticationInfo.RequestHeaderCA = requestHeaderConfig.CAContentProvider
// ... 其他 RequestHeader 字段
// 添加准入初始化 PostStartHook
config.GenericConfig.AddPostStartHook("start-kube-apiserver-admission-initializer", admissionPostStartHook)
// 处理 EgressSelector(出站流量控制)
if config.GenericConfig.EgressSelector != nil {
config.ExtraConfig.KubeletClientConfig.Lookup = config.GenericConfig.EgressSelector.Lookup
// 修改 ProxyTransport 的 DialContext
}
// 加载 ServiceAccount 公钥
var pubKeys []interface{}
for _, f := range s.Authentication.ServiceAccounts.KeyFiles {
keys, _ := keyutil.PublicKeysFromFile(f)
pubKeys = append(pubKeys, keys...)
}
config.ExtraConfig.ServiceAccountPublicKeys = pubKeys
return config, serviceResolver, pluginInitializers, nil
}
buildGenericConfig --- 最核心的配置构建函数:
go
func buildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transport) (...) {
// 1. 创建通用 Config
genericConfig = genericapiserver.NewConfig(legacyscheme.Codecs)
genericConfig.MergedResourceConfig = controlplane.DefaultAPIResourceConfigSource()
// 2. 依次 Apply 各 Options
s.GenericServerRunOptions.ApplyTo(genericConfig) // 地址、限流、超时
s.SecureServing.ApplyTo(&genericConfig.SecureServing, &genericConfig.LoopbackClientConfig)
s.Features.ApplyTo(genericConfig) // WatchCache
s.APIEnablement.ApplyTo(genericConfig, ...) // 资源启用
s.EgressSelector.ApplyTo(genericConfig) // 出站选择
// 3. 设置 OpenAPI 配置
genericConfig.OpenAPIConfig = genericapiserver.DefaultOpenAPIConfig(
generatedopenapi.GetOpenAPIDefinitions,
openapinamer.NewDefinitionNamer(legacyscheme.Scheme, extensionsapiserver.Scheme, aggregatorscheme.Scheme),
)
genericConfig.OpenAPIConfig.Info.Title = "Kubernetes"
// 4. 设置长运行请求判断函数
genericConfig.LongRunningFunc = filters.BasicLongRunningRequestCheck(
sets.NewString("watch", "proxy"), // 长运行 verbs
sets.NewString("attach", "exec", "proxy", "log", "portforward"), // 长运行 subresources
)
// 5. 构建 StorageFactory
storageFactoryConfig := kubeapiserver.NewStorageFactoryConfig()
completedStorageFactoryConfig, _ := storageFactoryConfig.Complete(s.Etcd)
storageFactory, _ = completedStorageFactoryConfig.New()
s.Etcd.ApplyWithStorageFactoryTo(storageFactory, genericConfig)
// 6. 配置回环客户端(用 protobuf 自通信,禁用压缩)
genericConfig.LoopbackClientConfig.ContentConfig.ContentType = "application/vnd.kubernetes.protobuf"
genericConfig.LoopbackClientConfig.DisableCompression = true
// 7. 创建外部 clientset 和 SharedInformerFactory
clientgoExternalClient, _ := clientgoclientset.NewForConfig(genericConfig.LoopbackClientConfig)
versionedInformers = clientgoinformers.NewSharedInformerFactory(clientgoExternalClient, 10*time.Minute)
// 8. 认证配置
s.Authentication.ApplyTo(&genericConfig.Authentication, genericConfig.SecureServing,
genericConfig.EgressSelector, genericConfig.OpenAPIConfig, clientgoExternalClient, versionedInformers)
// 9. 授权配置
genericConfig.Authorization.Authorizer, genericConfig.RuleResolver, _ = BuildAuthorizer(s, genericConfig.EgressSelector, versionedInformers)
// 10. 若未启用 RBAC,禁用 RBAC PostStartHook
if !sets.NewString(s.Authorization.Modes...).Has(modes.ModeRBAC) {
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
}
// 11. 审计配置
s.Audit.ApplyTo(genericConfig)
// 12. 准入控制配置
admissionConfig := &kubeapiserveradmission.Config{
ExternalInformers: versionedInformers,
LoopbackClientConfig: genericConfig.LoopbackClientConfig,
CloudConfigFile: s.CloudProvider.CloudConfigFile,
}
serviceResolver = buildServiceResolver(s.EnableAggregatorRouting, ...)
pluginInitializers, admissionPostStartHook, _ = admissionConfig.New(proxyTransport, genericConfig.EgressSelector, serviceResolver)
s.Admission.ApplyTo(genericConfig, versionedInformers, kubeClientConfig, feature.DefaultFeatureGate, pluginInitializers...)
// 13. 优先级与公平性限流
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIPriorityAndFairness) && s.GenericServerRunOptions.EnablePriorityAndFairness {
genericConfig.FlowControl = BuildPriorityAndFairness(s, clientgoExternalClient, versionedInformers)
}
return
}
3.2 CreateServerChain 三层委托链深度解析
createAggregatorServer createAggregatorConfig CreateKubeAPIServer createAPIExtensionsServer createAPIExtensionsConfig buildGenericConfig CreateKubeAPIServerConfig CreateNodeDialer CreateServerChain Run() createAggregatorServer createAggregatorConfig CreateKubeAPIServer createAPIExtensionsServer createAPIExtensionsConfig buildGenericConfig CreateKubeAPIServerConfig CreateNodeDialer CreateServerChain Run() #mermaid-svg-qquhNW5fJgq5ypdM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qquhNW5fJgq5ypdM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qquhNW5fJgq5ypdM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qquhNW5fJgq5ypdM .error-icon{fill:#552222;}#mermaid-svg-qquhNW5fJgq5ypdM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qquhNW5fJgq5ypdM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qquhNW5fJgq5ypdM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qquhNW5fJgq5ypdM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qquhNW5fJgq5ypdM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qquhNW5fJgq5ypdM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qquhNW5fJgq5ypdM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qquhNW5fJgq5ypdM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qquhNW5fJgq5ypdM .marker.cross{stroke:#333333;}#mermaid-svg-qquhNW5fJgq5ypdM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qquhNW5fJgq5ypdM p{margin:0;}#mermaid-svg-qquhNW5fJgq5ypdM .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qquhNW5fJgq5ypdM text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-qquhNW5fJgq5ypdM .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qquhNW5fJgq5ypdM .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-qquhNW5fJgq5ypdM .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-qquhNW5fJgq5ypdM .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-qquhNW5fJgq5ypdM #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-qquhNW5fJgq5ypdM .sequenceNumber{fill:white;}#mermaid-svg-qquhNW5fJgq5ypdM #sequencenumber{fill:#333;}#mermaid-svg-qquhNW5fJgq5ypdM #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-qquhNW5fJgq5ypdM .messageText{fill:#333;stroke:none;}#mermaid-svg-qquhNW5fJgq5ypdM .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qquhNW5fJgq5ypdM .labelText,#mermaid-svg-qquhNW5fJgq5ypdM .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-qquhNW5fJgq5ypdM .loopText,#mermaid-svg-qquhNW5fJgq5ypdM .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-qquhNW5fJgq5ypdM .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qquhNW5fJgq5ypdM .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-qquhNW5fJgq5ypdM .noteText,#mermaid-svg-qquhNW5fJgq5ypdM .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-qquhNW5fJgq5ypdM .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qquhNW5fJgq5ypdM .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qquhNW5fJgq5ypdM .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qquhNW5fJgq5ypdM .actorPopupMenu{position:absolute;}#mermaid-svg-qquhNW5fJgq5ypdM .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-qquhNW5fJgq5ypdM .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qquhNW5fJgq5ypdM .actor-man circle,#mermaid-svg-qquhNW5fJgq5ypdM line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-qquhNW5fJgq5ypdM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} NewConfig → ApplyTo(各Options)→ StorageFactory → Clientset→ Authentication → Authorization→ Audit → Admission → FlowControl 清空PostStartHooks覆盖RESTOptionsGetter覆盖Codec为apiextensions scheme覆盖MergedResourceConfig Config.Complete().New(EmptyDelegate) Config.Complete().New(delegate)→ 安装LegacyAPI(/api/v1)→ 安装APIGroups(/apis/*)→ 注册PostStartHooks 清空PostStartHooksSkipOpenAPIInstallation=true覆盖RESTOptionsGetter覆盖Codec为aggregator scheme Config.Complete().NewWithDelegate(delegate)→ 创建自动注册控制器→ 注册APIService→ 注册CRDRegistrationController 调用创建 NodeDialer + ProxyTransport创建 KubeAPIServerConfigbuildGenericConfiggenericConfig + informers + resolver + pluginsconfig + serviceResolver + pluginInitializers创建 APIExtensionsConfig(shallow copy genericConfig)apiExtensionsConfigcreateAPIExtensionsServer(delegate=EmptyDelegate)apiExtensionsServerCreateKubeAPIServer(delegate=apiExtensionsServer.GenericAPIServer)kubeAPIServer创建 AggregatorConfig(shallow copy genericConfig)aggregatorConfigcreateAggregatorServer(delegate=kubeAPIServer.GenericAPIServer)aggregatorServer
3.2.1 APIExtensions Server 构建
go
func createAPIExtensionsConfig(kubeAPIServerConfig genericapiserver.Config, ...) (*apiextensionsapiserver.Config, error) {
// ★ 关键:浅拷贝 genericConfig
genericConfig := kubeAPIServerConfig
// 清空 PostStartHooks(避免重复注册)
genericConfig.PostStartHooks = map[string]genericapiserver.PostStartHookConfigEntry{}
// 清空 RESTOptionsGetter(后面用自己的)
genericConfig.RESTOptionsGetter = nil
// 重新应用 Admission(使用 apiextensions 自己的 scheme)
commandOptions.Admission.ApplyTo(&genericConfig, ...)
// 覆盖 Etcd 配置:使用 apiextensions 的 Codec
etcdOptions := *commandOptions.Etcd
etcdOptions.StorageConfig.Codec = apiextensionsapiserver.Codecs.LegacyCodec(v1beta1, v1)
etcdOptions.StorageConfig.EncodeVersioner = runtime.NewMultiGroupVersioner(v1beta1.SchemeGroupVersion, ...)
genericConfig.RESTOptionsGetter = &genericoptions.SimpleRestOptionsFactory{Options: etcdOptions}
// 覆盖 MergedResourceConfig
commandOptions.APIEnablement.ApplyTo(&genericConfig,
apiextensionsapiserver.DefaultAPIResourceConfigSource(),
apiextensionsapiserver.Scheme)
return &apiextensionsapiserver.Config{
GenericConfig: &genericapiserver.RecommendedConfig{
Config: genericConfig,
SharedInformerFactory: externalInformers,
},
ExtraConfig: apiextensionsapiserver.ExtraConfig{
CRDRESTOptionsGetter: ...,
MasterCount: masterCount,
AuthResolverWrapper: authResolverWrapper,
ServiceResolver: serviceResolver,
},
}, nil
}
3.2.2 KubeAPIServer 构建
go
func CreateKubeAPIServer(kubeAPIServerConfig *controlplane.Config, delegateAPIServer genericapiserver.DelegationTarget) (*controlplane.Instance, error) {
// Config.Complete() → CompletedConfig
// CompletedConfig.New(delegate) → Instance
return kubeAPIServerConfig.Complete().New(delegateAPIServer)
}
completedConfig.New() 做了以下事情:
- 调用
GenericConfig.New("kube-apiserver", delegate)创建GenericAPIServer - 安装 Logs 路由(如启用)
- 安装 OpenID 元数据端点
- 安装 Legacy API(/api/v1):Pod、Service、Node、ConfigMap 等
- 安装 API Groups(/apis/*):apps、batch、rbac 等 18 个组
- 安装 Tunneler(如有)
- 注册 PostStartHook:
start-cluster-authentication-info-controller - 注册 PostStartHook:
start-kube-apiserver-identity-lease-controller(如 APIServerIdentity FeatureGate 启用) - 注册 PostStartHook:
start-kube-apiserver-identity-lease-garbage-collector
3.2.3 Aggregator Server 构建
go
func createAggregatorServer(aggregatorConfig *aggregatorapiserver.Config, delegateAPIServer genericapiserver.DelegationTarget, ...) (*aggregatorapiserver.APIAggregator, error) {
// 创建 Aggregator Server
aggregatorServer, _ := aggregatorConfig.Complete().NewWithDelegate(delegateAPIServer)
// 创建自动注册控制器
autoRegistrationController := autoregister.NewAutoRegisterController(...)
apiServices := apiServicesToRegister(delegateAPIServer, autoRegistrationController)
// 创建 CRD 注册控制器
crdRegistrationController := crdregistration.NewCRDRegistrationController(...)
// 注册 PostStartHook:自动注册 APIService
aggregatorServer.GenericAPIServer.AddPostStartHook("kube-apiserver-autoregistration", func(context) error {
go crdRegistrationController.Run(5, context.StopCh)
go func() {
// 等待 CRD 初始同步完成后再启动自动注册
if aggregatorConfig.GenericConfig.MergedResourceConfig.AnyVersionForGroupEnabled("apiextensions.k8s.io") {
crdRegistrationController.WaitForInitialSync()
}
autoRegistrationController.Run(5, context.StopCh)
}()
return nil
})
// 添加 APIService 可用性健康检查
aggregatorServer.GenericAPIServer.AddBootSequenceHealthChecks(
makeAPIServiceAvailableHealthCheck("autoregister-completion", apiServices, ...))
return aggregatorServer, nil
}
3.3 GenericServer 构建过程
go
func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*GenericAPIServer, error) {
// 前置检查
if c.Serializer == nil { return nil, fmt.Errorf("Serializer == nil") }
if c.LoopbackClientConfig == nil { return nil, fmt.Errorf("LoopbackClientConfig == nil") }
if c.EquivalentResourceRegistry == nil { return nil, fmt.Errorf("EquivalentResourceRegistry == nil") }
// ★ 构建 Handler Chain Builder
handlerChainBuilder := func(handler http.Handler) http.Handler {
return c.BuildHandlerChainFunc(handler, c.Config)
}
// ★ 创建 APIServerHandler(核心 HTTP 路由器)
apiServerHandler := NewAPIServerHandler(name, c.Serializer, handlerChainBuilder, delegationTarget.UnprotectedHandler())
// APIServerHandler 包含:
// - FullHandlerChain: handlerChainBuilder(director) = 完整过滤链
// - GoRestfulContainer: go-restful 容器(API 路由)
// - NonGoRestfulMux: PathRecorderMux(非 API 路由)
// - Director: 路由分发器
// ★ 创建 GenericAPIServer
s := &GenericAPIServer{
discoveryAddresses: c.DiscoveryAddresses,
LoopbackClientConfig: c.LoopbackClientConfig,
legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes,
admissionControl: c.AdmissionControl,
Serializer: c.Serializer,
AuditBackend: c.AuditBackend,
Authorizer: c.Authorization.Authorizer,
delegationTarget: delegationTarget,
Handler: apiServerHandler,
// Hook 管理
postStartHooks: map[string]postStartHookEntry{},
preShutdownHooks: map[string]preShutdownHookEntry{},
disabledPostStartHooks: c.DisabledPostStartHooks,
// 健康检查
healthzChecks: c.HealthzChecks,
livezChecks: c.LivezChecks,
readyzChecks: c.ReadyzChecks,
readinessStopCh: make(chan struct{}),
// 其他
DiscoveryGroupManager: discovery.NewRootAPIsHandler(c.DiscoveryAddresses, c.Serializer),
minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
ShutdownTimeout: c.RequestTimeout,
ShutdownDelayDuration: c.ShutdownDelayDuration,
SecureServingInfo: c.SecureServing,
ExternalAddress: c.ExternalAddress,
APIServerID: c.APIServerID,
StorageVersionManager: c.StorageVersionManager,
}
// 设置 JSON Patch 大小限制
atomic.CompareAndSwapInt64(&jsonpatch.AccumulatedCopySizeLimit, existing, c.JSONPatchMaxCopyBytes)
// ★ 从委托目标继承 PostStartHooks
for k, v := range delegationTarget.PostStartHooks() {
s.postStartHooks[k] = v
}
for k, v := range delegationTarget.PreShutdownHooks() {
s.preShutdownHooks[k] = v
}
// ★ 注册预配置的 PostStartHooks
for name, preconfiguredPostStartHook := range c.PostStartHooks {
s.AddPostStartHook(name, preconfiguredPostStartHook.hook)
}
// ★ 注册内置 PostStartHooks
// 1. generic-apiserver-start-informers: 启动 SharedInformerFactory
s.AddPostStartHook("generic-apiserver-start-informers", func(context) error {
c.SharedInformerFactory.Start(context.StopCh)
return nil
})
// 2. priority-and-fairness-config-consumer: 启动限流控制器
if c.FlowControl != nil {
s.AddPostStartHook("priority-and-fairness-config-consumer", func(context) error {
go c.FlowControl.MaintainObservations(context.StopCh)
go c.FlowControl.Run(context.StopCh)
return nil
})
// 3. priority-and-fairness-filter: 启动水位线维护
s.AddPostStartHook("priority-and-fairness-filter", func(context) error {
genericfilters.StartPriorityAndFairnessWatermarkMaintenance(context.StopCh)
return nil
})
} else {
// 3b. max-in-flight-filter: 启动最大并发水位线维护
s.AddPostStartHook("max-in-flight-filter", ...)
}
// ★ 继承委托目标的健康检查
for _, delegateCheck := range delegationTarget.HealthzChecks() {
s.AddHealthChecks(delegateCheck)
}
// ★ 合并 listedPathProvider
s.listedPathProvider = routes.ListedPathProviders{s.listedPathProvider, delegationTarget}
// ★ 安装基础 API 路由
installAPI(s, c.Config)
// 包括:Index、Profiling、Metrics、Version、Discovery、FlowControl
return s, nil
}
3.4 PostStartHook 机制
PostStartHook 是 kube-apiserver 的延迟初始化机制:在服务器开始监听端口后,以独立 goroutine 并发执行注册的 Hook 函数。
3.4.1 Hook 注册
go
type PostStartHookFunc func(context PostStartHookContext) error
type PostStartHookContext struct {
LoopbackClientConfig *restclient.Config // 回环客户端(特权访问)
StopCh <-chan struct{} // 停止信号
}
type postStartHookEntry struct {
hook PostStartHookFunc
originatingStack string // 调试用:注册时的调用栈
done chan struct{} // 完成信号(用于健康检查)
}
注册流程:
- 检查名称非空、hook 非 nil
- 检查是否被 DisabledPostStartHooks 禁用
- 检查是否已被调用过(
postStartHooksCalled标志) - 检查是否重名
- 创建
donechannel - 注册
postStartHookHealthz(检查 hook 是否完成的健康检查) - 存入
postStartHooksmap
3.4.2 Hook 执行
go
func (s *GenericAPIServer) RunPostStartHooks(stopCh <-chan struct{}) {
s.postStartHookLock.Lock()
defer s.postStartHookLock.Unlock()
s.postStartHooksCalled = true // ★ 标记已调用,后续注册将被拒绝
context := PostStartHookContext{
LoopbackClientConfig: s.LoopbackClientConfig,
StopCh: stopCh,
}
// ★ 每个 Hook 独立 goroutine,并发执行,无顺序保证
for hookName, hookEntry := range s.postStartHooks {
go runPostStartHook(hookName, hookEntry, context)
}
}
func runPostStartHook(name string, entry postStartHookEntry, context PostStartHookContext) {
defer utilruntime.HandleCrash() // ★ 防止意外 panic 杀死服务器
err := entry.hook(context)
if err != nil {
klog.Fatalf("PostStartHook %q failed: %v", name, err) // ★ 故意杀死:Hook 失败=服务器不可用
}
close(entry.done) // ★ 通知健康检查:Hook 已完成
}
3.4.3 KubeAPIServer 中注册的所有 PostStartHooks
| Hook 名称 | 作用 |
|---|---|
start-kube-apiserver-admission-initializer |
初始化准入插件 |
generic-apiserver-start-informers |
启动 SharedInformerFactory |
priority-and-fairness-config-consumer |
启动 APF 限流控制器 |
priority-and-fairness-filter |
启动 APF 水位线维护 |
max-in-flight-filter |
启动最大并发水位线维护(无APF时) |
bootstrap-controller |
启动 Bootstrap 控制器(kubernetes Service/Endpoint) |
start-cluster-authentication-info-controller |
同步 ClusterAuthenticationInfo 到 ConfigMap |
start-kube-apiserver-identity-lease-controller |
维护 API Server 身份 Lease |
start-kube-apiserver-identity-lease-garbage-collector |
GC 过期的身份 Lease |
kube-apiserver-autoregistration |
自动注册 APIService + CRD 注册控制器 |
start-kube-apiserver-informers |
各组 Informer 的启动 |
| RBAC related hooks | RBAC 数据引导等 |
3.5 优雅关闭流程
AuditBackend HTTP Server NonBlockingRun HandlerChainWaitGroup RunPreShutdownHooks readinessStopCh delayedStopCh preparedGenericAPIServer.Run OS Signal AuditBackend HTTP Server NonBlockingRun HandlerChainWaitGroup RunPreShutdownHooks readinessStopCh delayedStopCh preparedGenericAPIServer.Run OS Signal #mermaid-svg-qoq0ctbu9C22FrZH{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qoq0ctbu9C22FrZH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qoq0ctbu9C22FrZH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qoq0ctbu9C22FrZH .error-icon{fill:#552222;}#mermaid-svg-qoq0ctbu9C22FrZH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qoq0ctbu9C22FrZH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qoq0ctbu9C22FrZH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qoq0ctbu9C22FrZH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qoq0ctbu9C22FrZH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qoq0ctbu9C22FrZH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qoq0ctbu9C22FrZH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qoq0ctbu9C22FrZH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qoq0ctbu9C22FrZH .marker.cross{stroke:#333333;}#mermaid-svg-qoq0ctbu9C22FrZH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qoq0ctbu9C22FrZH p{margin:0;}#mermaid-svg-qoq0ctbu9C22FrZH .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qoq0ctbu9C22FrZH text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-qoq0ctbu9C22FrZH .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qoq0ctbu9C22FrZH .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-qoq0ctbu9C22FrZH .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-qoq0ctbu9C22FrZH .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-qoq0ctbu9C22FrZH #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-qoq0ctbu9C22FrZH .sequenceNumber{fill:white;}#mermaid-svg-qoq0ctbu9C22FrZH #sequencenumber{fill:#333;}#mermaid-svg-qoq0ctbu9C22FrZH #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-qoq0ctbu9C22FrZH .messageText{fill:#333;stroke:none;}#mermaid-svg-qoq0ctbu9C22FrZH .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qoq0ctbu9C22FrZH .labelText,#mermaid-svg-qoq0ctbu9C22FrZH .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-qoq0ctbu9C22FrZH .loopText,#mermaid-svg-qoq0ctbu9C22FrZH .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-qoq0ctbu9C22FrZH .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qoq0ctbu9C22FrZH .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-qoq0ctbu9C22FrZH .noteText,#mermaid-svg-qoq0ctbu9C22FrZH .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-qoq0ctbu9C22FrZH .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qoq0ctbu9C22FrZH .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qoq0ctbu9C22FrZH .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qoq0ctbu9C22FrZH .actorPopupMenu{position:absolute;}#mermaid-svg-qoq0ctbu9C22FrZH .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-qoq0ctbu9C22FrZH .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qoq0ctbu9C22FrZH .actor-man circle,#mermaid-svg-qoq0ctbu9C22FrZH line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-qoq0ctbu9C22FrZH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} stopCh 被关闭 /readyz 立即返回 failure/healthz 仍返回 success 给负载均衡器时间检测 /readyz 失败并摘除 优雅关闭:1. 停止接受新请求2. 等待已有请求完成3. 超时后强制关闭 parNonBlockingRun goroutine 如:取消注册 kubernetes Service Endpoint关闭 AuditBackend 等待所有 Handler Chain 中的请求完成 服务器完全关闭 SIGTERM/SIGINTclose(readinessStopCh)time.Sleep(ShutdownDelayDuration)close(delayedStopCh)delayedStopCh 关闭server.Shutdown(ctx, timeout=RequestTimeout)关闭审计后端RunPreShutdownHooks()<-delayedStopCh (等待延迟关闭完成)<-stoppedCh (等待HTTP优雅关闭完成)HandlerChainWaitGroup.Wait()
关键时序:
- 收到信号 →
stopCh关闭 - 立即 关闭
readinessStopCh→/readyz返回失败,负载均衡器开始摘除 - 等待
ShutdownDelayDuration→ 给 LB 时间完成摘除(不再有新流量) - 关闭
delayedStopCh→ 触发 HTTP Server 优雅关闭 - 执行 PreShutdownHooks → 清理操作(如从 kubernetes Endpoint 中移除自己)
- 等待 HTTP Server 关闭完成 →
server.Shutdown()等待所有活跃请求完成 - 等待 HandlerChainWaitGroup → 确保所有过滤链中的请求完成
- 完成
3.6 SecureServing / Authentication / Authorization 配置构建
3.6.1 SecureServing
go
type SecureServingInfo struct {
Listener net.Listener // 网络监听器
Cert dynamiccertificates.CertKeyContentProvider // 主证书
SNICerts []dynamiccertificates.SNICertKeyContentProvider // SNI 证书
ClientCA dynamiccertificates.CAContentProvider // 客户端 CA
MinTLSVersion uint16 // 最低 TLS 版本
CipherSuites []uint16 // 允许的密码套件
HTTP2MaxStreamsPerConnection int // HTTP/2 最大并发流
DisableHTTP2 bool // 禁用 HTTP/2
}
SecureServingInfo.Serve() 做了以下事情:
- 构建
tls.Config(最低 TLS 1.2,启用 HTTP/2) - 若有 ClientCA:设置
tls.RequestClientCert(请求但不强制客户端证书) - 创建
DynamicServingCertificateController(动态证书热更新) - 注册证书变更监听器
- 启动证书控制器 goroutine
- 配置 HTTP/2 参数(MaxUploadBufferPerStream=256KB, MaxConcurrentStreams=250)
- 创建
http.Server并启动RunServer()
3.6.2 Authentication
认证通过 BuiltInAuthenticationOptions.ApplyTo() 构建:
go
// 支持的认证方式(按优先级合并为 union authenticator):
// 1. Loopback Token(回环客户端 Bearer Token,最高优先级)
// 2. X509 Client Certificate
// 3. Bearer Token(静态 TokenFile)
// 4. Bootstrap Token
// 5. OIDC
// 6. ServiceAccount Token
// 7. RequestHeader(代理认证)
// 8. Webhook Token Authenticator
认证流程:
- 每种认证方式创建对应的
Authenticator实现 - 通过
authenticatorunion.New()合并为 Union Authenticator - 设置到
Config.Authentication.Authenticator - 同时将 Loopback Token 注册为特权认证和授权(
AuthorizeClientBearerToken)
3.6.3 Authorization
go
func BuildAuthorizer(s *options.ServerRunOptions, EgressSelector, versionedInformers) (authorizer.Authorizer, authorizer.RuleResolver, error) {
authorizationConfig := s.Authorization.ToAuthorizationConfig(versionedInformers)
// 若有 EgressSelector,设置自定义拨号器
if EgressSelector != nil {
egressDialer, _ := EgressSelector.Lookup(egressselector.ControlPlane.AsNetworkContext())
authorizationConfig.CustomDial = egressDialer
}
return authorizationConfig.New()
// 创建 Union Authorizer,包含:
// - RBAC Authorizer(基于 Role/ClusterRole/RoleBinding/ClusterRoleBinding)
// - Node Authorizer(基于 Node 的权限限制)
// - ABAC Authorizer(基于属性的访问控制)
// - Webhook Authorizer(外部授权服务)
}
四、Mermaid 图集
图1:整体架构图
#mermaid-svg-CHkeuIDBal0mI6Gj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CHkeuIDBal0mI6Gj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CHkeuIDBal0mI6Gj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CHkeuIDBal0mI6Gj .error-icon{fill:#552222;}#mermaid-svg-CHkeuIDBal0mI6Gj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CHkeuIDBal0mI6Gj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CHkeuIDBal0mI6Gj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CHkeuIDBal0mI6Gj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CHkeuIDBal0mI6Gj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CHkeuIDBal0mI6Gj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CHkeuIDBal0mI6Gj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CHkeuIDBal0mI6Gj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CHkeuIDBal0mI6Gj .marker.cross{stroke:#333333;}#mermaid-svg-CHkeuIDBal0mI6Gj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CHkeuIDBal0mI6Gj p{margin:0;}#mermaid-svg-CHkeuIDBal0mI6Gj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-CHkeuIDBal0mI6Gj .cluster-label text{fill:#333;}#mermaid-svg-CHkeuIDBal0mI6Gj .cluster-label span{color:#333;}#mermaid-svg-CHkeuIDBal0mI6Gj .cluster-label span p{background-color:transparent;}#mermaid-svg-CHkeuIDBal0mI6Gj .label text,#mermaid-svg-CHkeuIDBal0mI6Gj span{fill:#333;color:#333;}#mermaid-svg-CHkeuIDBal0mI6Gj .node rect,#mermaid-svg-CHkeuIDBal0mI6Gj .node circle,#mermaid-svg-CHkeuIDBal0mI6Gj .node ellipse,#mermaid-svg-CHkeuIDBal0mI6Gj .node polygon,#mermaid-svg-CHkeuIDBal0mI6Gj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CHkeuIDBal0mI6Gj .rough-node .label text,#mermaid-svg-CHkeuIDBal0mI6Gj .node .label text,#mermaid-svg-CHkeuIDBal0mI6Gj .image-shape .label,#mermaid-svg-CHkeuIDBal0mI6Gj .icon-shape .label{text-anchor:middle;}#mermaid-svg-CHkeuIDBal0mI6Gj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CHkeuIDBal0mI6Gj .rough-node .label,#mermaid-svg-CHkeuIDBal0mI6Gj .node .label,#mermaid-svg-CHkeuIDBal0mI6Gj .image-shape .label,#mermaid-svg-CHkeuIDBal0mI6Gj .icon-shape .label{text-align:center;}#mermaid-svg-CHkeuIDBal0mI6Gj .node.clickable{cursor:pointer;}#mermaid-svg-CHkeuIDBal0mI6Gj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CHkeuIDBal0mI6Gj .arrowheadPath{fill:#333333;}#mermaid-svg-CHkeuIDBal0mI6Gj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CHkeuIDBal0mI6Gj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CHkeuIDBal0mI6Gj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CHkeuIDBal0mI6Gj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CHkeuIDBal0mI6Gj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CHkeuIDBal0mI6Gj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CHkeuIDBal0mI6Gj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CHkeuIDBal0mI6Gj .cluster text{fill:#333;}#mermaid-svg-CHkeuIDBal0mI6Gj .cluster span{color:#333;}#mermaid-svg-CHkeuIDBal0mI6Gj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CHkeuIDBal0mI6Gj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CHkeuIDBal0mI6Gj rect.text{fill:none;stroke-width:0;}#mermaid-svg-CHkeuIDBal0mI6Gj .icon-shape,#mermaid-svg-CHkeuIDBal0mI6Gj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CHkeuIDBal0mI6Gj .icon-shape p,#mermaid-svg-CHkeuIDBal0mI6Gj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CHkeuIDBal0mI6Gj .icon-shape .label rect,#mermaid-svg-CHkeuIDBal0mI6Gj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CHkeuIDBal0mI6Gj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CHkeuIDBal0mI6Gj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CHkeuIDBal0mI6Gj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Backend
kube-apiserver
Client Layer
Storage Layer
Delegation Chain
Handler Chain
HTTPS
HTTPS
HTTPS
Watch
HTTPS
代理
kubectl
client-go SDK
kubelet
controller-manager
scheduler
Authentication
认证
Audit
审计
Authorization
授权
Admission
准入控制
FlowControl
限流
Aggregator
API 聚合
KubeAPIServer
内置资源
APIExtensions
CRD 资源
WatchCache
缓存层
etcd3 Client
etcd Cluster
External API Server
(metrics-server等)
图2:启动完整流程图
#mermaid-svg-LVmGiSgHcJf4IGel{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LVmGiSgHcJf4IGel .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LVmGiSgHcJf4IGel .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LVmGiSgHcJf4IGel .error-icon{fill:#552222;}#mermaid-svg-LVmGiSgHcJf4IGel .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LVmGiSgHcJf4IGel .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LVmGiSgHcJf4IGel .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LVmGiSgHcJf4IGel .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LVmGiSgHcJf4IGel .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LVmGiSgHcJf4IGel .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LVmGiSgHcJf4IGel .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LVmGiSgHcJf4IGel .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LVmGiSgHcJf4IGel .marker.cross{stroke:#333333;}#mermaid-svg-LVmGiSgHcJf4IGel svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LVmGiSgHcJf4IGel p{margin:0;}#mermaid-svg-LVmGiSgHcJf4IGel .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-LVmGiSgHcJf4IGel .cluster-label text{fill:#333;}#mermaid-svg-LVmGiSgHcJf4IGel .cluster-label span{color:#333;}#mermaid-svg-LVmGiSgHcJf4IGel .cluster-label span p{background-color:transparent;}#mermaid-svg-LVmGiSgHcJf4IGel .label text,#mermaid-svg-LVmGiSgHcJf4IGel span{fill:#333;color:#333;}#mermaid-svg-LVmGiSgHcJf4IGel .node rect,#mermaid-svg-LVmGiSgHcJf4IGel .node circle,#mermaid-svg-LVmGiSgHcJf4IGel .node ellipse,#mermaid-svg-LVmGiSgHcJf4IGel .node polygon,#mermaid-svg-LVmGiSgHcJf4IGel .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LVmGiSgHcJf4IGel .rough-node .label text,#mermaid-svg-LVmGiSgHcJf4IGel .node .label text,#mermaid-svg-LVmGiSgHcJf4IGel .image-shape .label,#mermaid-svg-LVmGiSgHcJf4IGel .icon-shape .label{text-anchor:middle;}#mermaid-svg-LVmGiSgHcJf4IGel .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LVmGiSgHcJf4IGel .rough-node .label,#mermaid-svg-LVmGiSgHcJf4IGel .node .label,#mermaid-svg-LVmGiSgHcJf4IGel .image-shape .label,#mermaid-svg-LVmGiSgHcJf4IGel .icon-shape .label{text-align:center;}#mermaid-svg-LVmGiSgHcJf4IGel .node.clickable{cursor:pointer;}#mermaid-svg-LVmGiSgHcJf4IGel .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LVmGiSgHcJf4IGel .arrowheadPath{fill:#333333;}#mermaid-svg-LVmGiSgHcJf4IGel .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LVmGiSgHcJf4IGel .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LVmGiSgHcJf4IGel .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LVmGiSgHcJf4IGel .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LVmGiSgHcJf4IGel .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LVmGiSgHcJf4IGel .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LVmGiSgHcJf4IGel .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LVmGiSgHcJf4IGel .cluster text{fill:#333;}#mermaid-svg-LVmGiSgHcJf4IGel .cluster span{color:#333;}#mermaid-svg-LVmGiSgHcJf4IGel div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LVmGiSgHcJf4IGel .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LVmGiSgHcJf4IGel rect.text{fill:none;stroke-width:0;}#mermaid-svg-LVmGiSgHcJf4IGel .icon-shape,#mermaid-svg-LVmGiSgHcJf4IGel .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LVmGiSgHcJf4IGel .icon-shape p,#mermaid-svg-LVmGiSgHcJf4IGel .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LVmGiSgHcJf4IGel .icon-shape .label rect,#mermaid-svg-LVmGiSgHcJf4IGel .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LVmGiSgHcJf4IGel .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LVmGiSgHcJf4IGel .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LVmGiSgHcJf4IGel :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} main
NewAPIServerCommand
创建 Cobra Command
解析命令行参数
Complete
补全默认值
Validate
校验参数
Run
启动入口
CreateServerChain
CreateNodeDialer
创建节点通信
buildGenericConfig
构建通用配置
NewConfig
ApplyTo
各Options
StorageFactory
Clientset
Informers
Authentication
Authorization
Audit
Admission
FlowControl
CreateKubeAPIServerConfig
createAPIExtensionsConfig
createAPIExtensionsServer
delegate=EmptyDelegate
CreateKubeAPIServer
delegate=CRD Server
createAggregatorConfig
createAggregatorServer
delegate=KubeAPIServer
PrepareRun
安装OpenAPI
安装Healthz/Livez/Readyz
注册Audit PreShutdownHook
Run
NonBlockingRun
启动AuditBackend
SecureServingInfo.Serve
启动HTTPS服务
RunPostStartHooks
执行所有PostStartHook
systemd SdNotify
READY=1
等待 stopCh
优雅关闭
图3:Server 委托链图
#mermaid-svg-Z3EUYaAlB9oxunIO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Z3EUYaAlB9oxunIO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Z3EUYaAlB9oxunIO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Z3EUYaAlB9oxunIO .error-icon{fill:#552222;}#mermaid-svg-Z3EUYaAlB9oxunIO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Z3EUYaAlB9oxunIO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Z3EUYaAlB9oxunIO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Z3EUYaAlB9oxunIO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Z3EUYaAlB9oxunIO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Z3EUYaAlB9oxunIO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Z3EUYaAlB9oxunIO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Z3EUYaAlB9oxunIO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Z3EUYaAlB9oxunIO .marker.cross{stroke:#333333;}#mermaid-svg-Z3EUYaAlB9oxunIO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Z3EUYaAlB9oxunIO p{margin:0;}#mermaid-svg-Z3EUYaAlB9oxunIO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Z3EUYaAlB9oxunIO .cluster-label text{fill:#333;}#mermaid-svg-Z3EUYaAlB9oxunIO .cluster-label span{color:#333;}#mermaid-svg-Z3EUYaAlB9oxunIO .cluster-label span p{background-color:transparent;}#mermaid-svg-Z3EUYaAlB9oxunIO .label text,#mermaid-svg-Z3EUYaAlB9oxunIO span{fill:#333;color:#333;}#mermaid-svg-Z3EUYaAlB9oxunIO .node rect,#mermaid-svg-Z3EUYaAlB9oxunIO .node circle,#mermaid-svg-Z3EUYaAlB9oxunIO .node ellipse,#mermaid-svg-Z3EUYaAlB9oxunIO .node polygon,#mermaid-svg-Z3EUYaAlB9oxunIO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Z3EUYaAlB9oxunIO .rough-node .label text,#mermaid-svg-Z3EUYaAlB9oxunIO .node .label text,#mermaid-svg-Z3EUYaAlB9oxunIO .image-shape .label,#mermaid-svg-Z3EUYaAlB9oxunIO .icon-shape .label{text-anchor:middle;}#mermaid-svg-Z3EUYaAlB9oxunIO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Z3EUYaAlB9oxunIO .rough-node .label,#mermaid-svg-Z3EUYaAlB9oxunIO .node .label,#mermaid-svg-Z3EUYaAlB9oxunIO .image-shape .label,#mermaid-svg-Z3EUYaAlB9oxunIO .icon-shape .label{text-align:center;}#mermaid-svg-Z3EUYaAlB9oxunIO .node.clickable{cursor:pointer;}#mermaid-svg-Z3EUYaAlB9oxunIO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Z3EUYaAlB9oxunIO .arrowheadPath{fill:#333333;}#mermaid-svg-Z3EUYaAlB9oxunIO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Z3EUYaAlB9oxunIO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Z3EUYaAlB9oxunIO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Z3EUYaAlB9oxunIO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Z3EUYaAlB9oxunIO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Z3EUYaAlB9oxunIO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Z3EUYaAlB9oxunIO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Z3EUYaAlB9oxunIO .cluster text{fill:#333;}#mermaid-svg-Z3EUYaAlB9oxunIO .cluster span{color:#333;}#mermaid-svg-Z3EUYaAlB9oxunIO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Z3EUYaAlB9oxunIO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Z3EUYaAlB9oxunIO rect.text{fill:none;stroke-width:0;}#mermaid-svg-Z3EUYaAlB9oxunIO .icon-shape,#mermaid-svg-Z3EUYaAlB9oxunIO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Z3EUYaAlB9oxunIO .icon-shape p,#mermaid-svg-Z3EUYaAlB9oxunIO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Z3EUYaAlB9oxunIO .icon-shape .label rect,#mermaid-svg-Z3EUYaAlB9oxunIO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Z3EUYaAlB9oxunIO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Z3EUYaAlB9oxunIO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Z3EUYaAlB9oxunIO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Delegation Chain 请求流转
匹配APIService?
代理
否
匹配内置资源?
处理
否
匹配CRD?
处理
否
HTTP Request
Aggregator Handler
是
External API Server
KubeAPIServer Handler
是
Core/Extensions REST Storage
APIExtensions Handler
是
CRD REST Storage
EmptyDelegate
404 Not Found
图4:核心类图
#mermaid-svg-4n4PDuiIvu34eRch{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4n4PDuiIvu34eRch .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4n4PDuiIvu34eRch .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4n4PDuiIvu34eRch .error-icon{fill:#552222;}#mermaid-svg-4n4PDuiIvu34eRch .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4n4PDuiIvu34eRch .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4n4PDuiIvu34eRch .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4n4PDuiIvu34eRch .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4n4PDuiIvu34eRch .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4n4PDuiIvu34eRch .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4n4PDuiIvu34eRch .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4n4PDuiIvu34eRch .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4n4PDuiIvu34eRch .marker.cross{stroke:#333333;}#mermaid-svg-4n4PDuiIvu34eRch svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4n4PDuiIvu34eRch p{margin:0;}#mermaid-svg-4n4PDuiIvu34eRch g.classGroup text{fill:#9370DB;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-4n4PDuiIvu34eRch g.classGroup text .title{font-weight:bolder;}#mermaid-svg-4n4PDuiIvu34eRch .cluster-label text{fill:#333;}#mermaid-svg-4n4PDuiIvu34eRch .cluster-label span{color:#333;}#mermaid-svg-4n4PDuiIvu34eRch .cluster-label span p{background-color:transparent;}#mermaid-svg-4n4PDuiIvu34eRch .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4n4PDuiIvu34eRch .cluster text{fill:#333;}#mermaid-svg-4n4PDuiIvu34eRch .cluster span{color:#333;}#mermaid-svg-4n4PDuiIvu34eRch .nodeLabel,#mermaid-svg-4n4PDuiIvu34eRch .edgeLabel{color:#131300;}#mermaid-svg-4n4PDuiIvu34eRch .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-4n4PDuiIvu34eRch .label text{fill:#131300;}#mermaid-svg-4n4PDuiIvu34eRch .labelBkg{background:#ECECFF;}#mermaid-svg-4n4PDuiIvu34eRch .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-4n4PDuiIvu34eRch .classTitle{font-weight:bolder;}#mermaid-svg-4n4PDuiIvu34eRch .node rect,#mermaid-svg-4n4PDuiIvu34eRch .node circle,#mermaid-svg-4n4PDuiIvu34eRch .node ellipse,#mermaid-svg-4n4PDuiIvu34eRch .node polygon,#mermaid-svg-4n4PDuiIvu34eRch .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4n4PDuiIvu34eRch .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch g.clickable{cursor:pointer;}#mermaid-svg-4n4PDuiIvu34eRch g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-4n4PDuiIvu34eRch g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-4n4PDuiIvu34eRch .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-4n4PDuiIvu34eRch .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-4n4PDuiIvu34eRch .dashed-line{stroke-dasharray:3;}#mermaid-svg-4n4PDuiIvu34eRch .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-4n4PDuiIvu34eRch #compositionStart,#mermaid-svg-4n4PDuiIvu34eRch .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch #compositionEnd,#mermaid-svg-4n4PDuiIvu34eRch .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch #dependencyStart,#mermaid-svg-4n4PDuiIvu34eRch .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch #dependencyStart,#mermaid-svg-4n4PDuiIvu34eRch .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch #extensionStart,#mermaid-svg-4n4PDuiIvu34eRch .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch #extensionEnd,#mermaid-svg-4n4PDuiIvu34eRch .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch #aggregationStart,#mermaid-svg-4n4PDuiIvu34eRch .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch #aggregationEnd,#mermaid-svg-4n4PDuiIvu34eRch .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch #lollipopStart,#mermaid-svg-4n4PDuiIvu34eRch .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch #lollipopEnd,#mermaid-svg-4n4PDuiIvu34eRch .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4n4PDuiIvu34eRch .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-4n4PDuiIvu34eRch .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4n4PDuiIvu34eRch .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4n4PDuiIvu34eRch .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4n4PDuiIvu34eRch :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Complete()
CreateKubeAPIServerConfig()
contains
Complete().New()
contains
contains
implements
通过GenericAPIServer
ServerRunOptions
+GenericServerRunOptions
+Etcd EtcdOptions
+SecureServing SecureServingOptionsWithLoopback
+Authentication BuiltInAuthenticationOptions
+Authorization BuiltInAuthorizationOptions
+Admission AdmissionOptions
+Audit AuditOptions
+Features FeatureOptions
+APIEnablement APIEnablementOptions
+EgressSelector EgressSelectorOptions
+EventTTL Duration
+ServiceClusterIPRanges string
+MasterCount int
+Flags() : NamedFlagSets
completedServerRunOptions
-ServerRunOptions *ServerRunOptions
Config
+GenericConfig *genericapiserver.Config
+ExtraConfig ExtraConfig
+Complete() : CompletedConfig
ExtraConfig
+APIResourceConfigSource
+StorageFactory
+ServiceIPRange IPNet
+KubeletClientConfig
+EventTTL Duration
+VersionedInformers
+ServiceAccountIssuer
GenericAPIServer
+Handler APIServerHandler
+LoopbackClientConfig
+SecureServingInfo
+Authorizer
+DiscoveryGroupManager
-postStartHooks map
-preShutdownHooks map
-delegationTarget DelegationTarget
+AddPostStartHook()
+InstallLegacyAPIGroup()
+InstallAPIGroups()
+PrepareRun() : preparedGenericAPIServer
Instance
+GenericAPIServer *GenericAPIServer
+ClusterAuthenticationInfo
APIServerHandler
+FullHandlerChain http.Handler
+GoRestfulContainer *restful.Container
+NonGoRestfulMux *PathRecorderMux
+Director http.Handler
<<interface>>
DelegationTarget
+UnprotectedHandler() : http.Handler
+PostStartHooks() : map
+PreShutdownHooks() : map
+HealthzChecks() : \[\]HealthChecker
+ListedPaths() : \[\]string
+NextDelegate() : DelegationTarget
+PrepareRun() : preparedGenericAPIServer
图5:依赖注入图
#mermaid-svg-nGYlaocCcavLSFDT{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-nGYlaocCcavLSFDT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nGYlaocCcavLSFDT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nGYlaocCcavLSFDT .error-icon{fill:#552222;}#mermaid-svg-nGYlaocCcavLSFDT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nGYlaocCcavLSFDT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nGYlaocCcavLSFDT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nGYlaocCcavLSFDT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nGYlaocCcavLSFDT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nGYlaocCcavLSFDT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nGYlaocCcavLSFDT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nGYlaocCcavLSFDT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nGYlaocCcavLSFDT .marker.cross{stroke:#333333;}#mermaid-svg-nGYlaocCcavLSFDT svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nGYlaocCcavLSFDT p{margin:0;}#mermaid-svg-nGYlaocCcavLSFDT .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-nGYlaocCcavLSFDT .cluster-label text{fill:#333;}#mermaid-svg-nGYlaocCcavLSFDT .cluster-label span{color:#333;}#mermaid-svg-nGYlaocCcavLSFDT .cluster-label span p{background-color:transparent;}#mermaid-svg-nGYlaocCcavLSFDT .label text,#mermaid-svg-nGYlaocCcavLSFDT span{fill:#333;color:#333;}#mermaid-svg-nGYlaocCcavLSFDT .node rect,#mermaid-svg-nGYlaocCcavLSFDT .node circle,#mermaid-svg-nGYlaocCcavLSFDT .node ellipse,#mermaid-svg-nGYlaocCcavLSFDT .node polygon,#mermaid-svg-nGYlaocCcavLSFDT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-nGYlaocCcavLSFDT .rough-node .label text,#mermaid-svg-nGYlaocCcavLSFDT .node .label text,#mermaid-svg-nGYlaocCcavLSFDT .image-shape .label,#mermaid-svg-nGYlaocCcavLSFDT .icon-shape .label{text-anchor:middle;}#mermaid-svg-nGYlaocCcavLSFDT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-nGYlaocCcavLSFDT .rough-node .label,#mermaid-svg-nGYlaocCcavLSFDT .node .label,#mermaid-svg-nGYlaocCcavLSFDT .image-shape .label,#mermaid-svg-nGYlaocCcavLSFDT .icon-shape .label{text-align:center;}#mermaid-svg-nGYlaocCcavLSFDT .node.clickable{cursor:pointer;}#mermaid-svg-nGYlaocCcavLSFDT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-nGYlaocCcavLSFDT .arrowheadPath{fill:#333333;}#mermaid-svg-nGYlaocCcavLSFDT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-nGYlaocCcavLSFDT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-nGYlaocCcavLSFDT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nGYlaocCcavLSFDT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-nGYlaocCcavLSFDT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nGYlaocCcavLSFDT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-nGYlaocCcavLSFDT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-nGYlaocCcavLSFDT .cluster text{fill:#333;}#mermaid-svg-nGYlaocCcavLSFDT .cluster span{color:#333;}#mermaid-svg-nGYlaocCcavLSFDT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-nGYlaocCcavLSFDT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-nGYlaocCcavLSFDT rect.text{fill:none;stroke-width:0;}#mermaid-svg-nGYlaocCcavLSFDT .icon-shape,#mermaid-svg-nGYlaocCcavLSFDT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-nGYlaocCcavLSFDT .icon-shape p,#mermaid-svg-nGYlaocCcavLSFDT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-nGYlaocCcavLSFDT .icon-shape .label rect,#mermaid-svg-nGYlaocCcavLSFDT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-nGYlaocCcavLSFDT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-nGYlaocCcavLSFDT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-nGYlaocCcavLSFDT :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ExtraConfig 特有注入
Config 内部注入
Options → Config 注入
.ApplyTo()
.ApplyTo()
.ApplyWithStorageFactoryTo()
.ApplyTo()
BuildAuthorizer()
.ApplyTo()
.ApplyTo()
.ApplyTo()
.ApplyTo()
.ApplyTo()
NewForConfig
ApplyTo参数
GenericServerRunOptions
Config
SecureServingOptions
EtcdOptions
AuthenticationOptions
AuthorizationOptions
AuditOptions
AdmissionOptions
FeatureOptions
EgressSelectorOptions
APIEnablementOptions
SecureServingInfo
AuthenticationInfo
AuthorizationInfo
LoopbackClientConfig
RESTOptionsGetter
AdmissionControl
FlowControl
ExtraConfig
StorageFactory
VersionedInformers
ServiceAccountIssuer
KubeletClientConfig
clientgoclientset
图6:Config 构建图
#mermaid-svg-0wK8lygWt8Kotsod{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0wK8lygWt8Kotsod .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0wK8lygWt8Kotsod .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0wK8lygWt8Kotsod .error-icon{fill:#552222;}#mermaid-svg-0wK8lygWt8Kotsod .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0wK8lygWt8Kotsod .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0wK8lygWt8Kotsod .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0wK8lygWt8Kotsod .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0wK8lygWt8Kotsod .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0wK8lygWt8Kotsod .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0wK8lygWt8Kotsod .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0wK8lygWt8Kotsod .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0wK8lygWt8Kotsod .marker.cross{stroke:#333333;}#mermaid-svg-0wK8lygWt8Kotsod svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0wK8lygWt8Kotsod p{margin:0;}#mermaid-svg-0wK8lygWt8Kotsod .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0wK8lygWt8Kotsod .cluster-label text{fill:#333;}#mermaid-svg-0wK8lygWt8Kotsod .cluster-label span{color:#333;}#mermaid-svg-0wK8lygWt8Kotsod .cluster-label span p{background-color:transparent;}#mermaid-svg-0wK8lygWt8Kotsod .label text,#mermaid-svg-0wK8lygWt8Kotsod span{fill:#333;color:#333;}#mermaid-svg-0wK8lygWt8Kotsod .node rect,#mermaid-svg-0wK8lygWt8Kotsod .node circle,#mermaid-svg-0wK8lygWt8Kotsod .node ellipse,#mermaid-svg-0wK8lygWt8Kotsod .node polygon,#mermaid-svg-0wK8lygWt8Kotsod .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0wK8lygWt8Kotsod .rough-node .label text,#mermaid-svg-0wK8lygWt8Kotsod .node .label text,#mermaid-svg-0wK8lygWt8Kotsod .image-shape .label,#mermaid-svg-0wK8lygWt8Kotsod .icon-shape .label{text-anchor:middle;}#mermaid-svg-0wK8lygWt8Kotsod .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0wK8lygWt8Kotsod .rough-node .label,#mermaid-svg-0wK8lygWt8Kotsod .node .label,#mermaid-svg-0wK8lygWt8Kotsod .image-shape .label,#mermaid-svg-0wK8lygWt8Kotsod .icon-shape .label{text-align:center;}#mermaid-svg-0wK8lygWt8Kotsod .node.clickable{cursor:pointer;}#mermaid-svg-0wK8lygWt8Kotsod .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0wK8lygWt8Kotsod .arrowheadPath{fill:#333333;}#mermaid-svg-0wK8lygWt8Kotsod .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0wK8lygWt8Kotsod .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0wK8lygWt8Kotsod .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0wK8lygWt8Kotsod .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0wK8lygWt8Kotsod .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0wK8lygWt8Kotsod .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0wK8lygWt8Kotsod .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0wK8lygWt8Kotsod .cluster text{fill:#333;}#mermaid-svg-0wK8lygWt8Kotsod .cluster span{color:#333;}#mermaid-svg-0wK8lygWt8Kotsod div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0wK8lygWt8Kotsod .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0wK8lygWt8Kotsod rect.text{fill:none;stroke-width:0;}#mermaid-svg-0wK8lygWt8Kotsod .icon-shape,#mermaid-svg-0wK8lygWt8Kotsod .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0wK8lygWt8Kotsod .icon-shape p,#mermaid-svg-0wK8lygWt8Kotsod .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0wK8lygWt8Kotsod .icon-shape .label rect,#mermaid-svg-0wK8lygWt8Kotsod .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0wK8lygWt8Kotsod .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0wK8lygWt8Kotsod .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0wK8lygWt8Kotsod :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} CreateKubeAPIServerConfig
etcd 预检
capabilities.Initialize()
解析 ServiceIPRange
构建 controlplane.Config
提取 ClientCA/RequestHeader
添加 admission PostStartHook
配置 EgressSelector
加载 ServiceAccount 公钥
buildGenericConfig
genericapiserver.NewConfig(codecs)
设置 MergedResourceConfig
GenericServerRunOptions.ApplyTo()
SecureServing.ApplyTo()
Features.ApplyTo()
APIEnablement.ApplyTo()
EgressSelector.ApplyTo()
设置 OpenAPIConfig
设置 LongRunningFunc
构建 StorageFactory
Etcd.ApplyWithStorageFactoryTo()
配置 LoopbackClientConfig
(protobuf+DisableCompression)
创建 External Clientset
- SharedInformerFactory
Authentication.ApplyTo()
BuildAuthorizer()
Audit.ApplyTo()
构建 Admission
Admission.ApplyTo()
BuildPriorityAndFairness()
图7:PostStartHook 机制图
#mermaid-svg-ElZHv8jtEGv5g2K0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ElZHv8jtEGv5g2K0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ElZHv8jtEGv5g2K0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ElZHv8jtEGv5g2K0 .error-icon{fill:#552222;}#mermaid-svg-ElZHv8jtEGv5g2K0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ElZHv8jtEGv5g2K0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ElZHv8jtEGv5g2K0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ElZHv8jtEGv5g2K0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ElZHv8jtEGv5g2K0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ElZHv8jtEGv5g2K0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ElZHv8jtEGv5g2K0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ElZHv8jtEGv5g2K0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ElZHv8jtEGv5g2K0 .marker.cross{stroke:#333333;}#mermaid-svg-ElZHv8jtEGv5g2K0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ElZHv8jtEGv5g2K0 p{margin:0;}#mermaid-svg-ElZHv8jtEGv5g2K0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ElZHv8jtEGv5g2K0 .cluster-label text{fill:#333;}#mermaid-svg-ElZHv8jtEGv5g2K0 .cluster-label span{color:#333;}#mermaid-svg-ElZHv8jtEGv5g2K0 .cluster-label span p{background-color:transparent;}#mermaid-svg-ElZHv8jtEGv5g2K0 .label text,#mermaid-svg-ElZHv8jtEGv5g2K0 span{fill:#333;color:#333;}#mermaid-svg-ElZHv8jtEGv5g2K0 .node rect,#mermaid-svg-ElZHv8jtEGv5g2K0 .node circle,#mermaid-svg-ElZHv8jtEGv5g2K0 .node ellipse,#mermaid-svg-ElZHv8jtEGv5g2K0 .node polygon,#mermaid-svg-ElZHv8jtEGv5g2K0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ElZHv8jtEGv5g2K0 .rough-node .label text,#mermaid-svg-ElZHv8jtEGv5g2K0 .node .label text,#mermaid-svg-ElZHv8jtEGv5g2K0 .image-shape .label,#mermaid-svg-ElZHv8jtEGv5g2K0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-ElZHv8jtEGv5g2K0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ElZHv8jtEGv5g2K0 .rough-node .label,#mermaid-svg-ElZHv8jtEGv5g2K0 .node .label,#mermaid-svg-ElZHv8jtEGv5g2K0 .image-shape .label,#mermaid-svg-ElZHv8jtEGv5g2K0 .icon-shape .label{text-align:center;}#mermaid-svg-ElZHv8jtEGv5g2K0 .node.clickable{cursor:pointer;}#mermaid-svg-ElZHv8jtEGv5g2K0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ElZHv8jtEGv5g2K0 .arrowheadPath{fill:#333333;}#mermaid-svg-ElZHv8jtEGv5g2K0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ElZHv8jtEGv5g2K0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ElZHv8jtEGv5g2K0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ElZHv8jtEGv5g2K0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ElZHv8jtEGv5g2K0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ElZHv8jtEGv5g2K0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ElZHv8jtEGv5g2K0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ElZHv8jtEGv5g2K0 .cluster text{fill:#333;}#mermaid-svg-ElZHv8jtEGv5g2K0 .cluster span{color:#333;}#mermaid-svg-ElZHv8jtEGv5g2K0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ElZHv8jtEGv5g2K0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ElZHv8jtEGv5g2K0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-ElZHv8jtEGv5g2K0 .icon-shape,#mermaid-svg-ElZHv8jtEGv5g2K0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ElZHv8jtEGv5g2K0 .icon-shape p,#mermaid-svg-ElZHv8jtEGv5g2K0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ElZHv8jtEGv5g2K0 .icon-shape .label rect,#mermaid-svg-ElZHv8jtEGv5g2K0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ElZHv8jtEGv5g2K0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ElZHv8jtEGv5g2K0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ElZHv8jtEGv5g2K0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 健康检查
是
否
poststarthook/{name}
done已关闭?
✅ healthy
❌ not finished
执行阶段
否
是
RunPostStartHooks(stopCh)
设置 postStartHooksCalled=true
构建 PostStartHookContext
(LoopbackClientConfig+StopCh)
for each hook:
go runPostStartHook()
每个hook独立goroutine
defer HandleCrash()
执行 hook(context)
成功?
klog.Fatalf()
杀死进程
close(done)
通知健康检查
注册阶段
是
否
是
否
是
否
是
否
是
否
AddPostStartHook(name, hook)
名称为空?
返回错误
hook为nil?
返回错误
已被禁用?
跳过
已被调用?
返回错误
postStartHooksCalled=true
重名?
返回错误
含注册调用栈
创建 done channel
注册 postStartHookHealthz
(检查done是否关闭)
存入 postStartHooks map
图8:优雅关闭图
#mermaid-svg-q5iCjxDygP9sre4e{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-q5iCjxDygP9sre4e .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-q5iCjxDygP9sre4e .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-q5iCjxDygP9sre4e .error-icon{fill:#552222;}#mermaid-svg-q5iCjxDygP9sre4e .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-q5iCjxDygP9sre4e .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-q5iCjxDygP9sre4e .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-q5iCjxDygP9sre4e .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-q5iCjxDygP9sre4e .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-q5iCjxDygP9sre4e .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-q5iCjxDygP9sre4e .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-q5iCjxDygP9sre4e .marker{fill:#333333;stroke:#333333;}#mermaid-svg-q5iCjxDygP9sre4e .marker.cross{stroke:#333333;}#mermaid-svg-q5iCjxDygP9sre4e svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-q5iCjxDygP9sre4e p{margin:0;}#mermaid-svg-q5iCjxDygP9sre4e .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-q5iCjxDygP9sre4e .cluster-label text{fill:#333;}#mermaid-svg-q5iCjxDygP9sre4e .cluster-label span{color:#333;}#mermaid-svg-q5iCjxDygP9sre4e .cluster-label span p{background-color:transparent;}#mermaid-svg-q5iCjxDygP9sre4e .label text,#mermaid-svg-q5iCjxDygP9sre4e span{fill:#333;color:#333;}#mermaid-svg-q5iCjxDygP9sre4e .node rect,#mermaid-svg-q5iCjxDygP9sre4e .node circle,#mermaid-svg-q5iCjxDygP9sre4e .node ellipse,#mermaid-svg-q5iCjxDygP9sre4e .node polygon,#mermaid-svg-q5iCjxDygP9sre4e .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-q5iCjxDygP9sre4e .rough-node .label text,#mermaid-svg-q5iCjxDygP9sre4e .node .label text,#mermaid-svg-q5iCjxDygP9sre4e .image-shape .label,#mermaid-svg-q5iCjxDygP9sre4e .icon-shape .label{text-anchor:middle;}#mermaid-svg-q5iCjxDygP9sre4e .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-q5iCjxDygP9sre4e .rough-node .label,#mermaid-svg-q5iCjxDygP9sre4e .node .label,#mermaid-svg-q5iCjxDygP9sre4e .image-shape .label,#mermaid-svg-q5iCjxDygP9sre4e .icon-shape .label{text-align:center;}#mermaid-svg-q5iCjxDygP9sre4e .node.clickable{cursor:pointer;}#mermaid-svg-q5iCjxDygP9sre4e .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-q5iCjxDygP9sre4e .arrowheadPath{fill:#333333;}#mermaid-svg-q5iCjxDygP9sre4e .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-q5iCjxDygP9sre4e .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-q5iCjxDygP9sre4e .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-q5iCjxDygP9sre4e .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-q5iCjxDygP9sre4e .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-q5iCjxDygP9sre4e .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-q5iCjxDygP9sre4e .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-q5iCjxDygP9sre4e .cluster text{fill:#333;}#mermaid-svg-q5iCjxDygP9sre4e .cluster span{color:#333;}#mermaid-svg-q5iCjxDygP9sre4e div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-q5iCjxDygP9sre4e .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-q5iCjxDygP9sre4e rect.text{fill:none;stroke-width:0;}#mermaid-svg-q5iCjxDygP9sre4e .icon-shape,#mermaid-svg-q5iCjxDygP9sre4e .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-q5iCjxDygP9sre4e .icon-shape p,#mermaid-svg-q5iCjxDygP9sre4e .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-q5iCjxDygP9sre4e .icon-shape .label rect,#mermaid-svg-q5iCjxDygP9sre4e .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-q5iCjxDygP9sre4e .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-q5iCjxDygP9sre4e .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-q5iCjxDygP9sre4e :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SIGTERM/SIGINT
stopCh 关闭
close(readinessStopCh)
/readyz → failure
/healthz → success
/livez → success
time.Sleep(ShutdownDelayDuration)
⏳ 等待LB检测/readyz失败
停止发送新流量
close(delayedStopCh)
RunPreShutdownHooks()
audit-backend: AuditBackend.Shutdown()
bootstrap-controller: 移除Endpoint
HTTP Server.Shutdown()
停止接受新请求
等待已有请求完成
(超时=ShutdownTimeout)
<-delayedStopCh
<-stoppedCh
HandlerChainWaitGroup.Wait()
服务器关闭完成
图9:数据流入流出图
#mermaid-svg-lN2aoPu05d5i12w8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lN2aoPu05d5i12w8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lN2aoPu05d5i12w8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lN2aoPu05d5i12w8 .error-icon{fill:#552222;}#mermaid-svg-lN2aoPu05d5i12w8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lN2aoPu05d5i12w8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lN2aoPu05d5i12w8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lN2aoPu05d5i12w8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lN2aoPu05d5i12w8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lN2aoPu05d5i12w8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lN2aoPu05d5i12w8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lN2aoPu05d5i12w8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lN2aoPu05d5i12w8 .marker.cross{stroke:#333333;}#mermaid-svg-lN2aoPu05d5i12w8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lN2aoPu05d5i12w8 p{margin:0;}#mermaid-svg-lN2aoPu05d5i12w8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-lN2aoPu05d5i12w8 .cluster-label text{fill:#333;}#mermaid-svg-lN2aoPu05d5i12w8 .cluster-label span{color:#333;}#mermaid-svg-lN2aoPu05d5i12w8 .cluster-label span p{background-color:transparent;}#mermaid-svg-lN2aoPu05d5i12w8 .label text,#mermaid-svg-lN2aoPu05d5i12w8 span{fill:#333;color:#333;}#mermaid-svg-lN2aoPu05d5i12w8 .node rect,#mermaid-svg-lN2aoPu05d5i12w8 .node circle,#mermaid-svg-lN2aoPu05d5i12w8 .node ellipse,#mermaid-svg-lN2aoPu05d5i12w8 .node polygon,#mermaid-svg-lN2aoPu05d5i12w8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lN2aoPu05d5i12w8 .rough-node .label text,#mermaid-svg-lN2aoPu05d5i12w8 .node .label text,#mermaid-svg-lN2aoPu05d5i12w8 .image-shape .label,#mermaid-svg-lN2aoPu05d5i12w8 .icon-shape .label{text-anchor:middle;}#mermaid-svg-lN2aoPu05d5i12w8 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-lN2aoPu05d5i12w8 .rough-node .label,#mermaid-svg-lN2aoPu05d5i12w8 .node .label,#mermaid-svg-lN2aoPu05d5i12w8 .image-shape .label,#mermaid-svg-lN2aoPu05d5i12w8 .icon-shape .label{text-align:center;}#mermaid-svg-lN2aoPu05d5i12w8 .node.clickable{cursor:pointer;}#mermaid-svg-lN2aoPu05d5i12w8 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-lN2aoPu05d5i12w8 .arrowheadPath{fill:#333333;}#mermaid-svg-lN2aoPu05d5i12w8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-lN2aoPu05d5i12w8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-lN2aoPu05d5i12w8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lN2aoPu05d5i12w8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lN2aoPu05d5i12w8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lN2aoPu05d5i12w8 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-lN2aoPu05d5i12w8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-lN2aoPu05d5i12w8 .cluster text{fill:#333;}#mermaid-svg-lN2aoPu05d5i12w8 .cluster span{color:#333;}#mermaid-svg-lN2aoPu05d5i12w8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-lN2aoPu05d5i12w8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lN2aoPu05d5i12w8 rect.text{fill:none;stroke-width:0;}#mermaid-svg-lN2aoPu05d5i12w8 .icon-shape,#mermaid-svg-lN2aoPu05d5i12w8 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lN2aoPu05d5i12w8 .icon-shape p,#mermaid-svg-lN2aoPu05d5i12w8 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-lN2aoPu05d5i12w8 .icon-shape .label rect,#mermaid-svg-lN2aoPu05d5i12w8 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lN2aoPu05d5i12w8 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-lN2aoPu05d5i12w8 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-lN2aoPu05d5i12w8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Watch 数据流
etcd Watch
Cacher
WatchCache
事件缓存与分发
Watcher
HTTP Chunked Transfer
Client
流式接收变更事件
出站数据流
etcd Get/Watch
Decoder
从Protobuf反序列化
Convertor
版本转换
(internal→external)
NegotiatedSerializer
协商编码
(JSON/YAML/Protobuf)
HTTP Response
入站数据流
HTTP Request
(JSON/YAML/Protobuf)
Decoder
反序列化
Defaulter
填充默认值
Convertor
版本转换
(external→internal)
Validation
校验
Admission
准入控制
(Mutating→Validating)
Encoder
序列化为Protobuf
etcd Put
图10:接口层次图
#mermaid-svg-1xnWwNcn05Klqzmf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1xnWwNcn05Klqzmf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1xnWwNcn05Klqzmf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1xnWwNcn05Klqzmf .error-icon{fill:#552222;}#mermaid-svg-1xnWwNcn05Klqzmf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1xnWwNcn05Klqzmf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1xnWwNcn05Klqzmf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1xnWwNcn05Klqzmf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1xnWwNcn05Klqzmf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1xnWwNcn05Klqzmf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1xnWwNcn05Klqzmf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1xnWwNcn05Klqzmf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1xnWwNcn05Klqzmf .marker.cross{stroke:#333333;}#mermaid-svg-1xnWwNcn05Klqzmf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1xnWwNcn05Klqzmf p{margin:0;}#mermaid-svg-1xnWwNcn05Klqzmf g.classGroup text{fill:#9370DB;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-1xnWwNcn05Klqzmf g.classGroup text .title{font-weight:bolder;}#mermaid-svg-1xnWwNcn05Klqzmf .cluster-label text{fill:#333;}#mermaid-svg-1xnWwNcn05Klqzmf .cluster-label span{color:#333;}#mermaid-svg-1xnWwNcn05Klqzmf .cluster-label span p{background-color:transparent;}#mermaid-svg-1xnWwNcn05Klqzmf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1xnWwNcn05Klqzmf .cluster text{fill:#333;}#mermaid-svg-1xnWwNcn05Klqzmf .cluster span{color:#333;}#mermaid-svg-1xnWwNcn05Klqzmf .nodeLabel,#mermaid-svg-1xnWwNcn05Klqzmf .edgeLabel{color:#131300;}#mermaid-svg-1xnWwNcn05Klqzmf .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-1xnWwNcn05Klqzmf .label text{fill:#131300;}#mermaid-svg-1xnWwNcn05Klqzmf .labelBkg{background:#ECECFF;}#mermaid-svg-1xnWwNcn05Klqzmf .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-1xnWwNcn05Klqzmf .classTitle{font-weight:bolder;}#mermaid-svg-1xnWwNcn05Klqzmf .node rect,#mermaid-svg-1xnWwNcn05Klqzmf .node circle,#mermaid-svg-1xnWwNcn05Klqzmf .node ellipse,#mermaid-svg-1xnWwNcn05Klqzmf .node polygon,#mermaid-svg-1xnWwNcn05Klqzmf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1xnWwNcn05Klqzmf .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf g.clickable{cursor:pointer;}#mermaid-svg-1xnWwNcn05Klqzmf g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-1xnWwNcn05Klqzmf g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-1xnWwNcn05Klqzmf .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-1xnWwNcn05Klqzmf .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-1xnWwNcn05Klqzmf .dashed-line{stroke-dasharray:3;}#mermaid-svg-1xnWwNcn05Klqzmf .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-1xnWwNcn05Klqzmf #compositionStart,#mermaid-svg-1xnWwNcn05Klqzmf .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf #compositionEnd,#mermaid-svg-1xnWwNcn05Klqzmf .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf #dependencyStart,#mermaid-svg-1xnWwNcn05Klqzmf .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf #dependencyStart,#mermaid-svg-1xnWwNcn05Klqzmf .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf #extensionStart,#mermaid-svg-1xnWwNcn05Klqzmf .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf #extensionEnd,#mermaid-svg-1xnWwNcn05Klqzmf .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf #aggregationStart,#mermaid-svg-1xnWwNcn05Klqzmf .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf #aggregationEnd,#mermaid-svg-1xnWwNcn05Klqzmf .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf #lollipopStart,#mermaid-svg-1xnWwNcn05Klqzmf .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf #lollipopEnd,#mermaid-svg-1xnWwNcn05Klqzmf .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-1xnWwNcn05Klqzmf .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-1xnWwNcn05Klqzmf .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1xnWwNcn05Klqzmf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1xnWwNcn05Klqzmf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1xnWwNcn05Klqzmf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} optional
<<interface>>
DelegationTarget
+UnprotectedHandler() : http.Handler
+PostStartHooks() : map
+PreShutdownHooks() : map
+HealthzChecks() : \[\]HealthChecker
+ListedPaths() : \[\]string
+NextDelegate() : DelegationTarget
+PrepareRun() : preparedGenericAPIServer
emptyDelegate
全部返回 nil/空
GenericAPIServer
实现 DelegationTarget
APIGroupInfo
+PrioritizedVersions \[\]GroupVersion
+VersionedResourcesStorageMap map
+Scheme *runtime.Scheme
+NegotiatedSerializer
+ParameterCodec
+StaticOpenAPISpec
<<interface>>
RESTStorageProvider
+GroupName() : string
+NewRESTStorage(...)(APIGroupInfo, bool, error)
<<interface>>
PostStartHookProvider
+PostStartHook()(string, PostStartHookFunc, error)
<<interface>>
authenticator_Request
+AuthenticateRequest(req)(Response, bool, error)
<<interface>>
authorizer_Authorizer
+Authorize(ctx, attr)(Decision, string, error)
<<interface>>
admission_Interface
+Handle(ctx, attr) : error
<<interface>>
flowcontrol_Interface
+Handle(ctx, request) : FlowControlStatus
+Run(stopCh)
+MaintainObservations(stopCh)
corerest.LegacyRESTStorageProvider
rbacrest.RESTStorageProvider
图11:Options 层次图
#mermaid-svg-VsravstTxfMAhIoZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VsravstTxfMAhIoZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VsravstTxfMAhIoZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VsravstTxfMAhIoZ .error-icon{fill:#552222;}#mermaid-svg-VsravstTxfMAhIoZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VsravstTxfMAhIoZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VsravstTxfMAhIoZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VsravstTxfMAhIoZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VsravstTxfMAhIoZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VsravstTxfMAhIoZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VsravstTxfMAhIoZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VsravstTxfMAhIoZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VsravstTxfMAhIoZ .marker.cross{stroke:#333333;}#mermaid-svg-VsravstTxfMAhIoZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VsravstTxfMAhIoZ p{margin:0;}#mermaid-svg-VsravstTxfMAhIoZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-VsravstTxfMAhIoZ .cluster-label text{fill:#333;}#mermaid-svg-VsravstTxfMAhIoZ .cluster-label span{color:#333;}#mermaid-svg-VsravstTxfMAhIoZ .cluster-label span p{background-color:transparent;}#mermaid-svg-VsravstTxfMAhIoZ .label text,#mermaid-svg-VsravstTxfMAhIoZ span{fill:#333;color:#333;}#mermaid-svg-VsravstTxfMAhIoZ .node rect,#mermaid-svg-VsravstTxfMAhIoZ .node circle,#mermaid-svg-VsravstTxfMAhIoZ .node ellipse,#mermaid-svg-VsravstTxfMAhIoZ .node polygon,#mermaid-svg-VsravstTxfMAhIoZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VsravstTxfMAhIoZ .rough-node .label text,#mermaid-svg-VsravstTxfMAhIoZ .node .label text,#mermaid-svg-VsravstTxfMAhIoZ .image-shape .label,#mermaid-svg-VsravstTxfMAhIoZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-VsravstTxfMAhIoZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VsravstTxfMAhIoZ .rough-node .label,#mermaid-svg-VsravstTxfMAhIoZ .node .label,#mermaid-svg-VsravstTxfMAhIoZ .image-shape .label,#mermaid-svg-VsravstTxfMAhIoZ .icon-shape .label{text-align:center;}#mermaid-svg-VsravstTxfMAhIoZ .node.clickable{cursor:pointer;}#mermaid-svg-VsravstTxfMAhIoZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VsravstTxfMAhIoZ .arrowheadPath{fill:#333333;}#mermaid-svg-VsravstTxfMAhIoZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VsravstTxfMAhIoZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VsravstTxfMAhIoZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VsravstTxfMAhIoZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VsravstTxfMAhIoZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VsravstTxfMAhIoZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VsravstTxfMAhIoZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VsravstTxfMAhIoZ .cluster text{fill:#333;}#mermaid-svg-VsravstTxfMAhIoZ .cluster span{color:#333;}#mermaid-svg-VsravstTxfMAhIoZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VsravstTxfMAhIoZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VsravstTxfMAhIoZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-VsravstTxfMAhIoZ .icon-shape,#mermaid-svg-VsravstTxfMAhIoZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VsravstTxfMAhIoZ .icon-shape p,#mermaid-svg-VsravstTxfMAhIoZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VsravstTxfMAhIoZ .icon-shape .label rect,#mermaid-svg-VsravstTxfMAhIoZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VsravstTxfMAhIoZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VsravstTxfMAhIoZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VsravstTxfMAhIoZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ServerRunOptions
(顶层选项)
GenericServerRunOptions
AdvertiseAddress
MaxRequestsInFlight
RequestTimeout
GoawayChance
ShutdownDelayDuration
EtcdOptions
ServerList
Prefix
Codec
EnableWatchCache
WatchCacheSizes
SecureServingOptionsWithLoopback
BindAddress
BindPort
ServerCert
SNICertKeys
BuiltInAuthenticationOptions
ClientCert
TokenFile
OIDC
ServiceAccounts
RequestHeader
BootstrapToken
Webhook
BuiltInAuthorizationOptions
Modes(RBAC/ABAC/Node/Webhook)
PolicyFile
WebhookConfigFile
AdmissionOptions
RecommendedAdmissionOptions
PluginNames
ConfigFile
AuditOptions
LogOptions
WebhookOptions
PolicyFile
FeatureOptions
EnableWatchCache
APIEnablement
APIEnablementOptions
RuntimeConfig
EgressSelectorOptions
ConfigFile
CloudProviderOptions
CloudProvider
CloudConfigFile
KubeAPIServer 专属
EventTTL
ServiceClusterIPRanges
KubeletConfig
MasterCount
ServiceAccountSigningKeyFile
图12:ServerChain 构建时序图
Aggregator Server APIExtensions Server KubeAPIServer CreateServerChain() Run() Validate() Complete() Cobra Command main() Aggregator Server APIExtensions Server KubeAPIServer CreateServerChain() Run() Validate() Complete() Cobra Command main() #mermaid-svg-DMDIsfm9G6qCKLh2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DMDIsfm9G6qCKLh2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DMDIsfm9G6qCKLh2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DMDIsfm9G6qCKLh2 .error-icon{fill:#552222;}#mermaid-svg-DMDIsfm9G6qCKLh2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DMDIsfm9G6qCKLh2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DMDIsfm9G6qCKLh2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DMDIsfm9G6qCKLh2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DMDIsfm9G6qCKLh2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DMDIsfm9G6qCKLh2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DMDIsfm9G6qCKLh2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DMDIsfm9G6qCKLh2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DMDIsfm9G6qCKLh2 .marker.cross{stroke:#333333;}#mermaid-svg-DMDIsfm9G6qCKLh2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DMDIsfm9G6qCKLh2 p{margin:0;}#mermaid-svg-DMDIsfm9G6qCKLh2 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-DMDIsfm9G6qCKLh2 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-DMDIsfm9G6qCKLh2 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-DMDIsfm9G6qCKLh2 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-DMDIsfm9G6qCKLh2 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-DMDIsfm9G6qCKLh2 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-DMDIsfm9G6qCKLh2 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-DMDIsfm9G6qCKLh2 .sequenceNumber{fill:white;}#mermaid-svg-DMDIsfm9G6qCKLh2 #sequencenumber{fill:#333;}#mermaid-svg-DMDIsfm9G6qCKLh2 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-DMDIsfm9G6qCKLh2 .messageText{fill:#333;stroke:none;}#mermaid-svg-DMDIsfm9G6qCKLh2 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-DMDIsfm9G6qCKLh2 .labelText,#mermaid-svg-DMDIsfm9G6qCKLh2 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-DMDIsfm9G6qCKLh2 .loopText,#mermaid-svg-DMDIsfm9G6qCKLh2 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-DMDIsfm9G6qCKLh2 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-DMDIsfm9G6qCKLh2 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-DMDIsfm9G6qCKLh2 .noteText,#mermaid-svg-DMDIsfm9G6qCKLh2 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-DMDIsfm9G6qCKLh2 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-DMDIsfm9G6qCKLh2 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-DMDIsfm9G6qCKLh2 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-DMDIsfm9G6qCKLh2 .actorPopupMenu{position:absolute;}#mermaid-svg-DMDIsfm9G6qCKLh2 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-DMDIsfm9G6qCKLh2 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-DMDIsfm9G6qCKLh2 .actor-man circle,#mermaid-svg-DMDIsfm9G6qCKLh2 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-DMDIsfm9G6qCKLh2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} DefaultAdvertiseAddressParseServiceIPRangeMaybeDefaultWithSelfSignedCertsSetupExternalHostSetupServiceAccountKey === 构建委托链 === NewConfig → ApplyTo各Options→ StorageFactory → Informers→ AuthN → AuthZ → Audit → Admission → FC shallow copy genericConfig清空PostStartHooks覆盖Codec/RESTOptionsGetter Config.Complete().New(EmptyDelegate)CRD 注册到 etcd par创建 CRD Server(内层先创建) Config.Complete().New(CRD.GenericAPIServer)安装 /api/v1 + /apis/*注册 bootstrap controller注册 identity lease hooks par创建 KubeAPIServer(中间层) shallow copy genericConfigSkipOpenAPIInstallation=true覆盖Codec/RESTOptionsGetter Config.Complete().NewWithDelegate(KAS)创建 autoRegistrationController创建 crdRegistrationController注册 autoregistration hook par创建 Aggregator(最外层) 安装OpenAPI/Healthz/Livez/Readyz安装Audit PreShutdownHook递归调用delegate.PrepareRun() 启动HTTP ServerRunPostStartHooks等待优雅关闭 执行 RunEComplete(s)completedServerRunOptionsValidate()nil (校验通过)Run(completedOptions, stopCh)CreateServerChain()CreateNodeDialer()buildGenericConfig()CreateKubeAPIServerConfig()createAPIExtensionsConfig()createAPIExtensionsServer(EmptyDelegate)CreateKubeAPIServer(CRD Server)createAggregatorConfig()createAggregatorServer(KAS.GenericAPIServer)APIAggregatorPrepareRun()Run(stopCh)
图13:健康检查图
#mermaid-svg-n3GC39PbmrGHW0ha{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-n3GC39PbmrGHW0ha .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-n3GC39PbmrGHW0ha .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-n3GC39PbmrGHW0ha .error-icon{fill:#552222;}#mermaid-svg-n3GC39PbmrGHW0ha .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-n3GC39PbmrGHW0ha .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-n3GC39PbmrGHW0ha .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-n3GC39PbmrGHW0ha .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-n3GC39PbmrGHW0ha .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-n3GC39PbmrGHW0ha .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-n3GC39PbmrGHW0ha .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-n3GC39PbmrGHW0ha .marker{fill:#333333;stroke:#333333;}#mermaid-svg-n3GC39PbmrGHW0ha .marker.cross{stroke:#333333;}#mermaid-svg-n3GC39PbmrGHW0ha svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-n3GC39PbmrGHW0ha p{margin:0;}#mermaid-svg-n3GC39PbmrGHW0ha .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-n3GC39PbmrGHW0ha .cluster-label text{fill:#333;}#mermaid-svg-n3GC39PbmrGHW0ha .cluster-label span{color:#333;}#mermaid-svg-n3GC39PbmrGHW0ha .cluster-label span p{background-color:transparent;}#mermaid-svg-n3GC39PbmrGHW0ha .label text,#mermaid-svg-n3GC39PbmrGHW0ha span{fill:#333;color:#333;}#mermaid-svg-n3GC39PbmrGHW0ha .node rect,#mermaid-svg-n3GC39PbmrGHW0ha .node circle,#mermaid-svg-n3GC39PbmrGHW0ha .node ellipse,#mermaid-svg-n3GC39PbmrGHW0ha .node polygon,#mermaid-svg-n3GC39PbmrGHW0ha .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-n3GC39PbmrGHW0ha .rough-node .label text,#mermaid-svg-n3GC39PbmrGHW0ha .node .label text,#mermaid-svg-n3GC39PbmrGHW0ha .image-shape .label,#mermaid-svg-n3GC39PbmrGHW0ha .icon-shape .label{text-anchor:middle;}#mermaid-svg-n3GC39PbmrGHW0ha .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-n3GC39PbmrGHW0ha .rough-node .label,#mermaid-svg-n3GC39PbmrGHW0ha .node .label,#mermaid-svg-n3GC39PbmrGHW0ha .image-shape .label,#mermaid-svg-n3GC39PbmrGHW0ha .icon-shape .label{text-align:center;}#mermaid-svg-n3GC39PbmrGHW0ha .node.clickable{cursor:pointer;}#mermaid-svg-n3GC39PbmrGHW0ha .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-n3GC39PbmrGHW0ha .arrowheadPath{fill:#333333;}#mermaid-svg-n3GC39PbmrGHW0ha .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-n3GC39PbmrGHW0ha .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-n3GC39PbmrGHW0ha .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-n3GC39PbmrGHW0ha .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-n3GC39PbmrGHW0ha .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-n3GC39PbmrGHW0ha .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-n3GC39PbmrGHW0ha .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-n3GC39PbmrGHW0ha .cluster text{fill:#333;}#mermaid-svg-n3GC39PbmrGHW0ha .cluster span{color:#333;}#mermaid-svg-n3GC39PbmrGHW0ha div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-n3GC39PbmrGHW0ha .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-n3GC39PbmrGHW0ha rect.text{fill:none;stroke-width:0;}#mermaid-svg-n3GC39PbmrGHW0ha .icon-shape,#mermaid-svg-n3GC39PbmrGHW0ha .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-n3GC39PbmrGHW0ha .icon-shape p,#mermaid-svg-n3GC39PbmrGHW0ha .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-n3GC39PbmrGHW0ha .icon-shape .label rect,#mermaid-svg-n3GC39PbmrGHW0ha .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-n3GC39PbmrGHW0ha .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-n3GC39PbmrGHW0ha .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-n3GC39PbmrGHW0ha :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 生命周期与检查关系
livezGracePeriod内
所有Hook完成
启动中
/livez = OK
(即使Hook未完成)
运行中
/healthz /livez /readyz = OK
收到SIGTERM
/readyz = FAIL
(立即)
/healthz /livez = OK
(ShutdownDelay期间)
真正关闭
所有检查 = FAIL
/readyz --- 就绪检查
PingHealthz
LogHealthz
poststarthook/*
InformerSyncHealthz
shutdown check
(readinessStopCh关闭→失败)
autoregister-completion
(APIService全部Available)
/livez --- 存活检查
PingHealthz
LogHealthz
poststarthook/*
InformerSyncHealthz
livezGracePeriod
(启动宽限期内
未完成Hook也返回OK)
/healthz --- 进程级健康
PingHealthz
LogHealthz
poststarthook/*
(每个Hook一个)
InformerSyncHealthz
(Informer同步检查)
图14:Delegate Chain 详细路由图
#mermaid-svg-4sBm2fUf0MhzsoTE{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4sBm2fUf0MhzsoTE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4sBm2fUf0MhzsoTE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4sBm2fUf0MhzsoTE .error-icon{fill:#552222;}#mermaid-svg-4sBm2fUf0MhzsoTE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4sBm2fUf0MhzsoTE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4sBm2fUf0MhzsoTE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4sBm2fUf0MhzsoTE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4sBm2fUf0MhzsoTE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4sBm2fUf0MhzsoTE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4sBm2fUf0MhzsoTE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4sBm2fUf0MhzsoTE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4sBm2fUf0MhzsoTE .marker.cross{stroke:#333333;}#mermaid-svg-4sBm2fUf0MhzsoTE svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4sBm2fUf0MhzsoTE p{margin:0;}#mermaid-svg-4sBm2fUf0MhzsoTE .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-4sBm2fUf0MhzsoTE .cluster-label text{fill:#333;}#mermaid-svg-4sBm2fUf0MhzsoTE .cluster-label span{color:#333;}#mermaid-svg-4sBm2fUf0MhzsoTE .cluster-label span p{background-color:transparent;}#mermaid-svg-4sBm2fUf0MhzsoTE .label text,#mermaid-svg-4sBm2fUf0MhzsoTE span{fill:#333;color:#333;}#mermaid-svg-4sBm2fUf0MhzsoTE .node rect,#mermaid-svg-4sBm2fUf0MhzsoTE .node circle,#mermaid-svg-4sBm2fUf0MhzsoTE .node ellipse,#mermaid-svg-4sBm2fUf0MhzsoTE .node polygon,#mermaid-svg-4sBm2fUf0MhzsoTE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4sBm2fUf0MhzsoTE .rough-node .label text,#mermaid-svg-4sBm2fUf0MhzsoTE .node .label text,#mermaid-svg-4sBm2fUf0MhzsoTE .image-shape .label,#mermaid-svg-4sBm2fUf0MhzsoTE .icon-shape .label{text-anchor:middle;}#mermaid-svg-4sBm2fUf0MhzsoTE .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4sBm2fUf0MhzsoTE .rough-node .label,#mermaid-svg-4sBm2fUf0MhzsoTE .node .label,#mermaid-svg-4sBm2fUf0MhzsoTE .image-shape .label,#mermaid-svg-4sBm2fUf0MhzsoTE .icon-shape .label{text-align:center;}#mermaid-svg-4sBm2fUf0MhzsoTE .node.clickable{cursor:pointer;}#mermaid-svg-4sBm2fUf0MhzsoTE .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4sBm2fUf0MhzsoTE .arrowheadPath{fill:#333333;}#mermaid-svg-4sBm2fUf0MhzsoTE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4sBm2fUf0MhzsoTE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4sBm2fUf0MhzsoTE .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4sBm2fUf0MhzsoTE .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4sBm2fUf0MhzsoTE .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4sBm2fUf0MhzsoTE .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4sBm2fUf0MhzsoTE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4sBm2fUf0MhzsoTE .cluster text{fill:#333;}#mermaid-svg-4sBm2fUf0MhzsoTE .cluster span{color:#333;}#mermaid-svg-4sBm2fUf0MhzsoTE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4sBm2fUf0MhzsoTE .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4sBm2fUf0MhzsoTE rect.text{fill:none;stroke-width:0;}#mermaid-svg-4sBm2fUf0MhzsoTE .icon-shape,#mermaid-svg-4sBm2fUf0MhzsoTE .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4sBm2fUf0MhzsoTE .icon-shape p,#mermaid-svg-4sBm2fUf0MhzsoTE .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4sBm2fUf0MhzsoTE .icon-shape .label rect,#mermaid-svg-4sBm2fUf0MhzsoTE .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4sBm2fUf0MhzsoTE .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4sBm2fUf0MhzsoTE .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4sBm2fUf0MhzsoTE :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
APIExtensions 层路由
/apis/apiextensions.k8s.io/
→ CRD 定义资源
/apis/{crd-group}/{crd-version}/
→ CRD 实例资源
(动态注册)
其他 → EmptyDelegate
→ 404
KubeAPIServer 层路由
/api/v1/
→ Core REST Storage
(Pod/Service/Node等)
/apis/apps/v1/
→ Apps REST Storage
/apis/batch/v1/
→ Batch REST Storage
/apis/rbac.authorization.k8s.io/v1/
→ RBAC REST Storage
... 其他内置组
其他 → delegate to APIExtensions
Aggregator 层路由
/apis/apiregistration.k8s.io/
→ APIService REST Storage
/apis/{group}/{version}/...
→ 代理到后端 API Server
其他 → delegate to KubeAPIServer
请求进入
FullHandlerChain
(过滤链)
Director
(路由分发)
/apis路径且匹配
GoRestful WebService?
GoRestfulContainer
Dispatch
NonGoRestfulMux
Delegate Handler
(下一层委托)
图15:路由注册图
#mermaid-svg-8xlyQg1r4ILY81H8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8xlyQg1r4ILY81H8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8xlyQg1r4ILY81H8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8xlyQg1r4ILY81H8 .error-icon{fill:#552222;}#mermaid-svg-8xlyQg1r4ILY81H8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8xlyQg1r4ILY81H8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8xlyQg1r4ILY81H8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8xlyQg1r4ILY81H8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8xlyQg1r4ILY81H8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8xlyQg1r4ILY81H8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8xlyQg1r4ILY81H8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8xlyQg1r4ILY81H8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8xlyQg1r4ILY81H8 .marker.cross{stroke:#333333;}#mermaid-svg-8xlyQg1r4ILY81H8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8xlyQg1r4ILY81H8 p{margin:0;}#mermaid-svg-8xlyQg1r4ILY81H8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8xlyQg1r4ILY81H8 .cluster-label text{fill:#333;}#mermaid-svg-8xlyQg1r4ILY81H8 .cluster-label span{color:#333;}#mermaid-svg-8xlyQg1r4ILY81H8 .cluster-label span p{background-color:transparent;}#mermaid-svg-8xlyQg1r4ILY81H8 .label text,#mermaid-svg-8xlyQg1r4ILY81H8 span{fill:#333;color:#333;}#mermaid-svg-8xlyQg1r4ILY81H8 .node rect,#mermaid-svg-8xlyQg1r4ILY81H8 .node circle,#mermaid-svg-8xlyQg1r4ILY81H8 .node ellipse,#mermaid-svg-8xlyQg1r4ILY81H8 .node polygon,#mermaid-svg-8xlyQg1r4ILY81H8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8xlyQg1r4ILY81H8 .rough-node .label text,#mermaid-svg-8xlyQg1r4ILY81H8 .node .label text,#mermaid-svg-8xlyQg1r4ILY81H8 .image-shape .label,#mermaid-svg-8xlyQg1r4ILY81H8 .icon-shape .label{text-anchor:middle;}#mermaid-svg-8xlyQg1r4ILY81H8 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8xlyQg1r4ILY81H8 .rough-node .label,#mermaid-svg-8xlyQg1r4ILY81H8 .node .label,#mermaid-svg-8xlyQg1r4ILY81H8 .image-shape .label,#mermaid-svg-8xlyQg1r4ILY81H8 .icon-shape .label{text-align:center;}#mermaid-svg-8xlyQg1r4ILY81H8 .node.clickable{cursor:pointer;}#mermaid-svg-8xlyQg1r4ILY81H8 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8xlyQg1r4ILY81H8 .arrowheadPath{fill:#333333;}#mermaid-svg-8xlyQg1r4ILY81H8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8xlyQg1r4ILY81H8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8xlyQg1r4ILY81H8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8xlyQg1r4ILY81H8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8xlyQg1r4ILY81H8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8xlyQg1r4ILY81H8 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8xlyQg1r4ILY81H8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8xlyQg1r4ILY81H8 .cluster text{fill:#333;}#mermaid-svg-8xlyQg1r4ILY81H8 .cluster span{color:#333;}#mermaid-svg-8xlyQg1r4ILY81H8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8xlyQg1r4ILY81H8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8xlyQg1r4ILY81H8 rect.text{fill:none;stroke-width:0;}#mermaid-svg-8xlyQg1r4ILY81H8 .icon-shape,#mermaid-svg-8xlyQg1r4ILY81H8 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8xlyQg1r4ILY81H8 .icon-shape p,#mermaid-svg-8xlyQg1r4ILY81H8 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8xlyQg1r4ILY81H8 .icon-shape .label rect,#mermaid-svg-8xlyQg1r4ILY81H8 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8xlyQg1r4ILY81H8 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8xlyQg1r4ILY81H8 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8xlyQg1r4ILY81H8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Aggregator 路由注册
/apis/apiregistration.k8s.io/
APIService
代理路由
根据APIService
代理到后端Server
APIExtensions 路由注册
/apis/apiextensions.k8s.io/
CustomResourceDefinition
动态路由
根据CRD定义
自动注册/{group}/{version}/{resource}
KubeAPIServer 路由注册
InstallLegacyAPI
(/api/v1)
pods → PodStorage
services → ServiceStorage
nodes → NodeStorage
configmaps → ConfigMapStorage
secrets → SecretStorage
endpoints → EndpointStorage
events → EventStorage
persistentvolumes → PVStorage
persistentvolumeclaims → PVCStorage
namespaces → NamespaceStorage
serviceaccounts → SAStorage
... 其他核心资源
InstallAPIs
(/apis/*)
apps → Deployment/ReplicaSet/StatefulSet/DaemonSet
authentication → TokenReview/TokenRequest
authorization → SubjectAccessReview/SelfSubjectAccessReview
batch → Job/CronJob
certificates → CertificateSigningRequest
networking → Ingress/NetworkPolicy
rbac.authorization → Role/RoleBinding/ClusterRole/ClusterRoleBinding
storage → StorageClass/VolumeAttachment
admissionregistration → ValidatingWebhook/MutatingWebhook
scheduling → PriorityClass
coordination → Lease
node → RuntimeClass
discovery → EndpointSlice
events.k8s.io → Event
policy → PodDisruptionBudget
flowcontrol → FlowSchema/PriorityLevelConfiguration
extensions → Ingress(legacy)
internal.apiserver → StorageVersion
五、总结与关键洞察
5.1 设计模式总结
| 模式 | 应用 |
|---|---|
| Delegation Chain | 三层服务器通过委托链组合,实现关注点分离与可扩展性 |
| CompletedConfig Pattern | 私有结构体+公开包装,强制 Complete→New 调用顺序 |
| Builder Pattern | Options→ApplyTo→Config→New,逐步构建复杂配置 |
| Hook Pattern | PostStartHook/PreShutdownHook 实现延迟初始化与优雅清理 |
| Strategy Pattern | Authenticator/Authorizer/Admission 通过接口替换具体实现 |
| Observer Pattern | dynamiccertificates.Notifier/Listener 实现证书热更新 |
| Factory Pattern | StorageFactory、RESTStorageProvider 封装资源创建逻辑 |
5.2 关键架构决策
-
Shallow Copy 配置传递:APIExtensions 和 Aggregator 对 KubeAPIServer 的 Config 进行浅拷贝,共享大部分配置但覆盖关键差异(Codec、RESTOptionsGetter、Scheme)
-
Protobuf 自通信:LoopbackClientConfig 使用 protobuf 编码(最高效),禁用压缩(本地通信无需压缩),这是 apiserver 内部通信的性能优化
-
PostStartHook 的容错设计 :每个 Hook 有独立的
donechannel 和健康检查,Hook 意外 panic 被HandleCrash()捕获,但故意失败(klog.Fatalf)会杀死进程------因为 Hook 失败意味着服务器不可用 -
优雅关闭的分层设计:先标记不就绪(/readyz 失败)→ 等待 LB 摘除(ShutdownDelayDuration)→ 执行 PreShutdownHook → 关闭 HTTP Server → 等待请求完成
-
Handler Chain 的洋葱模型:过滤链从外到内依次包裹,每个 Filter 负责一个关注点,最内层是 Director 路由分发器
5.3 启动时序关键点
- Options → Config 是单向的、不可逆的转化
- Server Chain 从内到外构建:EmptyDelegate → APIExtensions → KubeAPIServer → Aggregator
- 请求从外到内流转:Aggregator → KubeAPIServer → APIExtensions → EmptyDelegate
- PostStartHook 在 HTTP 服务启动后执行,否则无法使用 LoopbackClientConfig
- systemd 通知在所有 Hook 启动后发送,表示服务就绪
本文档基于 Kubernetes 源码
cmd/kube-apiserver/app/server.go、apiextensions.go、aggregator.go、pkg/controlplane/instance.go、staging/src/k8s.io/apiserver/pkg/server/config.go、genericapiserver.go、handler.go、hooks.go、secure_serving.go等核心文件深度分析编写。