一、安全机制说明
在k8s集群中,API Server是集群内部各个通信组件的中介,是外部控制的入口,所以k8s的安全机制主要是针对保护API Server来设置。
二、认证
1、常见认证方式
Kubernetes 集群的客户端认证方式主要分为以下几种:
1. 客户端证书认证(X.509 Client Certificates)
-
原理:通过为客户端签发 X.509 证书,并在请求时携带该证书,API Server 使用预先配置的 CA 证书进行验证。
-
配置方式 :证书和私钥配置在 kubeconfig 文件中,API Server 启动时通过
--client-ca-file
指定 CA 证书。 -
特点:安全性高,支持双向 TLS 认证,常用于 kubectl 和集群组件间通信。
2. 静态 Token 认证(Static Token File)
-
原理 :API Server 启动时加载一个包含用户名、用户组、Token 等信息的静态文件(通过
--token-auth-file
指定)。 -
使用方式 :客户端在 HTTP Header 中加入
Authorization: Bearer <token>
进行认证。 -
特点:简单但不灵活,Token 长期有效,修改需重启 API Server。
3. Service Account Token 认证
-
原理:Kubernetes 自动为每个命名空间创建 ServiceAccount,并为其生成 JWT Token。
-
使用场景:Pod 内进程访问 API Server 时使用,Token 自动挂载到 Pod 中。
-
特点:适用于集群内部服务认证,Token 由 API Server 签发并验证。
4. Bootstrap Token 认证
-
原理:用于节点加入集群时的认证,Token 通过 Secret 存储在 kube-system 命名空间中。
-
使用场景:集群扩容或新节点加入时使用。
5. OpenID Connect(OIDC)Token 认证
-
原理:基于 OAuth 2.0 和 OIDC 协议,通过外部身份提供商(如 Google、Azure AD)进行认证。
-
配置方式 :API Server 启动参数中配置
--oidc-issuer-url
、--oidc-client-id
等。 -
特点:适用于与外部身份系统集成,支持单点登录(SSO)。
6. Webhook Token 认证
-
原理:通过远程 Webhook 服务验证 Bearer Token,API Server 将 Token 转发给 Webhook 服务进行认证。
-
配置方式 :API Server 启动参数中配置
--authentication-token-webhook-config-file
指定 Webhook 服务的 kubeconfig 文件。 -
特点:可扩展性强,支持自定义认证逻辑和外部身份系统(如 LDAP、SAML)。
7. 身份认证代理(Authenticating Proxy)
-
原理:通过反向代理(如 Nginx、OAuth2 Proxy)在请求头中注入用户身份信息,API Server 信任代理并提取用户信息。
-
配置方式 :API Server 通过
--requestheader-username-headers
等参数配置信任的头信息。 -
特点:适用于统一认证网关场景,减少客户端配置复杂度。
8. HTTP Basic 认证
-
原理:通过用户名和密码进行认证,信息以 Base64 编码后放在 HTTP Header 中。
-
特点:简单但不安全,通常需配合 HTTPS 使用,生产环境较少使用。
9. 匿名认证
-
原理:允许未经认证的请求访问集群资源,默认关闭。
-
配置方式 :通过 API Server 启动参数
--anonymous-auth=true
开启。 -
特点:存在安全风险,生产环境建议关闭。
10. client-go 凭据插件(Exec Credential Plugins)
-
原理:通过外部命令动态获取认证凭据(如 Token 或证书),支持自定义认证协议(如 LDAP、Kerberos)。
-
配置方式 :在 kubeconfig 文件中配置
exec
字段,指定外部命令及其参数。 -
特点:灵活性高,支持与外部身份系统集成。
认证方式 | 安全性 | 适用场景 | 配置复杂度 | 备注 |
---|---|---|---|---|
客户端证书 | 高 | kubectl、组件通信 | 中 | 默认推荐方式 |
静态 Token | 中 | 简单场景 | 低 | Token 长期有效 |
Service Account | 中 | Pod 内服务认证 | 低 | 自动挂载 |
Bootstrap Token | 中 | 节点加入集群 | 低 | 临时 Token |
OIDC Token | 高 | 外部身份系统集成 | 高 | 支持 SSO |
Webhook Token | 高 | 自定义认证逻辑 | 高 | 可扩展性强 |
身份认证代理 | 高 | 统一认证网关 | 中 | 需配置代理信任 |
HTTP Basic | 低 | 测试环境 | 低 | 不安全,需 HTTPS |
匿名认证 | 低 | 公开访问 | 低 | 建议关闭 |
client-go 插件 | 高 | 复杂外部系统集成 | 高 | 支持动态认证 |
2、部分认证方式讲解
由于k8s中支持的认证方式较多,我选择其中三个较常用的认证方式进行讲解
2.1HTTPS证书认证(客户端证书)
精简总结:HTTPS证书认证就是在客户端和服务端均信任的 CA 架构下,实现 TLS 双向握手进行身份认证和授权的方式。
客户端和服务器端向二者均信任的 CA 架构进行证书请求,CA 架构下发证书后,二者实现 TLS 双向握手(客户端发起 HTTPS → 服务端返回自己的证书 → 客户端验证服务端证书 →服务端要求客户端证书 → 客户端发送自己的证书 → 服务端用公钥对客户端证书做链式验证 → 握手完成,建立加密通道),由由 API Server 验证,并把证书的 CN/O 映射到 RBAC 身份即可。
①、HTTPS 认证方式(补充)
Ⅰ、HTTPS 单向认证
客户端认证服务端,如访问百度等等的网页。
首先客户端向服务端发送请求(包含客户端支持的https版本),服务器选择二者均支持的https版本并向客户端发送公钥/证书,然后客户端拿着自己的 CA 架构对服务端发来的公钥进行安全认证,如果公钥不可信会提醒客户端该网页的证书不可信,可能存在什么虚假信息等等,如果可信则客户端向服务器端发送自己的对称加密的算法,接着服务器端从中选择合适的算法返还给客户端,至此客户端和服务器端就形成了自己的加密算法,客户端在收到后会创建随机字符串作为加密密钥,再对此经过加密,向服务器端发送公钥,服务器端拿到后对此进行解密,得到对称加密的密钥

