kube-apiserver 深度剖析

概述

kube-apiserver 是 Kubernetes 控制平面的核心组件,提供 RESTful API,是所有组件和客户端与集群交互的网关。它负责:

  • 处理所有 REST 操作
  • 执行认证、授权、准入控制
  • 数据存储到 etcd
  • 资源验证和变更
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
┌─────────────────────────────────────────────────────────────────────────┐
│ kube-apiserver 架构图 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 外部请求 │
│ kubectl、kubelet、controller、client-go │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Request Flow │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ │
│ │ │ 认证 │───►│ 授权 │───►│ 准入 │───►│ 验证 │ │ │
│ │ │ (AuthN) │ │ (AuthZ) │ │(Admission)│ │ (Validation)│ │
│ │ └──────────┘ └──────────┘ └──────────┘ └─────────┘ │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Mutating │───►│ Storage │───►│ etcd │ │ │
│ │ │ Webhook │ │ │ │ │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 内部组件 │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Watch │ │ List │ │ Proxy │ │ Attach │ │ │
│ │ │ Cache │ │ Cache │ │ Handler │ │ Handler │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘

1. 请求处理流程

1.1 完整请求处理流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
┌─────────────────────────────────────────────────────────────────────────┐
│ API Server 请求处理流程 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ HTTP Request │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 1. Filter Chain (过滤器链) │ │
│ │ ├── WithAuthentication - 认证插件 │ │
│ │ ├── WithAuthorization - 授权插件 │ │
│ │ ├── WithAudit - 审计日志 │ │
│ │ └── WithCORS - 跨域资源共享 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 2. Route Matching (路由匹配) │ │
│ │ └── /api/v1/namespaces/{namespace}/pods/{name} │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 3. Handler Chain (处理器链) │ │
│ │ ├── InitSchema - 初始化存储 schema │ │
│ │ ├── RecoverFromPanic - 异常恢复 │ │
│ │ ├── WithGarbageCollection - 垃圾回收 │ │
│ │ └── WithAudit - 审计 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 4. Authentication (认证) │ │
│ │ ├── RequestHeaderAuthRequestor │ │
│ │ ├── ClientCertAuthenticator │ │
│ │ ├── BootstrapTokenAuthenticator │ │
│ │ └── ServiceAccountAuthenticator │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 5. Authorization (授权) │ │
│ │ ├── Node Authorization │ │
│ │ ├── RBAC Authorizer │ │
│ │ └── Webhook Authorization │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 6. Mutating Admission (变更准入) │ │
│ │ ├── AlwaysPullImages │ │
│ │ ├── DefaultStorageClass │ │
│ │ ├── DefaultTolerationSeconds │ │
│ │ └── Pod/Service/... MutatingWebhook │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 7. Validation (验证) │ │
│ │ └── Validate Object Schema & Custom Validation │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 8. Non-Mutating Admission (只读准入) │ │
│ │ ├── LimitRanger │ │
│ │ ├── ResourceQuota │ │
│ │ └── ... ValidatingWebhook │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 9. Storage (存储) │ │
│ │ └── etcd (通过 storage backend) │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ HTTP Response │
│ │
└─────────────────────────────────────────────────────────────────────────┘

1.2 核心代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// staging/src/k8s.io/apiserver/pkg/endpoints/filters/filters.go

// 认证过滤器
func WithAuthentication(handler http.Handler, ... ) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
// 1. 获取认证信息
user, ok := authenticator.AuthenticateRequest(req)

if !ok {
// 认证失败
handleAuthError(w, req)
return
}

// 2. 创建上下文
ctx := request.WithUser(req.Context(), user)
req = req.WithContext(ctx)

handler.ServeHTTP(w, req)
})
}

// 授权过滤器
func WithAuthorization(handler http.Handler, ... ) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
ctx := req.Context()
user, ok := request.UserFrom(ctx)

attributes := newRequestAttributes(req)

