k8s(九)安全机制
文章目录
- 前言
- 一、身份认证(Authentication):确认“你是谁”
- 1.1 核心认证对象
- 1.2 主流认证方式
- 二、 授权(Authorization):判断“你能做什么”
- 2.1 主流授权模式
- 三、准入控制(Admission Control):“操作前的最后检查”
- 四、Pod安全机制:限制容器“能做什么”
- 1. Pod安全标准(Pod Security Standards,PSS)
- 2. 关键安全配置
- 五、网络安全:隔离“谁能和谁通信”
- 1. 核心概念
- 2. 示例:限制Pod通信
- 六、 Secrets与敏感数据安全:保护“机密信息”
- 1. 核心安全措施
- 总结:k8s安全机制的核心逻辑
- -----------------------------------------------------------------------------------------------------------
- 一、Kubernetes 安全机制概述
- 二、认证(Authentication)
- 2.1 支持的认证方式
- 2.2 需要被认证的访问类型
- 2.3 安全性说明(端口与证书)
- 2.4 证书颁发方式
- 2.5 kubeconfig
- 2.6 Service Account(SA)
- 2.7 Secret 与 SA 的关系
- 三、鉴权(Authorization)
- 3.1 授权策略与对比
- 3.2 RBAC 资源对象
- 3.3 角色(Role/ClusterRole)
- 3.3.1 Role 示例
- 3.3.2 ClusterRole 示例
- 3.4 角色绑定(RoleBinding/ClusterRoleBinding)
- 3.4.1 RoleBinding 示例 1
- 3.4.2 RoleBinding 示例 2
- 3.4.3 ClusterRoleBinding 示例
- 3.5 主体(Subject)与 JWT
- 3.6 Resources
- 3.6.1 常见 verbs、resources、apiGroups 速查
- 四、准入控制(Admission Control)
- 4.1 推荐插件列表示例
- 4.2 部分插件说明
- 五、实践:创建仅能管理指定命名空间的用户
- 5.1 目标
- 5.2 创建系统用户
- 5.3 生成证书与 kubeconfig
- 5.3.1 准备证书工具
- 5.3.2 生成证书签名请求(CSR)
- 5.3.3 生成 kubeconfig
- 5.4 创建命名空间与配置 kubeconfig 上下文
- 5.5 RBAC 授权(Role + RoleBinding)
- 5.6 切换用户并验证权限
- 5.6.1 问题补充
- 5.7 管理员侧验证
- 5.8 可选:授予命名空间管理员权限
- 六、官方文档与参考
- 总结
前言
Kubernetes(k8s)作为容器编排平台,其安全机制围绕“纵深防御”理念设计,覆盖从集群基础设施到容器应用的全生命周期,核心目标是保障集群组件安全、容器运行安全、网络通信安全、数据存储安全及访问权限可控。以下从6个核心维度,详细拆解k8s的安全机制:
一、身份认证(Authentication):确认“你是谁”
身份认证是k8s安全的第一道防线,用于验证访问者(用户/组件/服务)的身份合法性,仅负责“身份确认”,不涉及权限判断。k8s不存储用户信息,而是依赖外部认证源或内置机制实现认证。
1.1 核心认证对象
- 用户(User):面向集群外的人类用户(如运维人员),k8s不提供用户管理功能,需通过外部系统(如LDAP、OAuth2.0)或静态凭证认证。
- 服务账户(Service Account):面向集群内的Pod/服务(如应用程序调用k8s API),由k8s自动创建和管理,关联到具体Namespace,权限范围更精细。
1.2 主流认证方式
认证方式 | 适用场景 | 原理说明 |
---|---|---|
客户端证书(X.509) | 集群管理员、核心组件(如kubelet、apiserver) | 通过CA签发的证书验证身份,证书包含用户名(Subject 字段),安全性最高,是k8s默认推荐方式。 |
静态令牌(Static Token) | 测试环境、临时访问 | 预定义令牌(存储在token.csv ),访问时通过Authorization: Bearer <token> 传递,安全性较低,不建议生产使用。 |
ServiceAccount Token | 集群内Pod访问API Server | k8s自动为Service Account生成令牌,通过Secret 挂载到Pod的/var/run/secrets/kubernetes.io/serviceaccount 目录,Pod内应用可直接使用该令牌调用API。 |
OAuth2.0/OIDC | 企业级用户认证(对接SSO系统) | 集成外部身份提供商(如Keycloak、Azure AD),支持第三方登录,适合多团队协作场景。 |
用户名/密码(Basic Auth) | 测试环境 | 静态存储用户名密码(basic-auth.csv ),明文传输风险高,仅用于临时测试。 |
二、 授权(Authorization):判断“你能做什么”
授权在认证通过后执行,用于判断已认证用户/服务是否有权限执行某个操作(如创建Pod、删除ConfigMap),核心是“权限规则匹配”。k8s支持多种授权模式,可通过apiserver
的--authorization-mode
参数启用(多个模式用逗号分隔,按顺序生效)。
2.1 主流授权模式
-
RBAC(Role-Based Access Control,基于角色的访问控制)
k8s 默认且推荐的授权模式,通过“角色(Role)”定义权限,“角色绑定(RoleBinding)”将角色关联到用户,实现权限的精细化管理,且权限范围与Namespace强关联(集群级用ClusterRole
和ClusterRoleBinding
)。- 核心概念:
Role
:Namespace内的权限集合(如“允许读取default命名空间的Pod”);ClusterRole
:集群级权限集合(如“允许查看所有命名空间的Node”);RoleBinding
:将Role绑定到用户/Service Account(仅作用于当前Namespace);ClusterRoleBinding
:将ClusterRole绑定到用户(作用于全集群)。
- 核心概念:
-
ABAC(Attribute-Based Access Control,基于属性的访问控制)
通过“属性规则”(如用户、资源类型、Namespace、操作动词)定义权限,规则存储在文件中(--authorization-policy-file
指定)。灵活性高,但规则管理复杂,适合定制化需求场景。 -
Node授权(Node Authorization)
专门为kubelet
设计的授权模式,允许kubelet
仅访问其管理的Node/Pod相关资源(如上报Node状态、获取Pod日志),避免kubelet
拥有过度权限。 -
Webhook授权
将授权判断委托给外部HTTP服务(如企业内部权限系统),k8s通过Webhook请求外部服务,根据返回结果(allow/deny
)决定是否允许操作,适合需要对接外部权限体系的场景。
三、准入控制(Admission Control):“操作前的最后检查”
准入控制是API请求的最后一道安全关卡,仅作用于“创建、更新、删除”等会修改集群状态的API操作(查询操作不经过准入控制),用于对请求进行“拦截-校验-修改”,确保资源符合集群安全策略。
k8s通过准入控制器(Admission Controller) 实现该功能,控制器分为两类:
-
内置准入控制器:k8s原生提供,需通过
apiserver
的--enable-admission-plugins
启用,核心控制器包括:NamespaceLifecycle
:禁止在不存在的Namespace中创建资源,删除Namespace时清理关联资源;LimitRanger
:强制Pod遵守Namespace的资源限制(如CPU/内存上限),防止资源滥用;ResourceQuota
:限制Namespace的总资源使用(如最多创建10个Pod),避免单Namespace耗尽集群资源;PodSecurity
:强制Pod遵守安全标准(如禁止以root用户运行),替代旧版的PodSecurityPolicy
(PSP已在k8s 1.25+移除);ServiceAccount
:自动为Pod挂载默认Service Account(若未指定),简化服务账户使用;NodeRestriction
:限制kubelet
仅修改自身Node的标签/污点,防止节点越权操作。
-
动态准入控制器(Dynamic Admission Control):通过
ValidatingWebhook
(校验请求合法性)和MutatingWebhook
(修改请求内容)实现,支持用户自定义规则(如强制Pod添加安全标签、禁止使用特权容器),灵活性极高,是生产环境的核心安全手段(如集成OPA Gatekeeper、Kyverno等工具实现策略即代码)。
四、Pod安全机制:限制容器“能做什么”
Pod是k8s的最小部署单元,其安全机制直接决定容器运行的安全性,核心是“最小权限原则”——禁止容器获取不必要的系统权限。
1. Pod安全标准(Pod Security Standards,PSS)
k8s 1.25+推荐使用PSS定义Pod的安全级别,替代旧版PSP,分为3个等级(从宽松到严格):
级别 | 适用场景 | 核心限制 |
---|---|---|
Privileged | 需完全系统权限的应用 | 无限制(等同于root权限),仅用于核心系统组件(如网络插件),不建议普通应用使用。 |
Baseline | 常规应用(默认推荐) | 禁止已知高危权限(如特权容器、挂载主机目录),允许基本系统操作(如非root用户运行)。 |
Restricted | 高安全需求应用 | 严格限制(如禁止root用户、禁止进程特权升级、限制Linux capabilities),安全性最高。 |
2. 关键安全配置
- Security Context:为Pod/容器设置安全上下文
- Privileged Container:
privileged: true
会让容器获得主机的全部权限(如修改主机内核参数、访问主机设备),严禁普通应用使用。 - Host Namespace:禁止使用
hostNetwork: true
(共享主机网络)、hostPID: true
(共享主机进程空间),避免容器影响主机系统。 - Volume挂载限制:禁止挂载主机敏感目录(如
/etc
、/var/run
),仅允许挂载必要的EmptyDir、ConfigMap等k8s原生存储。
五、网络安全:隔离“谁能和谁通信”
k8s默认允许所有Pod之间自由通信,网络安全机制通过“网络策略(Network Policy)”实现Pod间的通信隔离,确保“仅授权的Pod能通信”。
1. 核心概念
- Network Policy:定义Pod的入站(Ingress)和出站(Egress)流量规则,仅作用于匹配
podSelector
的Pod,且需网络插件支持(如Calico、Flannel+Canal)。 - 无网络策略时:Pod的入站/出站流量默认“允许所有”;若存在匹配的网络策略,未明确允许的流量将被“拒绝”(默认拒绝原则)。
2. 示例:限制Pod通信
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: app-network-policynamespace: default
spec:podSelector: # 作用于标签为app=web的PodmatchLabels:app: webpolicyTypes: # 规则类型(Ingress=入站,Egress=出站)- Ingress- Egressingress: # 入站规则:仅允许标签为app=api的Pod访问80端口- from:- podSelector:matchLabels:app: apiports:- protocol: TCPport: 80egress: # 出站规则:仅允许访问标签为app=db的Pod的3306端口- to:- podSelector:matchLabels:app: dbports:- protocol: TCPport: 3306
六、 Secrets与敏感数据安全:保护“机密信息”
k8s通过Secret
存储敏感数据(如密码、Token、证书),但默认Secret
以Base64编码存储(并非加密),需额外配置安全机制防止泄露。
1. 核心安全措施
- 静态加密(Encryption at Rest):
配置apiserver
使用外部加密 provider(如AES、Vault),将Secret
在etcd中存储为加密数据,而非明文Base64。需在/etc/kubernetes/manifests/kube-apiserver.yaml
中添加:command: - kube-apiserver - --encryption-provider-config=/etc/kubernetes/encryption-config.yaml # 加密配置文件
- 限制Secret访问权限:
通过RBAC禁止普通用户读取Secret
,仅授权必要的Service Account(如部署工具)。 - 动态Secret(如Vault):
不直接在k8s中存储Secret
,而是通过Vault等工具动态生成临时凭证,Pod按需获取(有效期短,泄露风险低),需集成Vault Agent Injector
等组件。 - 避免Secret暴露:
禁止通过env
环境变量挂载Secret
(可能被ps
命令泄露),推荐通过volumeMounts
挂载到文件(仅Pod内进程可访问)。
总结:k8s安全机制的核心逻辑
k8s安全是“多层防御”的集合,各机制环环相扣:
- 身份层:通过认证确认“谁在访问”;
- 权限层:通过授权控制“能做什么”;
- 准入层:通过准入控制拦截“非法操作”;
- 运行层:通过Pod安全配置限制“容器权限”;
- 网络层:通过网络策略隔离“通信范围”;
- 数据层:通过Secret加密保护“敏感信息”。
生产环境中,需结合业务需求启用核心机制(如RBAC、PSS、Network Policy、etcd加密),并搭配外部工具(如OPA、Vault、Falco)进一步增强安全防护能力。
-----------------------------------------------------------------------------------------------------------
一、Kubernetes 安全机制概述
Kubernetes 作为分布式集群的管理工具,API Server 是内部组件通信的中介与外部控制的入口。因此,其安全机制核心围绕保护 API Server 设计。
当客户端(如 kubectl
)向 API Server 请求资源时,需要通过三道关卡:
- 认证(Authentication):验证请求者的身份(你是谁?)
- 鉴权(Authorization):确定请求者的操作权限(你能做什么?)
- 准入控制(Admission Control):对请求进行最终验证与处理(是否允许该请求继续?是否需要在落盘前被变更或验证?)
二、认证(Authentication)
2.1 支持的认证方式
- HTTP Token 认证:在 HTTP Header 中携带一个难以仿冒的长 Token;API Server 维护 Token 与用户名的映射关系。
- HTTP Basic 认证:将“用户名:密码”使用 Base64 编码后放入 Header 的
Authorization
字段。 - HTTPS 证书认证(最严格):基于 CA 根证书签名的双向 TLS 认证。(双向认证,另外两种是单向认证)
注:Token 与 Basic 认证仅支持服务端对客户端的单向认证;HTTPS 证书认证可实现双向认证(客户端验证服务端证书,服务端验证客户端证书)。
2.2 需要被认证的访问类型
- Kubernetes 组件对 API Server 的访问:如
kubectl
、kubelet
、kube-proxy
等。 - Kubernetes 管理的 Pod 对 API Server 的访问:包括以 Pod 形式运行的
coredns
、dashboard
等组件。
2.3 安全性说明(端口与证书)
- Controller Manager、Scheduler 通常与 API Server 部署在同一节点,常通过非安全端口(如
8080
)通信。 - kubectl、kubelet、kube-proxy 访问 API Server 时,需通过 HTTPS 双向认证,端口使用
6443
。
2.4 证书颁发方式
- 手动签发:在二进制部署 Kubernetes 时,需通过 CA 手动签发 HTTPS 证书。
- 自动签发:
kubelet
首次访问 API Server 时使用 token 认证,通过后由 Controller Manager 为其生成证书,后续改用证书访问。
2.5 kubeconfig
kubeconfig 是 Kubernetes 中用于配置集群访问的文件,包含以下关键信息:
- 集群参数:CA 证书、API Server 地址等。
- 客户端参数:客户端证书与私钥等认证信息。
- 上下文参数:集群名、用户名、命名空间等。
通过指定不同的 kubeconfig,组件(如 kubelet
、kube-proxy
)可切换不同集群并连接到对应的 API Server。kubectl
默认使用的 kubeconfig 路径为 ~/.kube/config
。
2.6 Service Account(SA)
Service Account 用于解决 Pod 中容器访问 API Server 的身份认证问题。由于 Pod 具有动态创建和销毁的特性,为每个 Pod 手动颁发证书不可行,因此设计了 Service Account 机制。
2.7 Secret 与 SA 的关系
Kubernetes 中的 Secret 对象主要分为两类:
- service-account-token:保存 ServiceAccount 的令牌等认证信息。
- Opaque:保存用户自定义的保密信息(如密码、密钥等)。
Service Account 包含三部分核心内容:
Token
:由 API Server 私钥签名的 Token,用于服务端认证来访主体。ca.crt
:CA 根证书,供客户端验证 API Server 的证书合法性。namespace
:该 service-account-token 的命名空间作用域。
默认情况下,每个命名空间都有一个默认的 Service Account(default
SA)。若创建 Pod 时未指定 Service Account,将自动使用所属命名空间的 default
SA。创建 Pod 后,系统会自动将以下内容挂载到容器的 /var/run/secrets/kubernetes.io/serviceaccount/
目录:
/var/run/secrets/kubernetes.io/serviceaccount/├─ ca.crt├─ namespace└─ token
示例命令:
# 查看命名空间中的 Service Account
kubectl get sa# 输出示例
NAME SECRETS AGE
default 1 22d# 查看 kube-system 命名空间中的 Pod
kubectl get pod -n kube-system# 进入 Pod 查看挂载的 ServiceAccount 信息
kubectl exec -it kube-proxy-xxxx -n kube-system sh -- ls /var/run/secrets/kubernetes.io/serviceaccount/
# 输出:ca.crt namespace token
三、鉴权(Authorization)
认证确认“你是谁”,鉴权则确认“你能做什么”。API Server 的授权策略通过启动参数 --authorization-mode
进行设置。
3.1 授权策略与对比
- AlwaysDeny:拒绝所有请求(仅用于测试)。
- AlwaysAllow:允许所有请求(仅用于测试或无需授权流程的场景)。
- ABAC(属性基):基于用户配置的属性规则进行授权;配置繁琐,修改通常需要重启 API Server,目前已较少使用。已淘汰,企业不能重启APIServer,不再使用。
- Webhook:调用外部 REST 服务进行授权;可在集群外部统一实现鉴权逻辑,适用于复杂的授权场景。网络钩子,可以自动创建用户、自动授权。也不常用。
- RBAC(基于角色):自 Kubernetes 1.6 起成为默认授权策略;具有动态性、细粒度、与资源模型一致等优势,是目前最常用的授权方式。企业基本都是用RBAC。
RBAC 优势:
- 覆盖资源(如 Pod、Deployment、Service)与非资源(如元信息、状态)的授权管理。
- 由标准 API 资源对象构成,可通过
kubectl
或 API 进行管理。 - 运行时可动态调整权限,无需重启 API Server(ABAC 需重启)。
3.2 RBAC 资源对象
RBAC 引入了 4 个顶级对象:
- Role:命名空间级别的角色,定义该命名空间内的权限。
- ClusterRole:集群级别的角色,可定义跨命名空间的权限或集群级资源的权限。
- RoleBinding:将角色(Role 或 ClusterRole)绑定到主体(User、Group、ServiceAccount),作用范围为命名空间。
- ClusterRoleBinding:将 ClusterRole 绑定到主体,作用范围为整个集群。
若使用 RoleBinding 绑定 ClusterRole,权限仍受限于该 RoleBinding 所在的命名空间;若使用 ClusterRoleBinding 绑定 ClusterRole,则权限作用于全集群。
官方文档:https://kubernetes.io/docs/reference/access-authn-authz/rbac/
3.3 角色(Role/ClusterRole)
- 权限仅能累加(白名单机制),不存在“先赋予所有权限再减少”的黑名单模型。
Role
只能定义在某个命名空间内;跨命名空间的权限定义需使用ClusterRole
。
3.3.1 Role 示例
以下示例定义了在 default
命名空间中读取 Pods 的权限:
apiVersion: rbac.authorization.k8s.io/v1 # 指定 API 组和版本
kind: Role # 指定类型为 Role
metadata:namespace: default # 使用默认命名空间 name: pod-reader # Role 的名称
rules: # 定义规则
- apiGroups: [""] # "" 表示使用 core API 组,""表示 apiGroups 和 apiVersion 使用相同的 core API 组,即 rbac.authorization.k8s.ioresources: ["pods"] # 资源对象为 Pod 类型verbs: ["get", "watch", "list"] # 被授予的操作权限
以上配置的意义是:若将 pod-reader
这个 Role 赋予某个用户,该用户将在 default
命名空间中具有对 Pod 资源进行 get
(获取)、watch
(监听)、list
(列出)操作的权限。
3.3.2 ClusterRole 示例
以下示例定义了读取所有命名空间的 Secrets 的权限:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:# "namespace" 被忽略,因为 ClusterRoles 不受命名空间限制name: secret-reader
rules:
- apiGroups: [""]resources: ["secrets"]verbs: ["get", "watch", "list"]
3.4 角色绑定(RoleBinding/ClusterRoleBinding)
- RoleBinding:在命名空间内将 Role 或 ClusterRole 赋予 User、Group 或 ServiceAccount。
- ClusterRoleBinding:在全集群范围内将 ClusterRole 赋予 User、Group 或 ServiceAccount。
3.4.1 RoleBinding 示例 1
在 default
命名空间内授予用户 zhangsan
读取 Pods 的 Role:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: read-podsnamespace: default
subjects:
- kind: Username: zhangsanapiGroup: rbac.authorization.k8s.io #当kind: ServiceAccount,apiGroup可以省略,也可以apiGroup:""
roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io
上述配置将 default
命名空间的 pod-reader
Role 授予 zhangsan
用户,此后 zhangsan
用户在 default
命名空间中将拥有 pod-reader
定义的权限。
Kubernetes 早期的核心资源(如 Pod、Service、ServiceAccount 等)未采用 API 组机制,后来扩展资源才引入了 API 组。为保持兼容性,核心组资源的 apiGroup 字段可以省略,而扩展组资源则必须明确声明。
3.4.2 RoleBinding 示例 2
在 kube-public
命名空间内给用户 lisi
引用 ClusterRole secret-reader
:
# RoleBinding 可以引用 ClusterRole 来对当前命名空间内的 User、Group 或 ServiceAccount 进行授权,
# 这种操作允许集群管理员在整个集群内定义通用的 ClusterRole,然后在不同命名空间中通过 RoleBinding 引用。
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: read-secretsnamespace: kube-public
subjects:
- kind: Username: lisiapiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: rbac.authorization.k8s.io
kubectl get rolebindings -n kube-public
虽然 secret-reader
具备全集群读取 secrets 的权限,但由于 RoleBinding 定义在 kube-public
命名空间,因此用户 lisi
仅能访问 kube-public
命名空间中的 secrets。
3.4.3 ClusterRoleBinding 示例
将 secret-reader
授予 manager
组,权限作用于全集群:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: read-secrets-global
subjects:
- kind: Groupname: managerapiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: rbac.authorization.k8s.io
上述配置授权 manager
组内的所有用户在全部命名空间中对 secrets 进行访问。
3.5 主体(Subject)与 JWT
- Subject 类型:包括
User
(用户)、Group
(用户组)、ServiceAccount
(服务账号)。 system:
前缀为系统保留,管理员应避免普通用户使用该前缀。- Pod 使用 ServiceAccount 认证时,其
service-account-token
中的 JWT(JSON Web Token)保存用户信息;结合 Role/ClusterRole 与 (Cluster)RoleBinding 完成权限绑定。
3.6 Resources
Kubernetes 集群内的资源通常以名称字符串表示,这些字符串会出现在 API 的 URL 地址中。某些资源包含子资源,例如 Pod 的 log
子资源,其 API 请求 URL 示例为:
GET /api/v1/namespaces/{namespace}/pods/{name}/log
在 RBAC 中,可通过“资源/子资源”的形式控制对资源的访问,示例如下:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: defaultname: pod-and-pod-logs-reader
rules:
- apiGroups: [""]resources: ["pods", "pods/log"] # 控制对 pods 资源及其 log 子资源的访问verbs: ["get", "list"]
3.6.1 常见 verbs、resources、apiGroups 速查
- verbs:
get
、list
、watch
、create
、update
、patch
、delete
、exec
- resources(示例):
services
、endpoints
、pods
、secrets
、configmaps
、deployments
、jobs
、nodes
、rolebindings
、clusterroles
等 - apiGroups:
""
(core 组)、apps
、autoscaling
、batch
等
四、准入控制(Admission Control)
Admission Controller 是一组插件链,请求抵达 API Server 后,将依次通过这些插件的验证;若有插件拒绝该请求,请求将被直接拒绝。建议采用官方默认的控制器组合。
4.1 推荐插件列表示例
不同 Kubernetes 版本的默认插件组合可能存在差异,以下是 Kubernetes 中这些 Admission 插件的详细介绍表格:
插件名称 | 功能描述 | 作用阶段 | 主要用途 |
---|---|---|---|
NamespaceLifecycle | 管理命名空间的生命周期 | 验证阶段 | 阻止在已终止的命名空间中创建资源,防止删除默认命名空间(default、kube-system 等) |
LimitRanger | 实施资源限制和请求 | 变异 + 验证阶段 | 确保 Pod 符合命名空间中定义的 LimitRange 规则,自动为未设置资源的 Pod 分配默认限制 |
ServiceAccount | 管理服务账户及其令牌 | 变异阶段 | 自动为 Pod 关联默认 ServiceAccount,注入令牌 Secret 到 Pod 中 |
DefaultStorageClass | 管理默认存储类 | 变异阶段 | 当 PVC 未指定 storageClassName 时,自动分配集群默认的存储类 |
DefaultTolerationSeconds | 设置默认容忍时间 | 变异阶段 | 为未指定 tolerationSeconds 的 Pod 自动添加对 node.kubernetes.io/not-ready 和 node.kubernetes.io/unreachable 污点的默认容忍(5分钟) |
MutatingAdmissionWebhook | 执行自定义变异逻辑 | 变异阶段 | 允许外部 webhook 服务修改资源对象(如自动注入 sidecar 容器) |
ValidatingAdmissionWebhook | 执行自定义验证逻辑 | 验证阶段 | 允许外部 webhook 服务验证资源对象是否符合自定义规则,不符合则拒绝创建 |
ResourceQuota | 实施命名空间级别的资源配额 | 验证阶段 | 确保命名空间中的资源使用不超过 ResourceQuota 定义的总量限制 |
NodeRestriction | 限制 kubelet 可修改的资源 | 验证阶段 | 仅允许 kubelet 修改与自身相关的 Node 和 Pod 资源,增强节点级别的安全性 |
这些插件都是 Kubernetes 核心 Admission Controller 的一部分,通过在资源创建/更新过程中进行拦截处理,实现了对集群资源的精细化管理、安全控制和自动化配置。其中,Webhook 类插件(MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook)提供了扩展机制,允许用户根据业务需求自定义 admission 逻辑。
4.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/
五、实践:创建仅能管理指定命名空间的用户
5.1 目标
创建用户 zhangsan
,使其仅能在命名空间 mgb
内对 Pods 执行 get
、watch
、list
、create
等操作。
5.2 创建系统用户
# 创建用户 zhangsan
useradd zhangsan
# 设置密码
passwd zhangsan# 切换为该用户尝试访问集群(未配置认证信息时会失败)
su - zhangsan
kubectl get pods
# 输出错误:The connection to the server localhost:8080 was refused - did you specify the right host or port?
5.3 生成证书与 kubeconfig
5.3.1 准备证书工具
将证书工具 cfssl
、cfssljson
、cfssl-certinfo
上传至 /usr/local/bin
目录,并赋予执行权限:
chmod +x /usr/local/bin/cfssl*
5.3.2 生成证书签名请求(CSR)
# 创建工作目录
mkdir -p /opt/zhangsan && cd /opt/zhangsan# 创建 CSR 配置文件生成脚本
vim user-cert.sh
#######################
cat > zhangsan-csr.json <<EOF
{"CN": "zhangsan","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","ST": "BeiJing","L": "BeiJing","O": "k8s","OU": "System"}]
}
EOF
# API Server 会把客户端证书的 CN 字段作为 User,把 names.O 字段作为 Group
cd /etc/kubernetes/pki/
# 使用 CA 证书和密钥生成用户证书
cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /opt/zhangsan/zhangsan-csr.json | cfssljson -bare zhangsan
################################ 赋予脚本执行权限并执行
chmod +x user-cert.sh
./user-cert.sh
# 执行后,/etc/kubernetes/pki/ 目录中会生成 zhangsan-key.pem(私钥)、zhangsan.pem(证书)、zhangsan.csr(证书签名请求)
5.3.3 生成 kubeconfig
cd /opt/zhangsan# 创建 kubeconfig 生成脚本
vim rbac-kubeconfig.sh
APISERVER=$1
# 设置集群参数
export KUBE_APISERVER="https://$APISERVER:6443"
kubectl config set-cluster kubernetes \--certificate-authority=/etc/kubernetes/pki/ca.crt \--embed-certs=true \--server=${KUBE_APISERVER} \--kubeconfig=zhangsan.kubeconfig# 设置客户端认证参数
kubectl config set-credentials zhangsan \--client-key=/etc/kubernetes/pki/zhangsan-key.pem \--client-certificate=/etc/kubernetes/pki/zhangsan.pem \--embed-certs=true \--kubeconfig=zhangsan.kubeconfig# 设置上下文参数
kubectl config set-context kubernetes \--cluster=kubernetes \--user=zhangsan \--namespace=mgb \--kubeconfig=zhangsan.kubeconfig# 使用上下文参数
kubectl config use-context kubernetes --kubeconfig=zhangsan.kubeconfig
5.4 创建命名空间与配置 kubeconfig 上下文
# 创建命名空间 mgb
kubectl create namespace mgb# 赋予脚本执行权限并生成 kubeconfig(替换为实际的 API Server 地址)
chmod +x rbac-kubeconfig.sh
./rbac-kubeconfig.sh 192.168.10.120# 分发 kubeconfig 到用户目录
mkdir -p /home/zhangsan/.kube
cp zhangsan.kubeconfig /home/zhangsan/.kube/config
chown -R zhangsan:zhangsan /home/zhangsan/.kube/# 查看生成的 kubeconfig
cat zhangsan.kubeconfig
5.5 RBAC 授权(Role + RoleBinding)
创建 rbac.yaml
文件:
vim rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: mgbname: pod-reader
rules:
- apiGroups: [""]resources: ["pods"]verbs: ["get", "watch", "list", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: read-podsnamespace: mgb
subjects:
- kind: Username: zhangsanapiGroup: rbac.authorization.k8s.io
roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io
应用配置并检查:
kubectl apply -f rbac.yaml
# 查看命名空间 mgb 中的 Role 和 RoleBinding
kubectl get role,rolebinding -n mgb
# 输出示例:
# role.rbac.authorization.k8s.io/pod-reader 32s
# rolebinding.rbac.authorization.k8s.io/read-pods 32s
5.6 切换用户并验证权限
# 切换到 zhangsan 用户
su - zhangsan# 创建测试 Pod(应允许)
cat > pod-test.yaml <<'YAML'
apiVersion: v1
kind: Pod
metadata:name: pod-test
spec:containers:- name: nginximage: nginx
YAMLkubectl create -f pod-test.yaml
# 查看 Pod(应允许)
kubectl get pods -o wide
# 尝试访问 services(应拒绝,未授权)
kubectl get svc
# 尝试访问 default 命名空间的 Pods(应拒绝,权限限制在 mgb 命名空间)
kubectl get pods -n default
# 输出错误:Error from server (Forbidden): pods is forbidden: User "zhangsan" cannot list resource "pods" in API group "" in the namespace "default"
5.6.1 问题补充
当配置完了zhangsan的权限时,如果发现还是不能使用该账号来进行相应权限的操作时,可能会看到一下报错
这可能是因为$KUBECONFIG
被强制覆盖为/etc/kubernetes/admin.conf
无法找到正确的路径,使用一下命令修复:
# 在 zhangsan 用户的 shell 配置中清除该变量(如 ~/.bashrc)
echo "unset KUBECONFIG" >> ~/.bashrc
source ~/.bashrc # 生效配置
kubectl config view
再次验证,发现问题解决
5.7 管理员侧验证
# 管理员查看所有命名空间的 Pods
kubectl get pods --all-namespaces -o wide
# 可见 RoleBinding 生效,用户仅能管理指定命名空间的资源
5.8 可选:授予命名空间管理员权限
若需要让 zhangsan
在 mgb
命名空间内具备管理员能力,可执行以下命令:
kubectl create rolebinding zhangsan-admin-binding \--clusterrole=admin \--user=zhangsan \--namespace=mgb
六、官方文档与参考
- RBAC 参考:https://kubernetes.io/docs/reference/access-authn-authz/rbac/
- Admission Controllers:https://kubernetes.io/zh/docs/reference/access-authn-authz/admission-controllers/
总结
Kubernetes 安全机制是一个多层次、全方位的防护体系,其核心目标是在复杂的分布式环境中实现 “身份可辨、权限可控、操作可审、资源可隔、数据可保”。通过本文的梳理,可将其核心逻辑归纳为以下几点:
- 分层防御,环环相扣:从身份认证(确认 “谁在访问”)到授权(控制 “能做什么”),再到准入控制(拦截 “非法操作”),形成了 API 请求的三道核心关卡;结合 Pod 安全配置(限制容器权限)、网络策略(隔离通信范围)和 Secret 加密(保护敏感数据),构建了从访问入口到运行环境的全链条防护。
- 最小权限原则贯穿始终:无论是 RBAC 授权中对角色权限的精细定义,还是 Pod 安全标准中对 root 权限、特权容器的严格限制,抑或是 Node 授权对 kubelet 操作范围的约束,均体现了 “仅赋予必要权限” 的安全理念,最大限度降低风险面。
- 灵活性与扩展性并重:内置机制(如 RBAC、PSS)满足基础安全需求,而动态准入控制器(Webhook)、外部认证源(OIDC)、第三方工具(Vault、OPA)则支持企业根据业务场景定制安全策略,适应复杂的生产环境。
- 实践落地需结合场景:生产环境中需优先启用核心机制(如双向 TLS 认证、etcd 静态加密、网络策略),并针对不同应用场景(如普通业务 Pod、系统组件、多团队协作)调整安全级别,平衡安全性与可用性。
总之,Kubernetes 安全是一个持续迭代的过程,需要结合技术演进(如 PSP 到 PSS 的升级)、业务变化和攻防对抗经验,不断优化防护策略,才能在云原生时代构建真正可靠的集群安全屏障。