Ⅱ、HTTPS 双向认证(mTLS)
客户端和服务端互相认证,如ATM取钱。
https的双向认证和单向认证差不多,只不过是多了服务端认证客户端,确保是正确可执行的用户。
k8s中的API Server就是使用的HTTPS 的双向认证。
2.2HTTP Token认证(静态 Token)
精简总结:HTTP Token 认证就是用一个通过特殊编码方式的且难以被模仿的字符串------ Token 来进行身份认证的方式。
Token 是一个很长很复杂的字符串,存储在 API Server 的可访问文件中,每当客户端发起 API 的调用请求时,要在 HTTP Header 中放入 Token,之后 API 会去寻找你的 Token是否在可访问文件中存在,如果存在且匹配则身份认证成功,不存在就拒绝调用请求。
2.3HTTP Basic 认证
精简总结:HTTP Basic 认证就是通过用户名和密码进行认证的方式。
将用户名和密码信息以 Base64 编码后生成的字符串放在 HTTP Header 中,将其发给服务端,服务端再次进行编码得到你的用户名和密码,如果正确且相互匹配则身份认证成功,否则失败,拒绝请求。
3、必须认证+mTLS的组件/角色
3.1需认证不需mTLS
其余 常驻 Master 节点且与 API Server 同机 的组件,默认走本地非安全端口 127.0.0.1:8080,不强制 双向 TLS,但生产环境仍建议关掉 8080 端口,全部强制 mTLS。
3.2需认证需mTLS
在 Kubernetes 集群里,只要"客户端 ≠ API Server 本机" ,就必须走 HTTPS 6443 端口 + 双向 TLS(mTLS) ;换句话说,下面这些组件/角色 无一例外 都要做双向认证:
-
kubelet(每个节点)【自动颁发证书】
-
kube-proxy(每个节点)【手动颁发证书】
-
kubectl(任何一台管理机)【手动颁发证书】
-
以 Pod 形式运行、但 使用自己证书 的扩展控制器/Operator(如 Calico-kube-controllers、metrics-server 等)
-
外部调用方(CI/CD、Webhook、自定义 Controller)------只要它不在 Master 本机
精简总结:较安全环境可走非安全地址端口,非安全环境必须mTLS,生产环境强制mTLS。
组件/场景 | 必须 mTLS | 默认端口 | 备注 |
---|---|---|---|
kubelet → API Server | ✅ | 6443 | 自动轮换证书 |
kube-proxy → API Server | ✅ | 6443 | DaemonSet 挂载证书 |
kubectl → API Server | ✅ | 6443 | kubeconfig 证书或 token |
Controller/Scheduler → API Server | ✅ | 6443 | 1.20+ 已无 8080 |
Pod(ServiceAccount Token)→ API Server | ❌(只需单向 TLS) | 6443 | 非 mTLS,但强制 TLS |
自定义/外部 Controller → API Server | ✅ | 6443 | 客户端证书或 Token |
3.3补充SA
ServiceAccount 是 Kubernetes 用来给 "Pod 内进程" 提供 "集群内身份 + 调用 API Server 的凭据" 的原生对象。
主要包括:
-
ca.crt:集群根证书,用于Pod确定API Server的安全性
-
token:用于API Server确认Pod的安全性
-
namespace:标识Pod的作用域
bash
# 1. 创建
# 创建语句可直接 kubectl create sa <你的SA名称> -n <要放在的命名空间>
kubectl create serviceaccount api-bot -n dev
# 2. 赋权(RBAC),下方授权有讲
kubectl create role dev-reader --verb=get,list --resource=pods -n dev
kubectl create rolebinding dev-reader-binding \
--role=dev-reader --serviceaccount=dev:api-bot -n dev
# 3. 在 Pod 里引用
apiVersion: v1
kind: Pod
metadata:
name: job-pod
namespace: dev
spec:
serviceAccountName: api-bot # 关键字段
containers:
- image: bitnami/kubectl:latest
command: ["kubectl","get","pods"]
4、kubeconfig
4.1kubeconfig 是什么
-
作用:告诉 kubectl/任何 client-go 程序「连哪个集群、用什么身份、默认命名空间」。
-
本质:一个 YAML(默认 ~/.kube/config),可内嵌或引用证书、Token、Exec 插件。
4.2文件结构
以下给出一个大致yaml文件,如果想看自己的可以进入主节点(control plane)使用cat ~/.kube/config查看
bash
# 1. 集群列表
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBD... # 当前集群 CA 证书
server: https://10.0.0.10:6443 # 当前集群地址和端口
name: kind-my-multi-node-cluster1 # 由于我是用kind创建的集群,所以我的集群名字前带有kind
# 2. 用户列表(身份)
users:
- name: kind-my-multi-node-cluster1
user:
client-certificate-data: LS0tLS1CRUdJTiBD... # 用户证书
client-key-data: LS0tLS1CRUdJTiBSU0Eg... # 用户私钥
- name: bob-token
user:
token: eyJhbGciOiJSUzI1NiIsIm...
# 3. 上下文(把 cluster + user + 默认 ns 绑定)
contexts:
- context:
cluster: kind-my-multi-node-cluster1
user: kind-my-multi-node-cluster1
name: kind-my-multi-node-cluster1
current-context: kind-my-multi-node-cluster1
kind: Config
preferences: {}
# 4. 当前默认上下文
current-context: prod-alice
注意以上四大项顺序可能不同
当我们使用 kubectl 执行命令时,会去调用 ~/.kube/config的kubeconfig文件
三、授权
Kubernetes 提供了多种授权机制来控制用户和服务账户对集群资源的访问权限。
1、授权模式概述
Kubernetes 支持以下授权模式(可同时启用多个):
-
Node Authorization - 专门授权 kubelet
-
ABAC (Attribute-Based Access Control) - 基于属性的访问控制
-
RBAC (Role-Based Access Control) - 基于角色的访问控制(最常用)
-
Webhook - 外部授权服务集成
主流实现:RBAC(Role-Based Access Control) 。
2、RBAC(基于角色的访问控制)
2.1核心组件
RBAC提供了4个顶级资源对象:
-
Role :定义在特定命名空间 中的权限集合
-
ClusterRole :定义在集群 范围的权限集合
-
RoleBinding :将角色绑定到用户/组/服务账户(命名空间 内)
-
ClusterRoleBinding :将集群角色绑定到用户/组/服务账户(集群 范围)
以上四个均可通过kubectl与API进行操作
2.2配置文件举例
①、Role
bash
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default # 命名空间
name: pod-reader
rules:
- apiGroups: [""] # 空字符串表示核心API组
resources: ["pods"] # 操作的资源类型
verbs: ["get", "watch", "list"]
# 即将 "get", "watch", "list" 这些操作授予给一个 Role(命名空间级权限对象),名字叫 pod-reader,位于 default 命名空间。
Role刚创建出来其权限是0,不存在一开始就有很多权限,Role只可以定义在一个命名空间,如果要跨命名空间则要创建ClusterRole。rules中的权限可增加多个。
②、ClusterRole
bash
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# 和 Role 的区别在于没有命名空间
name: secret-reader
rules:
- apiGroups: [""] # 空字符串表示核心API组
resources: ["secrets"]
verbs: ["get", "watch", "list"]
# 即将 "get", "watch", "list" 这些操作授予给一个 ClusterRole(集群级权限对象),名字叫 secret-reader
③、RoleBinding
bash
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects: # 绑定对象
- kind: User # 授予身份1,绑定的是一个用户
name: jane # 身份1的名字(自定义)
apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount # 授予身份2,绑定的是一个SA
name: default # 身份2的名字(自定义)
namespace: kube-system
roleRef: # 要引用的角色(角色来源)
kind: Role # 引用的是命名空间级的 Role(而非 ClusterRole)
name: pod-reader # 引用的 Role 的名称叫 pod-reader
# 该对象必须与 RoleBinding 位于同一个命名空间
apiGroup: rbac.authorization.k8s.io # 指定 Role 所属的 API 组,固定值
# 即创建了一个 RoleBinding(命名空间级权限绑定),名字叫 read-pods,位于 default 命名空间。把 Role pod-reader 的权限授予两个身份 User 和 ServiceAccount
④、ClusterRoleBinding
bash
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects: # 绑定对象
- kind: Group # 绑定的是一个组
name: manager # 组的名称
apiGroup: rbac.authorization.k8s.io
roleRef: # 要引用的角色(角色来源)
kind: ClusterRole # 引用的是集群级的 ClusterRole(而非 Role)
name: secret-reader # 引用的 ClusterRole 的名称叫 secret-reader
apiGroup: rbac.authorization.k8s.io
# 即创建了一个 ClusterRoleBinding(集群级权限绑定),名字叫 read-secrets-global。把一个名称叫 secret-reader 的 ClusterRole 权限授予身份 Group
2.3配合绑定关系
①、Role+RoleBinding
即在当前命名空间内,将角色绑定,最终是命名空间级别
②、ClusterRole+ClusterRoleBinding
即在当前集群内,将集群角色绑定,最终是集群级别
③、ClusterRole+RoleBinding
相当于降维,即在当前命名空间内,将集群角色绑定(可减小资源开销),最终是命名空间级别
2.4RBAC规则解析
①、rules字段结构
每个规则包含:
-
apiGroups
:资源所属的API组("" 表示核心组) -
resources
:资源类型名称(复数形式) -
verbs
:操作动词(如 get, list, create, update, delete, watch) -
resourceNames
:可选,指定具体资源实例名称 -
nonResourceURLs
:非资源端点(如 "/healthz")
②、apiGroups(分组)
分组字符串 | 说明 / 常见资源 |
---|---|
"" (空串) |
核心组(Core)。Pod、Service、ConfigMap、Secret、Node、Namespace、Event ... |
apps |
Deployment、StatefulSet、DaemonSet、ReplicaSet、ControllerRevision |
batch |
Job、CronJob |
autoscaling |
HorizontalPodAutoscaler(HPA) |
networking.k8s.io |
Ingress、NetworkPolicy、IngressClass |
policy |
PodDisruptionBudget、PodSecurityPolicy(已弃用) |
以上分组只是部分,详情请见官方文档
③、resources(资源)
-
""
组pods
,services
,configmaps
,secrets
,endpoints
,events
,persistentvolumeclaims
,persistentvolumes
,nodes
,namespaces
,serviceaccounts
,resourcequotas
,limitranges
-
apps
组deployments
,statefulsets
,daemonsets
,replicasets
,controllerrevisions
-
batch
组jobs
,cronjobs
以上只列出每个分组最常用的;完整列表可用
kubectl api-resources -o wide
。每个大资源其下会有子资源
④、verbs(动作)
动词 | 含义 | 典型组合 |
---|---|---|
get |
读取单个资源 | 只读 |
list |
读取集合 | 只读 |
watch |
监听变化 | 只读 |
create |
新建资源 | 写 |
update |
整体更新资源 | 写 |
patch |
局部更新资源 | 写 |
delete |
删除单个资源 | 写 |
deletecollection |
批量删除集合 | 写 |
* |
所有动作(通配符) | 超级权限 |
四、准入控制
当 API Server 已经通过 认证 & 鉴权 ,但在真正持久化之前 ,由一组 准入插件(Admission Webhook 或内置控制器) 再对资源做 "增删改"拦截或修改。
主要是对额外功能的添加以及有权限但不合理的行为的过滤。