// 调用授权器
decision, reason, err := authorizer.Authorize(ctx, attributes)
if err != nil || decision != authorizer.DecisionAllow {
handleError(w, req, user, decision, reason)
return
}

handler.ServeHTTP(w, req)
})
}

2. 认证机制

2.1 认证插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
┌─────────────────────────────────────────────────────────────────────────┐
│ 认证插件架构 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 请求 │
│ │ │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ Authentication Chain │ │
│ └───────────┬────────────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ ClientCert │ │ BearerToken │ │ OIDC │ │
│ │ (x509) │ │ │ │ │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 验证 │ │ Token │ │ JWT Token │ │
│ │ 证书签名 │ │ 验证 │ │ 验证 │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┼─────────────────┘ │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ UserInfo + Groups │ │
│ │ (返回认证用户信息) │ │
│ └────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘

2.2 认证插件实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// staging/src/k8s.io/apiserver/pkg/authentication/auth.go
type Authenticator interface {
Authenticate(ctx context.Context, req *Request) (*Response, bool, error)
}

// 认证响应
type Response struct {
User user.Info
Expires time.Time
// ...
}

// 认证插件示例:ClientCert 认证
type x509Authenticator struct {
opts x509.VerifyOptions
}

func (a *x509Authenticator) Authenticate(
ctx context.Context,
req *authenticator.Request,
) (*authenticator.Response, bool, error) {
// 1. 获取客户端证书
clientCerts := req.TLS.GetPeerCertificates()
if len(clientCerts) == 0 {
return nil, false, nil
}

// 2. 验证证书
opts := a.opts
if opts.IntermediateCerts != nil {
// 使用中间证书验证
}

// 3. 提取用户信息
user := extractUserFromCert(clientCerts[0])

return &authenticator.Response{User: user}, true, nil
}

2.3 认证方式对比

认证方式 用途 配置
x509 ClientCert 集群组件间通信 --client-ca-file
Bearer Token ServiceAccount 自动挂载到 Pod
Bootstrap Token 节点引导加入 --enable-bootstrap-token-auth
OIDC 外部身份提供商 --oidc-* 参数
Webhook 第三方认证 --authentication-token-webhook-config-file

3. 授权机制

3.1 授权插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// staging/src/k8s.io/apiserver/pkg/authorization/authorizer.go
type Authorizer interface {
Authorize(ctx context.Context, attrs Attributes) (Decision, string, error)
}

// 授权决策
const (
DecisionAllow Decision = "Allow"
DecisionDeny Decision = "Deny"
DecisionNoOpinion Decision = "No Opinion"
)

// 请求属性
type AttributesRecord struct {
User user.Info
Verb string // get, list, create, update, delete, deletecollection
Resource string // pods, services, deployments
Subresource string // log, exec, status
Name string // specific resource name
Namespace string
APIGroup string // "", "apps", "batch"
APIResource string
ResourceRequest bool
Path string // /api/v1/pods
}

3.2 RBAC 授权

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 核心 RBAC 类型
type Role struct {
TypeMeta
ObjectMeta
Rules []PolicyRule
}

type PolicyRule struct {
// 资源列表
Resources []string
// 动词列表
Verbs []string
// API 组
APIGroups []string
// 命名空间
Namespaces []string
// 非资源 URL
NonResourceURLs []string
}

// RBAC 决策逻辑
func (r *RBACAuthorizer) Authorize(ctx context.Context, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
// 1. 检查用户权限
for _, rule := range getRulesForUser(attrs.GetUser()) {
if rule.Matches(attrs) {
return authorizer.DecisionAllow, "", nil
}
}

// 2. 检查角色绑定
for _, binding := range getBindingsForUser(attrs.GetUser()) {
if bindingRoleMatches(binding.Role, attrs) {
return authorizer.DecisionAllow, "", nil
}
}

return authorizer.DecisionNoOpinion, "RBAC: no matching role found", nil
}

3.3 授权模式配置

1
2
3
4
5
6
# 配置授权模式
kube-apiserver --authorization-mode=Node,RBAC,Webhook

