kubernetes_API_server
深入理解 Kubernetes API Server:访问控制、限流与对象实现
kube-apiserver 是 Kubernetes 集群的”大脑”,负责处理所有请求,是集群管理的核心组件。本文将深入探讨 kube-apiserver 的访问控制机制(认证、鉴权、准入控制)、限流策略以及 APIServer 对象的实现原理。
1. API Server 的核心功能
kube-apiserver 主要提供以下功能:
- 集群管理的 REST API 接口:提供认证授权、数据校验、集群状态变更等功能。
- 模块间数据交互枢纽:其他模块通过 API Server 查询或修改数据,只有 API Server 才直接操作 etcd。

2. 访问控制

客户端(例如 kubectl
、自定义控制器或其他 K8s 组件)发出的 API 请求首先到达 kube-apiserver
。这些请求经过一系列处理步骤,最终被处理并存储到 etcd
中(或从 etcd
中检索)。

Panic Recovery: 捕获并处理任何 panic,防止整个 apiserver 崩溃。
Request Timeout: 设置请求的超时时间,防止请求无限期挂起。
Authentication: 验证请求者的身份。K8s 支持多种认证机制,如 X.509 证书、Service Account Tokens、Bearer Tokens 等。
Audit: 记录请求的审计日志,用于安全审计和故障排除。
Impersonation: 允许一个用户或服务账户以另一个用户或服务账户的身份执行操作。
Max-in-flight: 限制并发处理的请求数量,防止服务器过载。
Authorization: 确定经过身份验证的用户是否有权限执行请求的操作。K8s 支持多种授权机制,如 RBAC (Role-Based Access Control)、ABAC (Attribute-Based Access Control) 等。

2.1 认证(Authentication)
在 Kubernetes 中,认证是指对请求的发送者(用户或服务)进行身份识别,以确保只有合法的实体可以访问 Kubernetes API Server。以下是 Kubernetes 支持的多种认证机制的详细说明:
1. X.509 证书
概念:
X.509 是一种基于公钥基础设施 (PKI) 的证书标准,通常用于安全通信。Kubernetes 支持通过客户端证书进行身份验证。
工作原理:
- 用户使用私钥和证书向 API Server 发起 HTTPS 请求。
- API Server 使用信任的 CA 证书对客户端证书进行验证。
- 若验证通过,则认证成功。
配置方式:
生成 CA 和用户证书:
1
2
3
4
5
6
7
8
9
10# 生成 CA 私钥和证书
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=kube-ca" -days 10000 -out ca.crt
# 生成用户私钥和 CSR
openssl genrsa -out user.key 2048
openssl req -new -key user.key -subj "/CN=my-user/O=my-group" -out user.csr
# 使用 CA 签发用户证书
openssl x509 -req -in user.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out user.crt -days 10000 -extensions v3_ext配置 API Server:
1
kube-apiserver --client-ca-file=/path/to/ca.crt
注意事项:
- 用户名(CN)由证书中的
Common Name
字段指定。 - 组(Group)由证书中的
Organization
字段指定。
2. 静态 Token 文件
概念:
静态 Token 是预定义的令牌,用于认证用户。它适合小型测试集群,但不推荐生产环境中使用。
工作原理:
- 用户请求中携带
Authorization: Bearer <token>
。 - API Server 从配置的 Token 文件中查找匹配的 Token。
- 若匹配成功,则认证通过。
配置方式:
创建 Token 文件(CSV 格式):
1
token1234,my-user,uid1234,"group1,group2"
配置 API Server:
1
kube-apiserver --token-auth-file=/path/to/tokens.csv
优缺点:
- 优点:简单易用,易于共享。
- 缺点:缺乏安全性(Token 没有过期机制)。
3. 引导 Token (Bootstrap Token)
概念:
引导 Token 是一种动态令牌,主要用于集群引导阶段(例如 kubeadm join
)。Token 生命周期由 kube-controller-manager
管理。
工作原理:
- Token 以 Kubernetes Secret 的形式存储于
kube-system
命名空间。 - 当客户端请求使用 Token 时,API Server 查询对应的 Secret 以验证其合法性。
TokenCleaner
控制器会自动清理过期的 Token。
常见命令:
查看引导 Token:
1
kubeadm token list
创建引导 Token:
1
kubeadm token create
优缺点:
- 优点:动态管理,支持自动过期。
- 缺点:只适合用于集群引导。
4. 静态密码文件
概念:
通过用户名和密码进行认证。这种方式简单但不安全,因此不推荐在生产环境中使用。
配置方式:
创建密码文件(CSV 格式):
1
password1234,my-user,uid1234,"group1,group2"
配置 API Server:
1
kube-apiserver --basic-auth-file=/path/to/passwords.csv
缺点:
- 用户名和密码以明文方式存储。
- 缺乏强制密码保护机制。
5. Service Account Token
概念:
Service Account 是 Kubernetes 原生的认证机制,主要为 Pod 提供身份认证。
工作原理:
- 每个 Pod 都可以绑定一个 Service Account。
- 默认情况下,Service Account 的 Token 会自动挂载到 Pod 的文件系统路径
/run/secrets/kubernetes.io/serviceaccount
。 - Pod 使用 Token 与 API Server 通信。
优点:
- 安全性高,自动管理。
- 适合 Pod 内部访问 API Server。
6. OpenID Connect (OIDC)
概念:
OIDC 是基于 OAuth 2.0 的身份认证协议,用于对接外部身份认证服务(例如 Google, Keycloak)。
工作原理:
- 用户向 OIDC 提供商请求 Token。
- 用户携带 Token 向 API Server 发起请求。
- API Server 验证 Token 的签名及有效性。
- 验证成功后,返回认证成功。
配置方式:
- 配置 API Server:
1
2
3
4
5kube-apiserver \
--oidc-issuer-url=https://issuer.example.com \
--oidc-client-id=kubernetes \
--oidc-username-claim=email \
--oidc-groups-claim=groups
优点:
- 集成第三方身份认证系统。
- 支持复杂身份和组管理。
7. Webhook Token 认证
概念:
通过 Webhook 调用外部服务来验证 Token 的合法性。
工作原理:
- 用户携带 Token 向 API Server 发起请求。
- API Server 将 Token 转发到配置的 Webhook 服务。
- Webhook 服务返回认证结果。
- API Server 根据认证结果决定是否通过。
配置方式:
配置 Webhook:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# webhook-config.yaml
apiVersion: v1
kind: Config
clusters:
- name: example
cluster:
server: https://auth.example.com/authenticate
users:
- name: example
contexts:
- context:
cluster: example
user: example
name: example-context
current-context: example-context启用 Webhook:
1
kube-apiserver --authentication-token-webhook-config-file=/path/to/webhook-config.yaml
优点:
- 灵活性高,可以集成复杂的认证逻辑。
8. 匿名请求
概念:
当未提供身份凭据时,API Server 将请求识别为匿名请求。匿名请求默认启用,但可以禁用。
配置方式:
- 禁用匿名请求:
1
kube-apiserver --anonymous-auth=false
优缺点:
- 优点:允许调试和测试。
- 缺点:不适合生产环境,可能引发安全问题。

