Kubernetes 安全体系深度解析:RBAC、网络安全与密钥管理 1. Kubernetes 安全威胁模型 1 2 3 4 5 6 7 8 9 10 11 12 外部攻击面: ├── API Server 暴露(未认证访问) ├── etcd 直接暴露 ├── kubelet API 暴露 └── Dashboard 未授权访问 内部攻击面: ├── 容器逃逸(特权容器) ├── 横向移动(Pod 间访问) ├── 权限提升(RBAC 配置不当) ├── Secret 泄露 └── 供应链攻击(恶意镜像)
2. RBAC 权限模型 2.1 核心概念 1 2 3 4 Subject(主体) → RoleBinding → Role(权限) ├── User ├── 资源类型 ├── Group ├── 操作动词 └── ServiceAccount └── 命名空间范围
2.2 Role vs ClusterRole 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: production name: pod-manager rules: - apiGroups: ["" ] resources: ["pods" , "pods/log" , "pods/exec" ] verbs: ["get" , "list" , "watch" , "create" , "delete" ]- apiGroups: ["apps" ] resources: ["deployments" ] verbs: ["get" , "list" , "watch" , "update" , "patch" ]- apiGroups: ["" ] resources: ["configmaps" ] resourceNames: ["app-config" ] verbs: ["get" ]
1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: node-reader rules: - apiGroups: ["" ] resources: ["nodes" , "nodes/status" ] verbs: ["get" , "list" , "watch" ]- apiGroups: ["metrics.k8s.io" ] resources: ["nodes" , "pods" ] verbs: ["get" , "list" ]
2.3 RoleBinding vs ClusterRoleBinding 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: dev-pod-manager namespace: production subjects: - kind: User name: alice apiGroup: rbac.authorization.k8s.io - kind: Group name: dev-team apiGroup: rbac.authorization.k8s.io - kind: ServiceAccount name: ci-bot namespace: ci-system roleRef: kind: Role name: pod-manager apiGroup: rbac.authorization.k8s.io
1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: monitoring-reader subjects: - kind: ServiceAccount name: prometheus namespace: monitoring roleRef: kind: ClusterRole name: node-reader apiGroup: rbac.authorization.k8s.io
2.4 内置 ClusterRole 1 2 3 4 5 6 7 8 kubectl get clusterroles | grep -v system: cluster-admin admin edit view
2.5 RBAC 最小权限原则 1 2 3 4 5 6 7 kubectl auth can-i create pods --as=alice kubectl auth can-i create pods --as=alice -n production kubectl auth can-i '*' '*' --as=alice kubectl auth can-i --list --as=alice -n production
3. ServiceAccount 3.1 ServiceAccount 基础 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 apiVersion: v1 kind: ServiceAccount metadata: name: my-app-sa namespace: default annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/my-role --- spec: serviceAccountName: my-app-sa automountServiceAccountToken: false
3.2 Token 投影(Projected Token) Kubernetes 1.20+ 使用有时效的投影 Token:
1 2 3 4 5 6 7 8 volumes: - name: token projected: sources: - serviceAccountToken: path: token expirationSeconds: 3600 audience: my-service
3.3 Workload Identity(云厂商集成) 1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: v1 kind: ServiceAccount metadata: name: s3-reader annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/s3-reader-role metadata: annotations: iam.gke.io/gcp-service-account: my-sa@project.iam.gserviceaccount.com
4. Secret 管理 4.1 Secret 类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 apiVersion: v1 kind: Secret metadata: name: my-secret type: Opaque data: username: YWRtaW4= password: cGFzc3dvcmQ= stringData: api-key: "my-secret-key" type: kubernetes.io/tls data: tls.crt: <base64> tls.key: <base64> type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: <base64> type: kubernetes.io/service-account-token
4.2 Secret 的安全问题 1 2 3 4 5 6 默认情况下,Secret 在 etcd 中是 base64 编码(非加密!) 风险: 1. etcd 数据泄露 → 所有 Secret 暴露 2. 有 get secret 权限的用户可以读取所有 Secret 3. 节点上的 Secret 以明文存储在 tmpfs
4.3 etcd 静态加密 1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration resources: - resources: - secrets - configmaps providers: - aescbc: keys: - name: key1 secret: <base64-encoded-32-byte-key> - identity: {}
1 2 3 4 5 --encryption-provider-config=/etc/kubernetes/encryption-config.yaml kubectl get secrets --all-namespaces -o json | kubectl replace -f -
4.4 外部 Secret 管理(推荐生产使用) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: my-secret spec: refreshInterval: 1h secretStoreRef: name: aws-secretsmanager kind: ClusterSecretStore target: name: my-k8s-secret data: - secretKey: password remoteRef: key: production/myapp/db property: password
支持的后端:
AWS Secrets Manager / Parameter Store
HashiCorp Vault
GCP Secret Manager
Azure Key Vault
5. Pod 安全标准(Pod Security Standards) 5.1 三个安全级别 1 2 3 4 5 6 7 8 9 10 11 12 apiVersion: v1 kind: Namespace metadata: name: production labels: pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/warn: restricted pod-security.kubernetes.io/audit: restricted
5.2 Restricted 级别要求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsNonRoot: true capabilities: drop: - ALL
6. 网络安全(NetworkPolicy) 6.1 默认拒绝所有流量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress namespace: production spec: podSelector: {} policyTypes: - Ingress --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-egress namespace: production spec: podSelector: {} policyTypes: - Egress
6.2 精细化访问控制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: backend-policy namespace: production spec: podSelector: matchLabels: app: backend policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: app: frontend ports: - protocol: TCP port: 8080 egress: - to: - podSelector: matchLabels: app: database ports: - protocol: TCP port: 5432 - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system ports: - protocol: UDP port: 53
7. 镜像安全 7.1 镜像扫描 1 2 3 4 5 trivy image nginx:latest trivy image --exit-code 1 --severity HIGH,CRITICAL my-app:v1
7.2 镜像签名验证(Cosign) 1 2 3 4 5 cosign sign --key cosign.key my-registry/my-app:v1 cosign verify --key cosign.pub my-registry/my-app:v1
7.3 准入控制强制验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: require-image-signature spec: validationFailureAction: Enforce rules: - name: check-image-signature match: resources: kinds: - Pod verifyImages: - imageReferences: - "my-registry/*" attestors: - entries: - keys: publicKeys: |- -----BEGIN PUBLIC KEY----- ... -----END PUBLIC KEY-----
8. 审计日志(Audit Logging) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 apiVersion: audit.k8s.io/v1 kind: Policy rules: - level: Metadata resources: - group: "" resources: ["secrets" ]- level: Request verbs: ["create" ] resources: - group: "" resources: ["pods/exec" , "pods/portforward" ]- level: None users: ["system:kube-proxy" ] verbs: ["watch" ] resources: - group: "" resources: ["endpoints" , "services" ]- level: Metadata
1 2 3 4 5 6 --audit-log-path=/var/log/kubernetes/audit.log --audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-log-maxage=30 --audit-log-maxbackup=10 --audit-log-maxsize=100
9. 运行时安全(Falco) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 - rule: Terminal shell in container desc: 检测容器内的 shell 会话 condition: > spawned_process and container and shell_procs and proc.tty != 0 and container_entrypoint output: > A shell was spawned in a container with an attached terminal (user=%user.name container=%container.name image=%container.image.repository) priority: WARNING - rule: Write below etc desc: 检测写入 /etc 目录 condition: > open_write and container and fd.name startswith /etc output: > File opened for writing below /etc (user=%user.name command=%proc.cmdline file=%fd.name) priority: ERROR
10. 安全加固 Checklist 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ✓ 禁用匿名访问:--anonymous-auth=false ✓ 启用 RBAC:--authorization-mode=Node,RBAC ✓ 启用审计日志 ✓ 限制 API Server 访问 IP ✓ 启用 TLS 加密通信 ✓ 启用静态数据加密 ✓ 限制 etcd 访问(只允许 apiserver) ✓ 定期备份 ✓ 禁用 kubelet 匿名访问 ✓ 启用节点授权 ✓ 定期更新节点 OS 和 K8s 版本 ✓ 使用 Pod Security Standards(restricted) ✓ 不使用 root 用户运行容器 ✓ 只读根文件系统 ✓ 删除不必要的 Linux Capabilities ✓ 使用 NetworkPolicy 隔离 ✓ 使用私有镜像仓库 ✓ 镜像扫描(Trivy) ✓ 镜像签名验证(Cosign) ✓ 使用 Distroless 或 Alpine 基础镜像
11. 总结 Kubernetes 安全是一个纵深防御体系:
认证 :证书、Token、OIDC 多种方式
授权 :RBAC 最小权限原则
准入控制 :Webhook 动态策略
Pod 安全 :非 root、只读文件系统、删除 Capabilities
网络隔离 :NetworkPolicy 零信任
Secret 管理 :etcd 加密 + 外部 Secret 管理
运行时安全 :Falco 实时检测
审计日志 :完整的操作记录