Kubernetes 认证与授权详解:守护集群API访问安全

前言

Kubernetes几乎所有操作,kubectl操作、Pod内部程序访问集群、第三方平台对接,全部都要请求kube‑apiserver。如果API接口没有访问管控,任何人都可以随意增删集群资源,集群安全将完全失控。

K8s设计了一套分层访问控制链路,一次API请求会依次经历:TLS传输安全 → 身份认证 → 鉴权授权 → 准入控制,最后写入etcd,还支持审计日志记录操作行为。很多同学容易混淆认证和授权:认证解决"你是谁",授权解决"你能干什么"。本文结合实操带你完整理解整套权限体系。

一、Kubernetes API访问控制完整流程

完整请求链路:

  1. 传输安全TLS:客户端与apiserver通信全部走TLS加密,apiserver默认监听6443端口,生产环境常用443。客户端需要CA证书验证服务端证书,防止中间人劫持。
  2. 身份认证Authentication :校验请求方身份,确认你是谁。认证失败直接返回401 Unauthorized。多个认证插件顺序尝试,任意一个认证成功即通过。
  3. 鉴权授权Authorization :确认身份之后,判断该用户是否允许执行本次操作(什么用户、什么命名空间、什么资源、什么动作)。全部鉴权模块都无许可则返回403 Forbidden。
  4. 准入控制Admission Control :仅针对增删改请求,只读请求不会执行。多个准入控制器串行执行,任意一个拒绝,请求直接失败;还可以自动补全资源默认字段。
  5. 校验资源格式合法,写入etcd持久化。
  6. 审计Audit:按时间记录集群安全相关操作,用于事后追溯排查。

区分状态码:401代表身份不合法(认证失败);403代表身份没问题,但是权限不足(鉴权拒绝)。

二、身份认证:确认访问者"你是谁"

K8s有两类访问身份:普通用户(人使用)、服务账号ServiceAccount(Pod内程序使用)。

2.1 两类用户核心区别

  1. 普通用户User
    Kubernetes没有User这个API资源对象!集群不会保存普通用户账号。用户名来源于外部认证插件:X509证书CN字段、令牌、外部LDAP/OIDC。集群不能通过kubectl查询普通用户列表。

设计哲学:K8s只做编排,身份交给外部系统,方便对接企业AD、LDAP。

  1. 服务账号ServiceAccount
    属于K8s原生API资源,命名空间隔离,每个ns自带defaultSA;会生成令牌,挂载进Pod,供容器内部程序调用apiserver。

2.2 主流认证插件

  • X509客户端证书:日常kubectl使用方式,apiserver启动参数--client‑ca‑file校验客户端证书。证书CN就是用户名,O对应用户组。
  • Bootstrap Token:集群节点加入的引导令牌,存放在kube-system下Secret。
  • ServiceAccount JWT令牌:Pod内部访问集群默认认证方式。
  • 静态令牌文件、Webhook认证、认证代理;1.19版本废弃basic‑auth-file。

实操:X509证书创建外部普通用户

实现创建laoma用户,签发证书,生成kubeconfig配置文件。

  1. 客户端生成私钥与证书请求csr
bash 复制代码
openssl genrsa -out laoma.key 2048
openssl req -new -key laoma.key -out laoma.csr -subj '/CN=laoma/O=kubernetes'
  1. Master节点使用集群CA签发用户证书
bash 复制代码
openssl x509 -req -in laoma.csr -CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out laoma.crt -days 1095
  1. 组装kubeconfig,写入集群CA、用户证书私钥。

重点:删除普通用户权限,只需要删除RBAC绑定;证书本身没有过期撤销机制,如果证书未过期,即使删除集群内RBAC绑定,持有证书依然可以完成认证,只是鉴权会403。真正封禁用户需要证书黑名单。

匿名请求

没有携带任何有效认证凭据的请求,识别为匿名用户system:anonymous,用户组system:unauthenticated,交由鉴权模块判断是否允许操作。

三、授权鉴权:判断"你可以干什么"

认证通过只是知道用户是谁,授权决定该用户可以执行哪些操作。apiserver参数--authorization‑mode指定启用鉴权模块,生产常用Node,RBAC。

支持模式:

  • RBAC:最常用,动态API配置权限;
  • Node:专门给kubelet节点使用的鉴权;
  • ABAC:静态json策略文件,现已不推荐;
  • Webhook:把鉴权交给外部http服务;
  • AlwaysAllow全部放行;AlwaysDeny全部拒绝。

RBAC核心4种资源

资源 作用 生效范围
Role 定义一组权限规则(资源+动作verbs) 单个命名空间
RoleBinding 把Role绑定给User/SA/Group 绑定的命名空间内生效
ClusterRole 集群级权限规则,可以包含集群资源、所有ns资源 集群全局
ClusterRoleBinding ClusterRole全局绑定主体 全部命名空间生效

小技巧:ClusterRole也可以被RoleBinding引用,此时该ClusterRole权限只会在RoleBinding所在的命名空间生效,不需要ClusterRoleBinding。

verbs 常用动作
  • get:获取单个资源详情
  • list:列出某类型全部资源
  • watch:监听资源变化
  • create/update/patch/delete:增改删操作