# Node 授权:允许 kubelet 访问自己节点的资源
# RBAC:基于角色的访问控制
# Webhook:外部授权服务

4. 准入控制

4.1 准入控制器链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
┌─────────────────────────────────────────────────────────────────────────┐
│ 准入控制器执行顺序 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ Mutating Phase (变更阶段) │ │
│ │ │ │
│ │ 1. NamespaceLifecycle - 强制创建命名空间 │ │
│ │ 2. LimitRanger - 设置资源限制 │ │
│ │ 3. NodeRestriction - 限制节点修改内容 │ │
│ │ 4. TaintNodesByCondition - 添加污点 │ │
│ │ 5. DefaultStorageClass - 设置默认存储类 │ │
│ │ 6. DefaultTolerationSeconds - 设置默认容忍时间 │ │
│ │ 7. MutatingWebhook - 自定义变更 webhook │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ Validation Phase (验证阶段) │ │
│ │ │ │
│ │ 1. NamespaceLifecycle - 防止删除系统命名空间 │ │
│ │ 2. ResourceQuota - 验证资源配额 │ │
│ │ 3. LimitRange - 验证资源限制 │ │
│ │ 4. PodNodeSelector - 验证节点选择器 │ │
│ │ 5. ValidatingWebhook - 自定义验证 webhook │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘

4.2 准入控制器接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// staging/src/k8s.io/apiserver/pkg/admission/interfaces.go
type AdmissionInterface interface {
Admit(ctx context.Context, a Attributes, o ObjectInterfaces) error
Validate(ctx context.Context, a Attributes, o ObjectInterfaces) error
}

// Mutating 准入控制器
type MutatingAdmission interface {
Admit(ctx context.Context, a Attributes, o ObjectInterfaces) error
}

// Validating 准入控制器
type ValidatingAdmission interface {
Validate(ctx context.Context, a Attributes, o ObjectInterfaces) error
}

// 控制器实现示例
type LimitRanger struct {
handler *admission.Handler
limits LimitFunctions
}

func (l *LimitRanger) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
// 1. 检查资源类型
if a.GetKind().GroupKind() != api.Kind("Pod") {
return nil
}

// 2. 获取 LimitRange
lr := l.getLimitRange(a)

// 3. 应用默认资源
pod := a.GetObject().(*v1.Pod)
for i := range pod.Spec.Containers {
l.setContainerDefaults(&pod.Spec.Containers[i], lr)
}

return nil
}

4.3 Webhook 准入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// AdmissionWebhook 配置
type AdmissionWebhook struct {
Name string
ClientConfig AdmissionWebhookClientConfig
Rules []AdmissionRule
FailurePolicy *FailurePolicyType
SideEffects *SideEffectClass
Timeout *metav1.Duration
}

// Webhook 请求格式
type AdmissionReview struct {
TypeMeta
Request *AdmissionRequest
Response *AdmissionResponse
}

// 验证 Webhook 示例
{
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"request": {
"uid": "705ab4f5-6393-11e8-b7cc-6807142b4b2e",
"kind": {"group":"", "version":"v1", "kind":"Pod"},
"resource": {"group":"", "version":"v1", "resource":"pods"},
"operation": "CREATE",
"object": {
"metadata": {"name": "my-pod"},
"spec": {...}
},
"oldObject": null
}
}

5. 资源存储

5.1 Storage Backend

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// staging/src/k8s.io/apiserver/pkg/storage/storage_backend.go
type Storage interface {
// 读取
Get(ctx context.Context, key string, opts GetOptions, out Object) error

// 列表
List(ctx context.Context, key string, opts ListOptions, listObj Object) error

// 创建
Create(ctx context.Context, key string, obj, out Object, ttl uint64) error

// 更新
Update(ctx context.Context, key string, obj Object, out Object, ttl uint64) error

// 删除
Delete(ctx context.Context, key string, out Object, preconditions *Preconditions) error

// Watch
Watch(ctx context.Context, key string, opts ListOptions) (watch.Interface, error)

// 事务
WatchList(ctx context.Context, key string, opts ListOptions) (watch.Interface, error)

// 计数
Count(key string) (int64, error)
}

