Kubernetes 安全体系深度解析:RBAC、网络安全与密钥管理

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
# Role:命名空间级别
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
# ClusterRole:集群级别(或跨命名空间复用)
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
# RoleBinding:在特定命名空间绑定
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 # 或 ClusterRole
name: pod-manager
apiGroup: rbac.authorization.k8s.io
1
2
3
4
5
6
7
8
9
10
11
12
13
# ClusterRoleBinding:集群范围绑定
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
# 查看内置 ClusterRole
kubectl get clusterroles | grep -v system:

# 常用内置角色
cluster-admin # 超级管理员(慎用)
admin # 命名空间管理员
edit # 可编辑大多数资源
view # 只读

2.5 RBAC 最小权限原则

1
2
3
4
5
6
7
# 检查用户/SA 的权限
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
# 创建 ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: default
annotations:
# AWS IRSA(IAM Roles for Service Accounts)
eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/my-role

---
# Pod 使用 ServiceAccount
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 # 1 小时过期
audience: my-service # 受众限制

3.3 Workload Identity(云厂商集成)

1
2
3
4
5
6
7
8
9
10
11
12
# AWS EKS IRSA
apiVersion: v1
kind: ServiceAccount
metadata:
name: s3-reader
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789:role/s3-reader-role

# GKE Workload Identity
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
# Opaque(通用)
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
username: YWRtaW4= # base64 编码
password: cGFzc3dvcmQ=
stringData: # 明文(自动 base64)
api-key: "my-secret-key"

# TLS 证书
type: kubernetes.io/tls
data:
tls.crt: <base64>
tls.key: <base64>

# Docker 镜像拉取凭证
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64>

# ServiceAccount Token
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
# /etc/kubernetes/encryption-config.yaml
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
# apiserver 启动参数
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml

# 重新加密现有 Secret
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
# External Secrets Operator
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
# Namespace 级别强制执行
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
# enforce:违规 Pod 被拒绝
pod-security.kubernetes.io/enforce: restricted
# warn:违规时警告但允许
pod-security.kubernetes.io/warn: restricted
# audit:违规时记录审计日志
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
# 不允许:
# privileged: true
# hostPID: true
# hostNetwork: true
# hostPath volumes

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
# 只允许 frontend 访问 backend 的 8080 端口
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
# 允许 DNS 查询
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53

7. 镜像安全

7.1 镜像扫描

1
2
3
4
5
# 使用 Trivy 扫描镜像
trivy image nginx:latest

# 集成到 CI/CD
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
# 使用 Kyverno 策略
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
# /etc/kubernetes/audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# 记录 Secret 的所有操作
- level: Metadata
resources:
- group: ""
resources: ["secrets"]

# 记录 Pod exec 操作
- 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
# apiserver 启动参数
--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
# Falco 规则示例
- 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
# 1. API Server 安全
✓ 禁用匿名访问:--anonymous-auth=false
✓ 启用 RBAC:--authorization-mode=Node,RBAC
✓ 启用审计日志
✓ 限制 API Server 访问 IP

# 2. etcd 安全
✓ 启用 TLS 加密通信
✓ 启用静态数据加密
✓ 限制 etcd 访问(只允许 apiserver)
✓ 定期备份

# 3. 节点安全
✓ 禁用 kubelet 匿名访问
✓ 启用节点授权
✓ 定期更新节点 OS 和 K8s 版本

# 4. 工作负载安全
✓ 使用 Pod Security Standards(restricted)
✓ 不使用 root 用户运行容器
✓ 只读根文件系统
✓ 删除不必要的 Linux Capabilities
✓ 使用 NetworkPolicy 隔离

# 5. 供应链安全
✓ 使用私有镜像仓库
✓ 镜像扫描(Trivy)
✓ 镜像签名验证(Cosign)
✓ 使用 Distroless 或 Alpine 基础镜像

11. 总结

Kubernetes 安全是一个纵深防御体系:

  1. 认证:证书、Token、OIDC 多种方式
  2. 授权:RBAC 最小权限原则
  3. 准入控制:Webhook 动态策略
  4. Pod 安全:非 root、只读文件系统、删除 Capabilities
  5. 网络隔离:NetworkPolicy 零信任
  6. Secret 管理:etcd 加密 + 外部 Secret 管理
  7. 运行时安全:Falco 实时检测
  8. 审计日志:完整的操作记录

Kubernetes 安全体系深度解析:RBAC、网络安全与密钥管理
https://k8s.chucz.asia/Kubernetes安全体系深度解析/
作者
K8s Engineer
发布于
2026年1月19日
许可协议