RBAC与安全策略
1. 概念
RBAC(Role-Based Access Control):谁(subject)能对什么(resource)做什么(verb)。K8s 默认开启。
ServiceAccount ─┐
User ├─→ RoleBinding ─→ Role
Group ─┘ (verbs + resources)
ClusterRoleBinding ─→ ClusterRole
| 概念 | 范围 | 资源 |
|---|---|---|
| Role | 单 namespace | namespace 内资源 |
| ClusterRole | 集群级 | 所有 ns + cluster 资源(Nodes、PV) |
| RoleBinding | 单 ns | 把 Role/ClusterRole 绑给主体 |
| ClusterRoleBinding | 集群级 | 把 ClusterRole 绑给主体 |
2. ServiceAccount
Pod 默认有个 ServiceAccount(default),用来调 K8s API。前端业务 Pod 一般不需要调 API。
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-frontend
namespace: frontend
automountServiceAccountToken: false # 不需要调 K8s API 的 Pod 关掉
# Pod 使用
spec:
serviceAccountName: my-frontend
3. Role 示例
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: frontend
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list"]
verbs:get、list、watch、create、update、patch、delete、deletecollection、*。
4. RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: alice-reads
namespace: frontend
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
5. ClusterRole 示例
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: dev-access
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch"]
通过 RoleBinding 绑到特定 ns(生效于该 ns),通过 ClusterRoleBinding 绑全集群。
6. 测试权限
# 当前用户
kubectl auth can-i create pods -n frontend
# yes / no
# 假装是别的 SA
kubectl auth can-i list secrets -n frontend \
--as=system:serviceaccount:frontend:my-frontend
7. CI/CD 用 ServiceAccount
最佳实践:CI 不用集群管理员账号,用最小权限 SA:
apiVersion: v1
kind: ServiceAccount
metadata:
name: ci-deployer
namespace: frontend
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: ci-deployer
namespace: frontend
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "patch", "update"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ci-deployer
namespace: frontend
subjects:
- kind: ServiceAccount
name: ci-deployer
namespace: frontend
roleRef:
kind: Role
name: ci-deployer
apiGroup: rbac.authorization.k8s.io
CI 拿这个 SA 的 token 做 kubectl 操作。
8. Pod Security Admission(PSA)
K8s 1.25+ 替代 PodSecurityPolicy。三档:
| 级别 | 含义 |
|---|---|
| privileged | 无限制 |
| baseline | 最小限制(禁特权、host 网络) |
| restricted | 严格(必须非 root、drop ALL cap) |
启用:
apiVersion: v1
kind: Namespace
metadata:
name: frontend
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
enforce = 拒绝;audit = 仅记录;warn = 用户警告。
9. NetworkPolicy(Pod 防火墙)
详见 Service / Ingress 章。生产强制:
# 默认拒绝所有
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: frontend
spec:
podSelector: {}
policyTypes: [Ingress, Egress]
按需打开。
10. 安全审计
API audit log 记录所有 API 调用:
# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
resources:
- group: ""
resources: ["secrets"]
- level: RequestResponse
verbs: ["create", "update", "delete"]
resources:
- group: ""
resources: ["pods", "configmaps"]
apiserver 启动加 --audit-policy-file=...。云托管集群(ACK / EKS)控制台开启。
11. 常见反模式
- CI 用 cluster-admin:泄露 = 全集群沦陷
- 不限 secret 访问:业务 Pod 能读所有 secret
- 业务 Pod 用 default SA:默认权限足够获取大量信息
automountServiceAccountToken: true没必要:不调 K8s API 的 Pod 应该关掉- 不用 NetworkPolicy:横向移动毫无障碍
- 不开 PSA:privileged 容器随意创建
- RBAC 用 ClusterRoleBinding:本应 ns 范围用了集群范围