apiGroups一定要写对!pod/service属于""空组;deployment属于apps;job属于batch,写错apiGroups会权限一直报错。

实操演示命名空间Role + RoleBinding

创建auth命名空间,创建pod‑reader角色,只允许get/list/watch pod资源。

bash 复制代码
# 创建命名空间
kubectl create ns auth
# 创建Role,auth命名空间内,pod只读权限
kubectl create role pod‑reader -n auth --verb=get,list,watch --resource=pods
# RoleBinding把角色绑定给laoma用户
kubectl create rolebinding laoma‑podread -n auth --role=pod‑reader --user=laoma

此时laoma用户只能在auth命名空间查看pod,其他命名空间无权限。删除rolebinding就回收权限。

ClusterRole与ClusterRoleBinding

系统内置预定义ClusterRole:

  1. view:只读,get/list/watch大部分资源;
  2. edit:普通开发者,读写命名空间内资源;
  3. admin:命名空间管理员;
  4. cluster‑admin:集群超级管理员,最高权限。

示例:创建集群角色,允许所有命名空间查看pod

bash 复制代码
kubectl create clusterrole cluster‑pod‑read --verb=get,list,watch --resource=pods
# 全局绑定,所有命名空间生效
kubectl create clusterrolebinding laoma‑allpod --clusterrole=cluster‑pod‑read --user=laoma

四、服务账号ServiceAccount深度解析

ServiceAccount是Pod内部程序访问apiserver的身份。每个namespace自带default SA,新建Pod默认挂载default账号。

SA令牌机制变化(重点!1.24+)

  • k8s1.24之前:SA会自动生成永久token的Secret,永久有效,风险高;
  • k8s1.24及以上:Bound ServiceAccount Token,短期临时令牌,kubelet通过TokenRequest API获取,默认1小时有效期,Pod销毁令牌立刻失效,通过projected投射卷挂载。

容器内部固定路径:/var/run/secrets/kubernetes.io/serviceaccount/,里面包含token、ca.crt、namespace。Pod内部程序读取token,放在http请求Authorization: Bearer <token>访问apiserver。

SA授权与使用

bash 复制代码
# 创建sa
kubectl create sa sa‑app -n auth
# 将集群角色绑定给服务账号,格式:命名空间:sa名称
kubectl create clusterrolebinding sa‑app‑admin --clusterrole=view --serviceaccount=auth:sa‑app

Pod通过serviceAccountName: sa‑app指定使用的服务账号。

注意:不要随意给业务Pod授予cluster‑admin最高权限,遵循最小权限原则。

手动获取临时token:

bash 复制代码
kubectl create token sa‑app -n auth

五、常见坑点总结

  1. 401和403区分不清:401认证失败(证书/token错误);403认证成功但是权限不足,排查RBAC;
  2. apiGroups写错:deployment写空字符串,权限永远不生效;
  3. 普通用户删除:删除RBAC绑定不等于吊销证书,证书没过期依旧认证成功;
  4. RoleBinding引用ClusterRole:权限只在当前命名空间,不是全局;
  5. ServiceAccount新版本不会自动生成Secret,不要手动创建永久token,优先使用临时token;
  6. 多个鉴权模块:只要一个模块允许就放行;全部无意见才拒绝。

六、思考:K8s为什么没有内置普通用户管理?

Kubernetes本身不提供User资源,不存储人类用户账号。遵循UNIX设计哲学:一件事做好一件工作。K8s专注容器编排,身份认证向外提供插件接口。企业可以对接LDAP、OIDC、Keycloak等成熟身份系统,实现账号统一管理,集群和身份系统解耦。

总结

  1. K8s API访问四层防护:TLS传输加密、身份认证、RBAC鉴权、准入控制,再加审计日志完成安全闭环;
  2. 认证解决"你是谁",分为外部普通用户(证书、令牌)、内部服务账号SA;
  3. RBAC区分命名空间级别Role和集群级别ClusterRole;绑定对象区分RoleBinding和ClusterRoleBinding;
  4. 新版本ServiceAccount使用短期Bound Token,废弃永久Secret令牌;
  5. K8s把用户身份交给外部系统,自身只做权限鉴权,便于企业集成。

环境清理

bash 复制代码
kubectl delete ns auth

相关推荐
安协技术部门2 小时前
安全光栅与红外报警器安全回路设计有什么区别?
安全·制造
Godspeed Zhao2 小时前
具身智能系统概论——系统安全与可靠性
安全·系统安全
自由彩虹2 小时前
靶场通关16--victim1
linux·服务器·网络·安全·web安全·网络安全
闲云野鹤在人间2 小时前
头秃修炼手册:StorageClass+StatefulSet+ETCD 全套渡劫笔记
linux·数据库·笔记·云原生·kubernetes·etcd
安教安全员通关宝3 小时前
2026年四川安全员B证考试题库+答案+解析
安全
艾伦_耶格宇3 小时前
【kubernetes - 1.28版本】-7 K8S命令
云原生·容器·kubernetes
L02082415 小时前
Kubernetes Ingress|CNI 网络模型|Calico 网络策略|Pod 调度器完整实战教程
运维·网络·云原生·容器·kubernetes
安教安全员通关宝16 小时前
2026年吉林安全员C3证考试题库+答案+解析
安全