本文详细介绍了 Kubernetes 的核心安全机制,内容涵盖 API Server 的安全访问控制流程,包括认证(Authentication)、鉴权(Authorization)和准入控制(Admission Control)。重点阐述了证书认证、ServiceAccount、RBAC 模型及其核心资源对象(Role, ClusterRole, RoleBinding, ClusterRoleBinding)的工作原理和使用方法。
K8S 安全机制概述
Kubernetes
作为一个分布式集群管理工具,保证集群的安全性是其一个重要的任务。
API Server 是集群内部各个组件通信的中介,也是外部控制的入口。
所以 Kubernetes 的安全机制基本就是围绕保护 API Server 来设计的。
一个完整的请求需要经过三个阶段:
- 认证(Authentication):确认请求者的身份是谁
- 鉴权(Authorization):判断该身份是否有权限执行请求的操作
- 准入控制(Admission Control):对行为进行校验或修改,判断是否合理
即使一个管理员有最大的操作权限,可以删除集群中任意资源;
但其执行
rm -rf /*
这个行为是不合理的。
1. 认证 (Authentication)
认证阶段的目标是识别出请求的来源是 “谁”。Kubernetes 支持多种认证方式。
认证模式
- HTTPS 证书认证
最常用也是最严格的认证方式。基于 CA 根证书为客户端签发证书,实现双向 TLS 认证。- 客户端证书的
CN
字段用于指定用户名
O
字段用于指定用户组
- 客户端证书的
HTTP Token 认证
通过一个预定义的 Token 来识别用户。Token 与用户名映射关系存储在文件中。HTTP Base 认证
使用用户名:密码
的方式进行认证,安全性较低,不推荐在生产环境使用。ServiceAccount Token 认证
专门用于 Pod 内进程访问 API Server 的认证方式。
需要认证的客户端
Kubernetes 组件
包括kubectl
、kube-proxy
、kubelet
、Controller Manager
、Scheduler
等,都需要访问 API Server,通常使用证书进行认证。Pod
Pod 内的应用程序如果需要访问 API Server,则使用 ServiceAccount 进行认证。
kubeconfig 文件
kubeconfig
文件用于存储集群的访问凭证。它包含:
- 集群信息(API Server 地址、CA 证书)
- 用户信息(客户端证书和私钥或 Token)
- 上下文(将用户和集群关联起来)
kubectl
等工具通过读取该文件来确定访问哪个集群以及使用哪个身份。
ServiceAccount
由于 Pod 是动态创建和销毁的,为其手动管理证书不可行。Kubernetes 引入了 ServiceAccount 资源来解决这个问题。
创建与关联:
每个命名空间都有一个默认的 ServiceAccount。创建 Pod 时,如果没有指定,会自动关联。Token 挂载:
ServiceAccount 会关联一个 Secret(类型为service-account-token
),其中包含一个 JWT Token。该 Secret 会自动挂载到 Pod 的/run/secrets/kubernetes.io/serviceaccount/
目录下。Pod 内访问:
Pod 内程序读取挂载的 Token,在访问 API Server 时加入到 HTTP 请求头中,从而完成身份认证。
2. 鉴权 (Authorization)
认证通过后,API Server 需要判断请求者是否有权限执行相应的操作,这个过程就是 鉴权。
鉴权策略
API Server 支持多种鉴权策略,通过 --authorization-mode
参数配置:
- AlwaysDeny:拒绝所有请求(用于测试)
- AlwaysAllow:允许所有请求(跳过鉴权)
- ABAC (Attribute-Based Access
Control):基于属性的访问控制,依赖复杂策略文件,管理不便
- RBAC (Role-Based Access
Control):基于角色的访问控制(默认且推荐)
- Webhook:将鉴权决策委托给外部 REST 服务
RBAC (基于角色的访问控制)
RBAC 的核心思想:将权限(可以对哪些资源做什么操作)定义到 角色(Role) 中,再将角色绑定到 主体(Subject) 上。主体可以是 用户(User)、用户组(Group) 或 服务账户(ServiceAccount)。
即引入主体和具体权限的一个中间层:角色。
角色可以复用,对于任意一个主体,想要什么权限,就将其绑定到特定角色上
四个核心资源对象
Role 和 ClusterRole
- Role
- 作用于特定命名空间
- 授予命名空间内的资源权限
- 作用于特定命名空间
- ClusterRole
- 作用于整个集群
- 可授予对 集群级别资源、非资源型 API、所有命名空间资源 的访问权限
- 作用于整个集群
示例:Role
1 | kind: Role |
RoleBinding 和 ClusterRoleBinding
- RoleBinding
- 将一个 Role 或 ClusterRole 的权限授予特定命名空间内的主体
- 如果绑定的是 ClusterRole,权限仅限于当前命名空间
- ClusterRoleBinding
- 将 ClusterRole 的权限授予所有命名空间的主体
- 实现集群级别的授权
主体通过 rolebinding 绑定到 role 时需要指定namespace,因为role只作用于特定命名空间
主体通过 ClusterRoleBinding 绑定到 ClusterRole 时需要不需要指定namespace,因为ClusterRoles管理整个集群,包括了所有命名空间
主体通过 rolebinding 绑定到 ClusterRole 时也需要指定namespace:
意义:将全局角色的权限限定在某个命名空间内生效。
机制:虽然 ClusterRole 可管理全局资源,但通过 RoleBinding 绑定后,只对指定命名空间的资源有效。
应用场景:
- 复用通用权限模板(如内置的
view/edit/admin
)。- 按命名空间隔离不同团队的权限。
- 实现最小权限原则,避免过度授权。
示例:RoleBinding
1 | kind: RoleBinding |
示例:ClusterRoleBinding
1 | kind: ClusterRoleBinding |
3. 准入控制 (Admission Control)
准入控制是 API Server 安全链的最后一环。 它在 请求通过认证和鉴权之后,但 对象写入 etcd 之前 拦截请求,并可能修改或拒绝。
准入控制器插件
API Server 启动时通过 --enable-admission-plugins
参数启用。常见插件包括:
NamespaceLifecycle 防止在不存在的命名空间中创建对象;保护
default
、kube-system
等命名空间;删除命名空间时清理其资源。LimitRanger 确保 Pod 的资源请求和限制不超过其所在命名空间的
LimitRange
。ServiceAccount 自动化 ServiceAccount 管理。例如:若 Pod 未指定 ServiceAccount,则自动设置为
default
。ResourceQuota 确保请求的资源不会超过命名空间的
ResourceQuota
。 (如:限制命名空间中 Pod 的总数或 CPU/内存总量)MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 允许管理员集成自定义逻辑:
- Mutating:可修改请求对象
- Validating:仅进行校验