前言
本文系统阐述Kubernetes安全机制的核心架构与实践方法,详细解析API Server保护的三大关键环节:认证、鉴权和准入控制,以及如何通过RBAC实现细粒度权限管理。特别聚焦在实践中如何创建安全隔离的集群访问账号,适用于Kubernetes安全架构设计与运维人员。
- 安全机制说明
- 认证:身份
- 鉴权:权限
- 准入控制
- 实践:赋权普通用户操作k8s
理论部分
1_安全机制概述
安全机制:保护Kubernetes集群中API Server的三层防护体系,防止未授权访问和操作。
1.1_机制说明
安全体系设计原因:Kubernetes作为分布式集群管理工具,API Server是内部组件通信中介与外部控制入口,安全机制围绕保护API Server设计。
安全三大环节:
- 认证(Authentication):验证"你是谁",确认请求主体身份 — 身份验证
- 鉴权(Authorization):确定"你能做什么",判定权限范围 — 资源权限控制
- 准入控制(Admission Control):决定"是否允许该请求被接受",请求进一步校验 — 二次验证
工作流程:
- 客户端(如kubectl)向API Server发送请求
- 请求通过三重安全关卡(认证→鉴权→准入控制)
- 所有关卡通过后,API Server才处理该请求
2_认证Authentication
2.1_认证方式
认证方式:API Server支持的三种主要认证方式。
| 认证方式 | 实现原理 | 特点 | 核心作用 |
|---|---|---|---|
| HTTP Token | HTTP Header携带难以仿冒的长Token | API Server维护Token与用户权限的映射。 | 授权访问特定API或资源 |
| HTTP Basic | Base64编码的用户名:密码放入Authorization字段 | 简单但安全性极低(密码明文传输,必须配合HTTPS) | 最基础的身份验证 |
| HTTPS证书 | 基于CA根证书签名的双向TLS认证 | 最严格,实现客户端与服务器的双向身份验证 | 建立通信双方的可信身份并加密通道 |
重要说明:
- Token与Basic认证仅支持服务端对客户端的单向认证
- HTTPS证书认证可实现双向认证(客户端与服务端互相验证)
2.2_认证对象
需要被认证的访问类型:
- Kubernetes组件对API Server的访问:kubectl、kubelet、kube-proxy
- 由Kubernetes管理的Pod对API Server的访问:coredns、dashboard等
端口与证书安全性:
- Controller Manager、Scheduler与API Server同机,常走非安全端口(如8080)
- kubectl、kubelet、kube-proxy访问API Server需HTTPS双向认证,端口使用6443
2.3_证书管理
证书颁发方式:
- 手动签发:二进制部署时,需与CA手动签发HTTPS证书
- 自动签发:kubelet首次访问用token认证,通过后由Controller Manager生成证书
kubeconfig:包含三类关键参数的配置文件
- 集群参数:CA证书、API Server地址
- 客户端参数:证书与私钥
- 上下文参数:集群名、用户名、命名空间
- kubectl默认位置:
~/.kube/config
Service Account (SA):用于Pod中容器访问API Server的身份标识
- 自动应对Pod动态创建/销毁场景
- 无需为每个Pod单独发证书
- 默认每个命名空间都有一个SA
2.4_Secret与SA的关系
Secret对象类型:
- service-account-token:保存ServiceAccount的令牌
- Opaque:保存用户自定义的保密信息
Service Account组成:
- Token:API Server私钥签名的Token
- ca.crt:CA根证书,验证API Server证书
- namespace:service-account-token的命名空间作用域
默认行为:
- 若创建Pod时未指定SA,将使用所属命名空间的defaultSA
- 系统自动将以下内容挂载到容器:
/var/run/secrets/kubernetes.io/serviceaccount/ ├── ca.crt ├── namespace └── token
小结
k8s 安全机制 3关 认证 鉴权 准入控制 认证 token 使用很长复杂的token(令牌)字符串 来做认证,通常是单向认证 basic 使用账号 密码的格式通过 base64编码和解码来做认证 通常是单向的认证 https 使用CA机构签发的证书进行https认证 可以实现双向认证 k8s 认证 组件 (**Controller Manager、Scheduler** **kubectl、kubelet、kube-proxy** 等)与apiserver通信,是使用https证书认证,默认使用6443进行通信 (未知Scheduler Controller 使用内部端口 8080 ),使用kubeconfig配置文件就知道使用什么证书连接到那个K8s的集群的APIserver pod 形式 的组件 (dashboad coredns 外置存储常插件 比如 NFS provsisnor)与APIserver通信,使用serviceaccount作为pod服务的账号来访问APIserver 每个pod都会有 一个 serviceaccouint服务账号,可以创建pod资源时指定serviceaccouint字段3_鉴权Authorization 重点
3.1_授权策略对比
授权策略:API Server通过--authorization-mode参数配置。
| 策略 | 特点 | 适用场景 |
|---|---|---|
| AlwaysDeny | 拒绝所有请求 | 测试环境 |
| AlwaysAllow | 允许所有请求 | 无安全要求环境 |
| ABAC(淘汰) | 基于用户配置的属性的静态规则,繁琐需重启ApiServer。 | 简单权限需求 |
| Webhook | 外部REST服务鉴权,触发器钩子 | 统一外部认证系统 |
| RBAC | 基于角色的动态权限,细粒度,与资源模型一致。 | 生产环境默认(≥v1.6) |
RBAC核心优势:
- 覆盖资源(Pod/Deployment/Service)与非资源(元信息/状态)
- 由标准API资源对象构成,可用kubectl/API管理
- 运行时可调整,无需重启API Server(ABAC需重启)
3.2_RBAC资源对象
① RBAC引入的四个顶级对象
Role
- 命名空间级权限定义
- 定义特定命名空间的权限
ClusterRole - 集群级权限,跨命名空间。
- 定义集体集群范围内的所有权限
RoleBinding - 命名空间内将角色绑定到主体
- 将Role或ClusterRole绑定到特定命名空间的主体
ClusterRoleBinding - 集群级将角色绑定到主体
- 将ClusterRole绑定到整个集群范围内的主体
② 绑定规则
- RoleBinding可引用ClusterRole,但仍受命名空间限制
- ClusterRoleBinding只能绑定ClusterRole作用于全集群
③ 权限控制模型
- 仅能累加(白名单模型)
- 不存在"先权限多再减少"的黑名单机制
- Role仅限单一命名空间;ClusterRole可跨命名空间
3.3_角色与角色绑定
① 角色定义:
- Role:只定义在一个命名空间内的权限
- ClusterRole:可定义跨多个命名空间的权限
Role示例(在default命名空间读取Pod):
apiVersion:rbac.authorization.k8s.io/v1kind:Rolemetadata:namespace:defaultname:pod-readerrules:-apiGroups:[""]resources:["pods"]verbs:["get","watch","list"]ClusterRole示例(读取所有命名空间Secret):
apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:secret-readerrules:-apiGroups:[""]resources:["secrets"]verbs:["get","watch","list"]② 角色绑定:
- RoleBinding:将Role/ClusterRole绑定到主体(User/Group/SA),限于命名空间
- ClusterRoleBinding:在全集群范围绑定ClusterRole到主体
RoleBinding示例(将pod-reader绑定给jxc用户):
apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:name:read-podsnamespace:defaultsubjects:-kind:Username:jxcapiGroup:rbac.authorization.k8s.ioroleRef:kind:Rolename:pod-readerapiGroup:rbac.authorization.k8s.io③ 主体(Subject)类型
- User(用户)
- Group(用户组)
- ServiceAccount(服务账号)
- 系统保留前缀:system:*(管理员应避免普通用户使用)
④ 资源(Resources)定义
- K8s资源以名称字符串表示(如pods, services)
- 子资源:如pods/log
- API访问示例:
GET /api/v1/namespaces/{namespace}/pods/{name}/log - 在RBAC中使用"资源/子资源"控制访问
④ 常见权限
- verbs:get、list、watch、create、update、patch、delete、exec
- resources:services、pods、secrets、configmaps等
- apiGroups:“”(core)、apps、autoscaling等
小结:
1、角色(Role/clusterRole) Role: 定义 特定的命名空间内的权限 clusterRole:定义整体集群范围内的所有权限 2、角色绑定 (RoleBinding/clusterRolebing) RoleBinding: 将Role或clusterRole绑定到特定(单)的命名空间内的用户、组或服务账号 clusterRolebing:将clusterRole绑定到整个集群范围内的用户、组或服务账号 主体(subject): 用户 (User) 组(Group) 服务账号(SerivceAccount) 权限管理 RBAC 基于 白名单 机制 只能增加权限 无法通过RBAC 直接减少权限 resource http 调用 一个方法 get pull put kubectl get pod 来获取 资源的信息 GET /api/v1/namespaces/pods4_准入控制AdmissionControl
4.1_准入控制概述
Admission Control:API Server处理请求前的最后一道关卡。
工作机制:
- 一组插件链,请求依次通过该列表
- 若任意插件拒绝,整个请求即被拒绝
- 建议采用官方推荐的控制器组合
官方默认插件链:
不同版本有所不同
NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,NodeRestriction4.2_关键插件功能
重点插件说明:
NamespaceLifecycle:
- 命名空间生命周期管理
- 阻止在不存在的命名空间创建对象
- 阻止删除系统命名空间
- 删除命名空间时级联清理
LimitRanger:
- 配额与限制管理
- 确保请求不超过该命名空间的LimitRange
ServiceAccount:
- 为Pod自动注入ServiceAccount
- 便于Pod访问API Server
ResourceQuota:
- 命名空间级高级配额
- 确保不超过该命名空间的ResourceQuota
NodeRestriction:
- 限制Node加入集群后的权限
- 遵循最小权限原则
官方文档:https://kubernetes.io/zh/docs/reference/access-authn-authz/admission-controllers/
实验部分
1_创建仅能管理指定命名空间的用户
1.1_准备工作
① 创建系统用户
- 创建操作系统层用户
useraddjxcechoqwer1234|passwd--stdin jxc# 切换用户验证su- jxc kubectl get podsThe connection to the server localhost:8080 was refused - did you specify the right host or port? 连接到服务器 localhost:8080 被拒绝 - 您是否指定了正确的主机或端口?
useradd:创建系统用户passwd:设置用户密码
jxc用户还未配置kubeconfig所以访问失败,为正常现象
1.2_生成证书与kubeconfig
① 上传证书工具
- 从本地上传证书工具
cfssl、cfssljson、cfssl-certinfo到 Master节点主机的/usr/local/bin目录下
# user@localhostscpcfssl cfssljson cfssl-certinfo root@k8s-master01:/usr/local/bin/CFSSL工具链是用于简单快速创建和管理TLS证书的命令行工具集。
cfss:l是核心生成器cfssljson:负责拆分证书文件cfssl-certinfo:用于查看证书信息
RSA/ECC非对称加密工具:
注释:RSA历史久远更常见,ECC更小更安全更现代。类似TLS是SSL的迭代产品。
| 工具 | 特点 | 适合场景 |
|---|---|---|
| OpenSSL | 老牌经典,功能全面,预装在多数系统 | 单次手动操作、故障排查、学习原理 |
| CFSSL | 现代,配置驱动,易于自动化 | 云平台、容器集群(如K8s)、需要批量签发证书 |
- 并赋予执行权限
# root@k8s-master chmod +x /usr/local/bin/cfssl* mkdir -p /opt/jxc && cd /opt/jxc
cfssl系列工具需提前安装并放置在PATH中
② 创建证书请求文件
# root@k8s-master01:/opt/jxcvimuser-cert.sh#!/bin/bashkube_user=jxccat>"$kube_user"-csr.json<<EOF { "CN": "$kube_user", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "BeiJing", "L": "BeiJing", "O": "k8s", "OU": "System" } ] } EOFcd/etc/kubernetes/pki/ cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /opt/$kube_user/"$kube_user"-csr.json|cfssljson -bare$kube_user
algo:algorithm(算法)的缩写CN:作为User身份names.O:作为Group身份(k8s)
API Server会将CN作为User,names.O作为Group"hosts": []:用户认证不需要填写,服务器/节点/Pod认证才需要补全hosts信息(IP/域名)。后面会warning警告,不必理会。
- 执行证书生成,会在
/etc/kubernetes/pki/生成证书:jxc-key.pem、jxc.pem、jxc.csr
# root@k8s-master01:/opt/jxcchmod+x user-cert.sh ./user-cert.shls/opt/jxc /etc/kubernetes/pki/|grep^jxcjxc.csr jxc-key.pem jxc.pem jxc-csr.json
jxc-csr.json:生成证书的申请配置模板,里面填写了你的身份信息和需求。jxc-key.pem:你的私钥,是绝不能泄露的核心秘密,用来证明你的身份并对CSR签名。jxc.csr:根据配置和私钥生成的证书请求文件,包含你的公钥和信息,并由私钥签名(数字签名),提交给CA机构用于申请证书。jxc.pem:CA机构颁发给你的正式证书,包含了你的公钥和CA的签名,是公开的身份凭证。
③ 生成kubeconfig
- 创建kubeconfig生成脚本
vimrbac-kubeconfig.sh#!/bin/bashAPISERVER=192.168.100.13# 必须替换为实际API Server IPkube_user=jxc# 替换为🗺的kube用户kube_namespace=yjs1023# 替换为实际的命名空间# 设置集群参数exportKUBE_APISERVER="https://$APISERVER:6443"kubectl config set-cluster kubernetes\--certificate-authority=/etc/kubernetes/pki/ca.crt\--embed-certs=true\--server=${KUBE_APISERVER}\--kubeconfig="$kube_user".kubeconfig# 设置客户端认证参数kubectl config set-credentials"$kube_user"\--client-key=/etc/kubernetes/pki/"$kube_user"-key.pem\--client-certificate=/etc/kubernetes/pki/"$kube_user".pem\--embed-certs=true\--kubeconfig="$kube_user".kubeconfig# 设置上下文参数kubectl config set-context kubernetes\--cluster=kubernetes\--user="$kube_user"\--namespace="$kube_namespace"\--kubeconfig="$kube_user".kubeconfig# 使用上下文参数生成 .kubeconfig 文件kubectl config use-context kubernetes --kubeconfig="$kube_user".kubeconfig设置集群参数、客户端认证参数和上下文
- 生成实际kubeconfig
chmod+x rbac-kubeconfig.sh ./rbac-kubeconfig.sh生成jxc.kubeconfig文件
1.3_权限配置
① 创建命名空间与应用配置
- 创建测试命名空间
kubectl create namespace yjs1023- 分发kubeconfig到用户目录
mkdir-p /home/jxc/.kubecpjxc.kubeconfig /home/jxc/.kube/configchown-R jxc:jxc /home/jxc/.kube/使jxc用户能使用此配置文件
② 创建RBAC规则
- 创建rbac.yaml权限配置文件
vimrbac.yamlapiVersion:rbac.authorization.k8s.io/v1kind:Rolemetadata:namespace:yjs1023name:pod-readerrules:-apiGroups:[""]resources:["pods"]verbs:["get","watch","list","create"]---apiVersion:rbac.authorization.k8s.io/v1kind:RoleBindingmetadata:name:read-podsnamespace:yjs1023subjects:-kind:Username:jxcapiGroup:rbac.authorization.k8s.ioroleRef:kind:Rolename:pod-readerapiGroup:rbac.authorization.k8s.io定义jxc在yjs1023命名空间的权限:
- get/watch/list/create Pod
- 应用RBAC配置
kubectl apply -f rbac.yaml kubectl get role,rolebinding -n yjs1023NAME CREATED AT role.rbac.authorization.k8s.io/pod-reader 2026-01-21T14:28:54Z NAME ROLE AGE rolebinding.rbac.authorization.k8s.io/read-pods Role/pod-reader 28s1.4_权限验证
① 验证jxc各项权限
- 切换用户并创建测试Pod
su- jxccat>role-rolebinding-test.yaml<<'YAML' apiVersion: v1 kind: Pod metadata: name: role-rolebinding-test spec: containers: - name: nginx image: nginx YAMLkubectl create -f role-rolebinding-test.yaml kubectl get pods -o wide预期输出:role-rolebinding-test成功创建并运行
- 测试跨命名空间访问
kubectl get pods -n defaultError from server (Forbidden): pods is forbidden: User "jxc" cannot list resource "pods" in API group "" in the namespace "default"访问其他命名空间失败,权限受限
- 测试其他资源访问
kubectl get svcError from server (Forbidden): services is forbidden: User "jxc" cannot list resource "services" in API group "" in the namespace "yjs1023"无权限查看Service资源
② 管理员视角验证
- root用户查看资源
# root@k8s-masterkubectl get pods --all-namespaces -o wideNAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES yjs1023 role-rolebinding-test 1/1 Running 0 5m2s 10.244.1.17 k8s-node01 <none> <none>确认RoleBinding已生效
- 查看所有角色和绑定
kubectl get role,rolebinding -n yjs1023③ 可选:授予管理员权限
- 授予用户特定命名空间管理员权限
kubectl create rolebinding jxc-admin-binding\--clusterrole=admin\--user=jxc\--namespace=yjs1023将集群admin角色绑定到用户,但限制在yjs1023命名空间
结语
如果想要有让一个pod 或者 Serivce secert configmap等 /普通用户 具有 接入 k8s =集群相关资源的操作权限 1、创建serviceaccount 或者 用户 2、做认证 token/证书认证 ① serviceaccount 会自动 生成Serivceaccount token 的 secret 资源 ② 用户需要创建证书,使用cfssl等工具通过CA证书和私钥文件 生成 证书和 私钥文件, 使用CA证书和私钥文件来去创建kubeconfig配置文件, 把kubeconfig配置文件导入用户的家目录中 目录名.kube/config文件中 3、做RBAC鉴权 Role|clusterRole 创建角色赋予给资源的操作权限(**resources**、verbs) Rolebinding|cluster Rolebinding 把主体(用户|组|服务账号)和角色进行绑定 此时切换用户后pod 或者用户具有相关的命名空间的中对相关子资源有了操作权限API Server安全:Kubernetes通过认证、鉴权和准入控制三道防线保护API Server;6443端口是安全访问的关键门户。
RBAC架构:基于Role/ClusterRole定义权限,通过RoleBinding/ClusterRoleBinding进行绑定;实现命名空间级精细权限控制。
安全最佳实践:最小权限原则,通过SA管理Pod访问权限;RBAC结合NetworkPolicy实现纵深防御。
[!question] 请问Kubernetes安全体系的三个环节分别是什么?
认证(确认身份)、鉴权(确认权限)、准入控制(请求验证), 请求必须经过这三道关卡才能被API Server处理
[!question] 为什么说RBAC是生产环境的推荐选择?
RBAC支持运行时调整权限,无需重启API Server;通过标准API资源管理;支持命名空间级和集群级权限控制
[!question] ServiceAccount自动产生哪些内容?
自动挂载三个文件到容器:token(认证令牌)、ca.crt(API Server根证书)、namespace(命名空间信息)
[!question] 如何限制用户只能在特定命名空间操作?
通过Role+RoleBinding组合:Role定义命名空间内权限,RoleBinding将角色绑定到特定用户
[!question] AlwaysAllow和AlwaysDeny策略适用于什么场景?
AlwaysAllow用于无安全要求或测试场景;AlwaysDeny用于安全测试,模拟拒绝所有请求环境