5.2 Cacher 机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// staging/src/k8s.io/apiserver/pkg/storage/cacher/cacher.go
type Cacher struct {
storage Storage
watchCache *watchCache
resourcePrefix string
newListFunc func() runtime.Object
}

func (c *Cacher) List(ctx context.Context, key string, opts storage.ListOptions, listObj runtime.Object) error {
// 1. 检查是否需要穿透到后端
if opts.ResourceVersion != "" {
// 指定版本,从 watchCache 读取
return c.watchCache.ReadProgressNotify(ctx, key, opts.ResourceVersion, listObj)
}

// 2. 从缓存读取最新数据
if c.watchCache.isCacheFresh() {
return c.watchCache.List(key, listObj)
}

// 3. 穿透到 etcd
return c.storage.List(ctx, key, opts, listObj)
}

func (c *Cacher) Watch(ctx context.Context, key string, opts storage.ListOptions) (watch.Interface, error) {
// 创建 watcher
return newCacheWatcher(c.watchCache, key, opts)
}

5.3 Watch 机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌─────────────────────────────────────────────────────────────────────────┐
│ API Server Watch 实现 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Client API Server WatchCache etcd │
│ │ │ │ │ │
│ │ Watch Pods │ │ │ │
│ │ ───────────────►│ │ │ │
│ │ │ │ │ │
│ │ │ 1. 注册 watcher │ │ │
│ │ │ ────────────────────►│ │ │
│ │ │ │ │ │
│ │ │ 2. 初始 bookmark │ │ │
│ │ ◄────────────── │ │ │ │
│ │ │ │ │ │
│ │ │ 3. Watch 事件 │ │ │
│ │ ◄────────────── │ ◄───────────────────│ │ │
│ │ │ │ │ │
│ │ 收到变更事件 │ │ │ │
│ │ ◄────────────── │ │ │ │
│ │ │ │ │ │
└─────────────────────────────────────────────────────────────────────────┘

6. 资源版本与并发控制

6.1 ResourceVersion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 资源版本用于乐观锁
type ObjectMeta struct {
ResourceVersion string `json:"resourceVersion,omitempty"`
UID types.UID `json:"uid,omitempty"`
}

// 读取时指定版本
pod, err := client.CoreV1().Pods("default").Get(
ctx,
"my-pod",
metav1.GetOptions{ResourceVersion: "12345"}
)

// 更新时携带版本
pod, err := client.CoreV1().Pods("default").Update(
ctx,
pod,
metav1.UpdateOptions{FieldManager: "my-app"}
)
// 如果版本冲突,返回 Conflict 错误

6.2 冲突处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 乐观锁冲突处理
func updateWithRetry(ctx context.Context, client v1.PodInterface, name string, updateFn func(*v1.Pod) *v1.Pod) (*v1.Pod, error) {
for i := 0; i < maxRetries; i++ {
// 1. 获取最新版本
pod, err := client.Get(ctx, name, metav1.GetOptions{})
if err != nil {
return nil, err
}

// 2. 应用更新
updated := updateFn(pod)

// 3. 尝试更新
result, err := client.Update(ctx, updated, metav1.UpdateOptions{})
if err == nil {
return result, nil
}

// 4. 处理冲突
if errors.IsConflict(err) {
continue // 重试
}
return nil, err
}
return nil, errors.New("max retries exceeded")
}

7. API 分组与扩展