2.1.1 基于 Webhook 的认证服务集成
可以构建符合 Kubernetes 规范的自定义认证服务。以下是构建认证服务的要点:
- 规范:
- URL:
https://authn.example.com/authenticate
- Method:
POST
- Input:
1
2
3
4
5{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"spec": { "token": "(BEARERTOKEN)" }
} - Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"status": {
"authenticated": true,
"user": {
"username": "janedoe@example.com",
"uid": "42",
"groups": [
"developers",
"qa"
]
}
}
}
- URL:
以下为go代码示例
1 |
|
2.1.2 keystone认证的陷阱
Keystone 是很多企业的核心认证服务。Kubernetes 中使用 Keystone 作为认证插件可能会导致 Keystone 故障且无法恢复。
原因:gophercloud 针对过期 token 会一直 retry,导致服务无法恢复
解决方案:
- 熔断
- 限流
2.2 授权
授权阶段负责确定已认证的用户是否有权限执行请求的操作。Kubernetes 支持以下授权模式:
- ABAC (Attribute-Based Access Control):基于属性的访问控制,配置复杂,不推荐。
- RBAC (Role-Based Access Control):基于角色的访问控制,推荐使用。
- Webhook:将授权决策委托给外部 Webhook 服务。
- Node:一种特殊用途的授权模式,用于授予 kubelet 访问特定资源的权限。
2.2.1 RBAC
RBAC 的核心概念:
- Role(角色):定义了一组权限规则。
- ClusterRole(集群角色):与 Role 类似,但作用于整个集群。
- RoleBinding(角色绑定):将 Role 或 ClusterRole 与用户、组或 ServiceAccount 绑定。
- ClusterRoleBinding(集群角色绑定):将 ClusterRole 与用户、组或 ServiceAccount 绑定。

