跳到主要内容

RBAC与安全策略

1. 概念

RBAC(Role-Based Access Control):谁(subject)能对什么(resource)做什么(verb)。K8s 默认开启。

ServiceAccount ─┐
User ├─→ RoleBinding ─→ Role
Group ─┘ (verbs + resources)
ClusterRoleBinding ─→ ClusterRole
概念范围资源
Role单 namespacenamespace 内资源
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:getlistwatchcreateupdatepatchdeletedeletecollection*

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 范围用了集群范围

12. 延伸阅读