7.1 API 组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
┌─────────────────────────────────────────────────────────────────────────┐
│ Kubernetes API 组 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ /api/v1 - 核心 API 组 │
│ ├── /namespaces/ │
│ ├── /pods/ │
│ ├── /services/ │
│ ├── /configmaps/ │
│ └── ... │
│ │
│ /apis/apps/v1 - 应用 API 组 │
│ ├── /deployments/ │
│ ├── /replicasets/ │
│ ├── /statefulsets/ │
│ └── /daemonsets/ │
│ │
│ /apis/batch/v1 - 批处理 API 组 │
│ ├── /jobs/ │
│ └── /cronjobs/ │
│ │
│ /apis/networking.k8s.io/v1 - 网络 API 组 │
│ ├── /networkpolicies/ │
│ └── /ingresses/ │
│ │
│ /apis/autoscaling/v2 - 弹性伸缩 API 组 │
│ └── /horizontalpodautoscalers/ │
│ │
└─────────────────────────────────────────────────────────────────────────┘

7.2 CRD 扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# CustomResourceDefinition 示例
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: webservers.example.com
spec:
group: example.com
names:
kind: WebServer
plural: webservers
scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
replicas:
type: integer
image:
type: string

8. 关键源码路径

功能 源码路径
API Server 入口 cmd/kube-apiserver/
请求处理 staging/src/k8s.io/apiserver/pkg/endpoints/
认证 staging/src/k8s.io/apiserver/pkg/authentication/
授权 staging/src/k8s.io/apiserver/pkg/authorization/
准入控制 staging/src/k8s.io/apiserver/pkg/admission/
存储 staging/src/k8s.io/apiserver/pkg/storage/
Watch Cache staging/src/k8s.io/apiserver/pkg/storage/cacher/

面试题

基础题

1. kube-apiserver 的主要职责是什么?

kube-apiserver 是 Kubernetes 的核心 API 网关:

  • 提供 RESTful API 供所有组件访问
  • 处理认证、授权、准入控制
  • 验证资源对象的合法性
  • 将数据持久化到 etcd
  • 提供 Watch 机制支持控制器响应变化

2. 什么是 Kubernetes 的认证、授权、准入控制?

  • **认证 (Authentication)**:验证请求者身份,如 x509 证书、Bearer Token、ServiceAccount
  • **授权 (Authorization)**:判断已认证用户是否有权限执行操作,如 RBAC、Node、Webhook
  • **准入控制 (Admission Control)**:在对象持久化前进行变更或验证,如资源限制、默认值、环境变量注入

3. kube-apiserver 如何保证高可用?

  • 部署多个 kube-apiserver 实例
  • 使用负载均衡器(如 kube-vip)分发请求
  • 所有实例连接同一个 etcd 集群
  • 客户端使用 --apiserver-count 配置重试

4. 什么是 ResourceVersion?

ResourceVersion 是 Kubernetes 的乐观锁机制:

  • 每次资源更新时递增
  • 用于检测并发修改冲突
  • Watch 操作的基准版本
  • 支持指定版本读取历史数据

5. kube-apiserver 支持哪些认证方式?

  • x509 客户端证书
  • Bearer Token(ServiceAccount)
  • Bootstrap Token(新节点加入)
  • OIDC(外部身份提供商)
  • Webhook(第三方认证服务)

中级题

6. 描述一下请求经过 kube-apiserver 的完整流程

  1. 请求到达过滤器链(认证)
  2. 请求到达过滤器链(授权)
  3. 路由匹配找到对应 Handler
  4. Mutating 准入控制器修改对象
  5. 对象验证
  6. Validating 准入控制器验证
  7. 写入 etcd
  8. 返回响应

7. 什么是 Mutating 和 Validating 准入控制器?

  • Mutating:可以修改请求对象,如设置默认值、注入 sidecar
  • Validating:只验证对象,不做修改,如检查配额、资源限制

Mutating 在 Validating 之前执行,因为修改后的对象需要再次验证。

8. kube-apiserver 如何实现 Watch?

  1. 客户端发起 Watch 请求
  2. API Server 从 watchCache 获取初始数据
  3. 同时监听 etcd 的变更
  4. 有变更时推送事件给客户端
  5. 客户端持续接收增量更新

9. 什么是 CRD?CRD 和内置资源有什么区别?