- 针对群组授权
1 |
|
2.2.2 规划系统角色
在规划 Kubernetes 集群的权限时,需要考虑以下角色:
- 管理员:拥有集群的最高权限。
- 普通用户:拥有其创建的命名空间内资源的操作权限,对其他命名空间可能有只读权限。
- SystemAccount:用于 Kubernetes 组件或自定义应用与 API Server 通信。
2.2.3 实现自定义授权逻辑的方案
- 在集群创建时,创建自定义的 Role,例如
namespace-creator
,定义用户可操作的对象和读写权限。 - 创建自定义的 Namespace 准入控制器,在 Namespace 创建请求被处理时,获取当前用户信息并将其添加到 Namespace 的 Annotation 中。
- 创建 RBAC 控制器,监视 Namespace 的创建事件,获取 Namespace 创建者信息,并在当前 Namespace 中创建 RoleBinding 对象,将
namespace-creator
角色与用户绑定。
2.2.4 权限相关的最佳实践
- ClusterRole 是非命名空间绑定的,针对整个集群生效。
- 通常需要创建一个管理员角色,并且绑定给开发运营团队成员。
- ThirdPartyResource 和 CustomResourceDefinition 是全局资源,普通用户创建
ThirdPartyResource 以后,需要管理员授予相应权限后才能真正操作该对象。 - 针对所有的角色管理,建议创建 spec,用源代码驱动。
- 权限是可以传递的,用户 A 可以将其对某对象的某操作,抽取成一个权限,并赋给用户 B。
- 防止海量的角色和角色绑定对象,因为大量的对象会导致鉴权效率低,同时给 apiserver 增加负担。
- ServiceAccount 也需要授权的。
- Tips:SSH 到 master 节点通过 insecure port 访问 apiserver 可绕过鉴权,当需要做管理操作又没有权限时可以使用(不推荐)
授权相关的坑:
研发人员忘记在生产环境更新 rolebinding 导致权限不足
2.3 准入控制
准入控制在授权之后对请求进行进一步的验证或修改。与认证和授权不同,准入控制可以处理请求的内容,并且仅对创建、更新、删除或连接(如代理)等操作有效。
Kubernetes 内置了许多准入控制插件,例如:
- AlwaysPullImages:强制拉取最新镜像。
- DenyEscalatingExec:禁止特权容器的 exec 和 attach 操作。
- ServiceAccount:自动创建默认 ServiceAccount。
- ResourceQuota:限制 Pod 的资源请求。
- LimitRanger:为 Pod 设置默认资源请求和限制。
- NamespaceLifecycle:确保处于 termination 状态的命名空间不再接收新的对象创建请求。
- PodSecurityPolicy:实施 Pod 安全策略。
- NodeRestriction:限制 kubelet 仅可访问 node、endpoint、pod、service 以及 secret、
configmap、PV 和 PVC 等相关的资源
2.3.1 准入控制插件的开发
除了默认的准入控制插件,Kubernetes 还支持自定义准入控制插件:
- MutatingWebhookConfiguration:修改准入对象。
- ValidatingWebhookConfiguration:校验准入对象,但不修改。
准入控制例子:
1 |
|
2.3.2 配额管理
原因:
资源有限,如何限定某个用户有多少资源?
方案:
- 预定义每个Namespace的ResourceQuota,并把spec保存为configmap
- 创建ResourceQuota Controller
- apiserver中开启ResourceQuota的admission plugin
3. 限流
限流是保护 API Server 免受过多请求影响的重要机制。
3.1 传统限流算法
- 计数器固定窗口算法:在固定时间窗口内对请求计数,超过阈值则拒绝。
- 计数器滑动窗口算法:将固定窗口划分为多个小窗口,分别计数,窗口滑动时更新计数。
- 漏斗算法:请求进入漏斗,以恒定速率流出,漏斗满时溢出。
- 令牌桶算法:以恒定速率向令牌桶中放入令牌,请求消耗令牌,桶空时拒绝。
3.2 APIServer 中的限流
kube-apiserver 通过以下参数进行限流:
--max-requests-inflight
:最大非 mutating 请求数。--max-mutating-requests-inflight
:最大 mutating 请求数。- 代码:
staging/src/k8s.io/apiserver/pkg/server/filters/maxinflight.go:WithMaxInFlightLimit()
默认值:
节点数 | max-requests-inflight | max-mutating-requests-inflight |
---|---|---|
1000-3000 | 400/1500 | 200/500 |
>3000 | 3000 | 1000 |
3.3 传统限流方法的局限性
- 粒度粗:无法针对不同用户、场景进行精细化限流。
- 单队列:所有请求共享限流资源,可能导致单个用户的行为影响整个系统。
- 不公平:正常用户的请求可能被排在队尾,无法及时处理。
- 无优先级:重要请求可能被限流,导致系统故障难以恢复。
3.4 API Priority and Fairness (APF)
APF 是 Kubernetes 1.18 引入的新特性,提供更细粒度的请求分类和隔离,以及有限的排队机制,避免短暂突发流量导致请求被拒绝。
3.4.1 APF 的核心概念
- 多等级 (Priority Level):不同优先级的请求拥有独立的并发资源。
- 多队列 (Multiple Queues):每个优先级内部使用多个队列,通过公平排队算法避免单个 Flow 饿死其他 Flow。

