Skip to content

Kubernetes RBAC 与安全 ​

安全链路 ​

请求依次经过认证、鉴权和准入:

  1. 认证确认请求者身份,如 OIDC 用户、客户端证书、ServiceAccount Token。
  2. 鉴权判断身份能否执行 verb,常用 RBAC。
  3. 准入在持久化前修改或校验对象,如 Pod Security Admission、CEL Policy 或 Webhook。
  4. API Server 把对象写入 etcd,审计策略可记录请求元数据或内容。

RBAC 允许某操作不代表准入一定接受;准入接受也不能替代 RBAC。

RBAC 对象 ​

对象作用域作用
Role命名空间定义该命名空间内权限
ClusterRole集群定义集群资源或可复用于各命名空间的权限
RoleBinding命名空间将 Role/ClusterRole 授给此命名空间中的主体
ClusterRoleBinding集群将 ClusterRole 授给主体,作用于全局

RBAC 是纯允许模型,没有 Deny;一个主体获得的所有 Binding 权限取并集。

最小权限示例 ​

让 demo 命名空间的 web ServiceAccount 只读一个 ConfigMap:

yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: web
  namespace: demo
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: web-config-reader
  namespace: demo
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["web-runtime-config"]
    verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: web-config-reader
  namespace: demo
subjects:
  - kind: ServiceAccount
    name: web
    namespace: demo
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: web-config-reader

resourceNames 对 create 无法按尚不存在的名称限制;对 list/watch 也有额外 field selector 约束,不能误当通用名称 ACL。

验证:

bash
kubectl auth can-i get configmap/web-runtime-config \
  --as=system:serviceaccount:demo:web -n demo
kubectl auth can-i list secrets \
  --as=system:serviceaccount:demo:web -n demo

高风险权限 ​

以下权限可能形成提权或远程执行路径,应单独审批:

  • create/update pods:可挂载 ServiceAccount、Secret、hostPath 或调度到敏感节点(取决于准入策略)。
  • pods/exec、pods/attach、pods/portforward:可执行代码或访问内部网络。
  • get/list/watch secrets:可直接获取命名空间凭据。
  • bind、escalate:可绑定或创建超出自身权限的 RBAC。
  • impersonate:可模拟其他用户、组或 ServiceAccount。
  • nodes/proxy:可能绕过 kubelet 细粒度 API 授权边界。
  • CSR approve、Webhook/CRD/APIService 管理、持久卷和准入策略管理。

避免通配 apiGroups: ["*"]、resources: ["*"]、verbs: ["*"]。定期清理无主体 Binding、长期 Token 和临时管理员权限。

Pod 安全上下文 ​

yaml
spec:
  automountServiceAccountToken: false
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: web
      image: registry.example.com/web@sha256:<digest>
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]
      volumeMounts:
        - name: tmp
          mountPath: /tmp
  volumes:
    - name: tmp
      emptyDir: {}

镜像必须支持非 root 和只读根文件系统。显式 UID 可提升确定性,但要与镜像和 Volume 权限匹配。避免 privileged、hostPID、hostIPC、hostNetwork、hostPath、危险 capabilities 和不受控设备。

v1.36 的 Pod User Namespace 已进入 Stable,但是否可用取决于 Linux、容器运行时和 Volume 类型;它是纵深防御,不替代 seccomp、MAC、capabilities 和节点隔离。

Pod Security Admission ​

命名空间标签可按 privileged、baseline、restricted 执行检查:

bash
kubectl label namespace demo \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/audit-version=v1.36 \
  pod-security.kubernetes.io/warn-version=v1.36

先用 audit/warn 发现不兼容工作负载,修复后再增加 pod-security.kubernetes.io/enforce=restricted。策略版本固定可避免升级时无意改变规则,但也必须纳入升级计划。系统命名空间按组件需求单独评估,不能一刀切。

Secret 与工作负载身份 ​

  • API Server 启用 etcd 静态数据加密并演练密钥轮换。
  • 使用短期、受众受限的 projected ServiceAccount Token。
  • 云访问优先 Workload Identity,不给 Pod 分发长期 Access Key。
  • Secret Store CSI/外部控制器也需要最小云权限、轮换与审计。
  • 禁止在 Git、镜像层、环境日志、命令参数和指标标签中放 Secret。
  • 能读取 Pod 的用户可能通过 exec 或应用漏洞读取其挂载的 Secret,因此权限分析要看完整路径。

网络、节点与供应链 ​

  • 命名空间使用默认拒绝 NetworkPolicy,再显式允许 DNS 和业务路径。
  • 控制面/etcd 不暴露公网;API 接入使用私网、身份代理或严格源限制。
  • 节点最小化软件,及时修补 OS、内核、运行时和 kubelet;禁止业务 SSH 常态化。
  • 固定镜像 digest,扫描 OS/语言依赖和恶意内容,生成 SBOM并验证签名/来源证明。
  • 限制允许的 Registry、特权配置和 Host Namespace;使用准入策略阻止不合规清单。
  • 第三方 Operator 常有集群级权限,安装前审查 RBAC、镜像、Webhook 和升级维护状态。

审计与应急 ​

审计策略要在可见性、敏感数据和成本之间平衡。至少关注:

  • RBAC、Secret、ServiceAccount、Webhook、CRD、Node、Namespace 的写操作。
  • exec/attach/port-forward/proxy 请求。
  • 拒绝请求、身份模拟、匿名访问和异常来源。
  • 审计日志完整性、保留周期、访问权限和告警。

疑似凭据泄漏时:立即吊销/轮换,检查相应身份审计轨迹,隔离工作负载并保存取证数据。只删除 Pod 不能使已泄漏 Token 失效。

安全基线检查 ​

bash
kubectl auth can-i --list -n demo
kubectl get rolebindings,clusterrolebindings -A
kubectl get validatingadmissionpolicies,validatingwebhookconfigurations
kubectl get namespaces --show-labels
kubectl get pods -A -o json | jq -r \
  '.items[] | select(.spec.hostNetwork == true or .spec.hostPID == true) | [.metadata.namespace,.metadata.name] | @tsv'

生产目标是降低攻击面和爆炸半径,而不是只让合规扫描变绿。详细基准还应结合托管平台指南和 Kubernetes Security Checklist。

继续阅读