CRD(CustomResourceDefinition)用于扩展 Kubernetes API:

  • 内置资源:apiserver 原生支持,如 Pod、Service
  • CRD:用户自定义资源,由 API Server 动态注册

CRD 通过 CustomResourceDefinition 对象定义,不需要修改 apiserver 代码。

10. kube-apiserver 如何处理并发请求?

  • 使用乐观锁(ResourceVersion)
  • Watch 请求通过 watchCache 缓存
  • 穿透请求直接访问 etcd
  • 限流防止过载

高级题

11. 分析 kube-apiserver 的存储层实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// API Server 存储层架构
// staging/src/k8s.io/apiserver/pkg/storage/

type Storage interface {
Get(ctx, key, options, out) error
List(ctx, key, options, list) error
Create(ctx, key, obj, out, ttl) error
Update(ctx, key, obj, out, ttl) error
Delete(ctx, key, out, preconditions) error
Watch(ctx, key, options) (watch.Interface, error)
}

// 层级结构
// Cacher -> StorageDecorator -> etcd3 -> etcd

// Cacher 提供:
// 1. watchCache 缓存
// 2. 读写分离
// 3. Watch 事件分发

12. kube-apiserver 如何实现限流?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 请求限流机制
type RateLimiter struct {
queues map[string]*workqueue.RateLimiter
sync.Once
}

func (r *RateLimiter) HandleError(req *Request, flowSchema string, estimatedDeduction time.Duration) {
// 1. 获取对应的限流器
limiter := r.getFlowSchemaLimiter(flowSchema)

// 2. 请求入队
if !limiter.TryAdd(req) {
// 3. 限流拒绝
http.Error(w, "Too Many Requests", 429)
}
}

// 优先级和公平调度
// - flowSchema 将请求分类
// - priorityLevel 配置不同限流级别
// - 紧急请求优先处理

13. 解释 kube-apiserver 的 API 聚合机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// API 聚合层允许扩展 API Server
// staging/src/k8s.io/apiserver/pkg/apis/apiserver/

type AggregatedDiscovery struct {
ServerGroups []*APIGroupDiscovery
}

func (a *APIAggregator) AddAPIService(apiService *APIService) error {
// 1. 注册到 API 代理
a.proxyRegistry.AddAPIService(apiService)

// 2. 设置路由
a.addRegistrationHandler(apiService)

// 3. 更新 discovery 信息
return a.discoveryRegistry.UpdateAPIGroupMetadata(apiService)
}

// 请求转发
// /apis/apiregistration.k8s.io/v1/apiservices/xxx
// -> 代理到扩展 apiserver

场景题

14. 如何排查 kube-apiserver 认证失败的问题?

  1. 检查客户端证书:openssl x509 -in client.crt -text
  2. 检查 ServiceAccount Token:kubectl get secret
  3. 查看审计日志:检查认证失败事件
  4. 检查 Webhook 配置:验证 admission webhook
  5. 检查 RBAC 权限:kubectl auth can-i

15. 如何实现自定义准入控制器?

1
2
3
4
5
6
7
8
9
10
11
12
13
// 1. 实现 admission interface
type myWebhook struct{}

func (m *myWebhook) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
// 验证逻辑
return nil
}

// 2. 注册 admission webhook
// admissionregistration.k8s.io/v1/ValidatingWebhookConfiguration

// 3. 配置 webhook 服务器
// 使用 kube-apiserver 的 webhook 认证

16. 如何优化 kube-apiserver 的性能?

  1. 参数调优

    • --max-requests-inflight:限制并发请求数
    • --max-mutating-requests-inflight:限制变更请求数
    • --target-ram-mb:内存限制
  2. 组件优化

    • etcd 使用 SSD
    • 启用 watchCache
    • 配置合适的 –watch-cache-sizes
  3. 网络优化

    • kube-apiserver 与 etcd 同机房
    • 使用高性能负载均衡器
  4. 客户端优化

    • 使用 SharedInformers 减少请求
    • 合理使用 Watch 而非轮询
    • 配置合适的 QPS 限制