3.4.2 关键概念
- FlowSchema:将请求分类到不同的 Flow。
- PriorityLevelConfiguration:定义每个优先级的并发限制和排队参数。
- Distinguisher:在 FlowSchema 内部进一步区分请求(例如,按用户或命名空间)。
- Shuffle Sharding:将请求分配到队列的算法,隔离低强度和高强度流量。
- Fair Queuing:从队列中选择请求的算法,确保同一优先级内不同 Flow 的公平性。
3.4.3 豁免请求
某些特别重要的请求(例如,system:masters
组的请求)不受 APF 限制。
3.4.4 默认配置
Kubernetes 提供了以下默认配置:
system
:用于system:nodes
组的请求。leader-election
:用于内置控制器的领导者选举请求。workload-high
:用于内置控制器的请求。workload-low
:用于来自任何服务帐户的请求。global-default
:处理所有其他流量。exempt
:完全不受流控限制。catch-all
:确保每个请求都被分类。
3.4.5 PriorityLevelConfiguration
1 |
|
3.4.6 FlowSchema
1 |
|
3.4.7 调试
可以使用以下命令调试 APF:
/debug/api_priority_and_fairness/dump_priority_levels
/debug/api_priority_and_fairness/dump_queues
/debug/api_priority_and_fairness/dump_requests
4. 高可用 APIServer
4.1 启动 apiserver 示例
1 |
|
4.2 构建高可用的多副本 apiserver
apiserver是无状态的Rest Server,无状态所以方便Scale Up/down,在多个apiserver实例之上,配置负载均衡,证书可能需要加上Loadbalancer VIP重新生成
4.3 其他最佳实践
- 预留充足的 CPU、内存资源。
- 善用速率限制(RateLimit)。
- 设置合适的缓存大小。
- 客户端尽量使用长连接。
- 访问 APIServer:
- 外部客户:通过 LoadBalancer 访问。
- 内部客户端:优先访问 Cluster IP。
5. 搭建多租户的 Kubernetes 集群
5.1 目标
- 授信:认证和授权,确保只有可信用户才能访问集群,并防止用户越权操作。
- 隔离:可见性隔离、资源隔离、应用访问隔离,确保不同租户之间的隔离性。
- 资源管理:Quota 管理,控制每个租户的资源使用量。
5.2 实现
- 认证:与企业现有认证系统集成(例如,使用 Webhook 认证插件与 Microsoft Active Directory 集成)。
- 授权:使用 RBAC 进行细粒度的权限控制。
- 可见性隔离:通过命名空间对不同租户可见的资源进行隔离
- 资源隔离:通过专有设备给特定租户使用
- 应用访问隔离: 通过设置,只允许特定租户访问某些应用
- Quota 管理:通过 ResourceQuota 控制每个命名空间的资源使用。
6. APIServer 对象的实现
6.1 GKV (Group, Kind, Version)
- Group:API 资源的分组。
- Kind:API 资源的类型。
- Version:API 资源的版本(Internal version 和 External version)。

6.2 定义 Group
1 |
|
6.3 定义对象类型
1 |
|
6.4 代码生成 Tags
- Global Tags:定义在
doc.go
中,例如// +k8s:deepcopy-gen=package
。 - Local Tags:定义在
types.go
中的每个对象里,例如// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
。
6.5 实现 etcd storage
1 |
|
6.6 创建和更新对象时的业务逻辑-Strategy
1 |
|
6.7 subresource
内嵌在kubernetes对象中,有独立的操作逻辑的属性集合,如podstatus
1 |
|
6.8 注册 APIGroup
- 定义 Storage:
configMapStorage := configmapstore.NewREST(restOptionsGetter)
。 - 定义对象的 StorageMap:
apiGroupInfo.VersionedResourcesStorageMap["v1"] = restStorageMap
。 - 将对象注册至 APIServer(挂载 handler):
1 |
|
6.9 代码生成
Kubernetes 使用以下代码生成器:
deepcopy-gen
:为对象生成 DeepCopy 方法。client-gen
:创建 Clientset。informer-gen
:创建 Informer 框架。lister-gen
:创建 Lister 框架。conversion-gen
:创建版本转换方法。
代码生成器位于:https://github.com/kubernetes/code-generator
hack/update-codegen.sh
脚本用于生成代码。
命令示例:
1 |
|
总结
本文深入探讨了 Kubernetes API Server 的内部机制,包括访问控制、限流策略和 APIServer 对象的实现。理解这些概念对于构建和管理 Kubernetes 集群至关重要。希望这篇博客能帮助你更好地理解 Kubernetes API Server 的工作原理。
apiserver 代码走读可以参考:https://cncamp.notion.site/kube-apiserver-10d5695cbbb14387b60c6d622005583d