Kubernetes 的安全模型遵循纵深防御原则——从 API 访问控制到 Pod 运行时隔离,从网络策略到密钥管理,每一层都有独立的安全机制。即使某一层被突破,其他层仍然提供保护。
本章从 RBAC 权限模型出发,逐步深入 ServiceAccount 身份管理、Pod 安全标准、容器安全上下文、网络隔离和密钥管理,构建完整的 Kubernetes 安全知识体系。
一、Kubernetes 安全模型概览
二、RBAC:基于角色的访问控制
RBAC 是 Kubernetes 的核心授权机制,控制”谁可以对什么资源做什么操作”。
2.1 RBAC 四个核心对象
| 对象 | 作用范围 | 说明 |
|---|---|---|
| Role | Namespace | 定义 Namespace 内的权限规则 |
| ClusterRole | 集群 | 定义集群范围的权限规则 |
| RoleBinding | Namespace | 将 Subject 绑定到 Role/ClusterRole(Namespace 内生效) |
| ClusterRoleBinding | 集群 | 将 Subject 绑定到 ClusterRole(集群范围生效) |
2.2 Role 与 ClusterRole
Role:Namespace 内的权限
apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: pod-reader namespace: productionrules: - apiGroups: [""] resources: ["pods", "pods/log"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["pods/exec"] verbs: ["create"] # 允许 exec 进入容器 - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list"] resourceNames: ["nginx"] # 限制为特定资源名ClusterRole:集群范围的权限
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: node-readerrules: - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["namespaces"] verbs: ["get", "list"]2.3 RoleBinding 与 ClusterRoleBinding
RoleBinding:将用户绑定到 Role(Namespace 内生效)
apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata: name: jane-pod-reader namespace: productionsubjects: - kind: User name: jane apiGroup: rbac.authorization.k8s.ioroleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.ioClusterRoleBinding:将用户绑定到 ClusterRole(集群范围生效)
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: admin-bindingsubjects: - kind: User name: admin apiGroup: rbac.authorization.k8s.ioroleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io2.4 常见权限模式
| 场景 | Role | Binding | 说明 |
|---|---|---|---|
| 开发者查看 Pod | Role (pod-reader) | RoleBinding | 只能查看指定 Namespace 的 Pod |
| CI/CD 部署应用 | Role (deployer) | RoleBinding | 可以管理 Deployment/Service |
| 集群只读用户 | ClusterRole (view) | ClusterRoleBinding | 可以查看所有 Namespace 的资源 |
| 集群管理员 | ClusterRole (cluster-admin) | ClusterRoleBinding | 完全控制 |
2.5 RBAC 排查
# 检查用户是否有权限执行操作kubectl auth can-i get pods --as=jane -n productionkubectl auth can-i delete deployments --as=jane -n production
# 检查 ServiceAccount 的权限kubectl auth can-i list secrets --as=system:serviceaccount:default:my-sa
# 查看 RoleBinding 详情kubectl describe rolebinding jane-pod-reader -n production
# 查看 ClusterRole 的规则kubectl describe clusterrole cluster-admin三、ServiceAccount:Pod 的身份
每个 Pod 都有一个 ServiceAccount,用于与 API Server 通信。ServiceAccount 是 RBAC 的 Subject 之一。
3.1 默认 ServiceAccount
每个 Namespace 自动创建一个 default ServiceAccount:
kubectl get sa -n production# NAME SECRETS AGE# default 0 30dPod 未指定 ServiceAccount 时,自动使用 default。
3.2 创建专用 ServiceAccount
apiVersion: v1kind: ServiceAccountmetadata: name: api-reader namespace: productionautomountServiceAccountToken: true # 自动挂载 API Token# Pod 使用专用 ServiceAccountspec: serviceAccountName: api-reader containers: - name: my-app image: my-app:v13.3 Token 挂载机制
Kubernetes 1.24+ 使用 TokenRequest API 生成短期 JWT Token,自动挂载到 Pod:
/var/run/secrets/kubernetes.io/serviceaccount/ ├── ca.crt # API Server CA 证书 ├── namespace # Pod 所在 Namespace └── token # 短期 JWT Token(默认 1 小时有效期)Token 自动轮换——kubelet 在 Token 过期前自动向 API Server 请求新 Token,Pod 无感知。
Kubernetes 1.24 之前,ServiceAccount 自动创建长期 Secret Token。1.24+ 不再自动创建,改用 TokenRequest API 生成短期 Token。如果需要长期 Token(如 CI/CD 场景),需要手动创建 Secret 类型为 kubernetes.io/service-account-token。
四、Pod 安全标准与 Pod Security Admission
Pod 安全标准定义了三种安全级别,Pod Security Admission 在 Namespace 级别强制执行。
4.1 三种安全级别
| 级别 | 说明 | 典型限制 |
|---|---|---|
| Privileged | 不受限制,完全特权 | 允许特权容器、hostPath、hostNetwork |
| Baseline | 最小限制,阻止已知提权 | 禁止特权容器、hostPID/hostIPC、新增能力 |
| Restricted | 严格限制,安全最佳实践 | 禁止所有特权、必须以非 root 运行、禁止新增能力 |
4.2 配置 Pod Security Admission
apiVersion: v1kind: Namespacemetadata: name: production labels: pod-security.kubernetes.io/enforce: restricted # 强制执行 pod-security.kubernetes.io/audit: restricted # 审计日志 pod-security.kubernetes.io/warn: restricted # 警告提示 pod-security.kubernetes.io/enforce-version: v1.29 # 使用 v1.29 版本标准| 模式 | 说明 |
|---|---|
| enforce | 违反标准的 Pod 被拒绝创建 |
| audit | 违反标准的 Pod 允许创建,但记录审计事件 |
| warn | 违反标准的 Pod 允许创建,但 kubectl 输出警告 |
4.3 Restricted 级别的 Pod 配置
apiVersion: v1kind: Podmetadata: name: secure-appspec: securityContext: runAsNonRoot: true # 必须以非 root 运行 runAsUser: 1000 fsGroup: 2000 seccompProfile: type: RuntimeDefault # 使用默认 seccomp 配置 containers: - name: app image: my-app:v1 securityContext: allowPrivilegeEscalation: false # 禁止提权 readOnlyRootFilesystem: true # 只读根文件系统 capabilities: drop: ["ALL"] # 删除所有 Linux 能力 volumeMounts: - name: tmp mountPath: /tmp volumes: - name: tmp emptyDir: {} # 临时目录用于写入五、SecurityContext:容器安全上下文
SecurityContext 定义 Pod 和容器的安全配置,控制容器的权限和隔离级别。
5.1 Pod 级别 vs 容器级别
| 配置 | Pod 级别 | 容器级别 | 说明 |
|---|---|---|---|
| runAsUser | 可 | 可(覆盖 Pod 级别) | 运行容器的 UID |
| runAsGroup | 可 | 可 | 运行容器的 GID |
| fsGroup | 可 | 否 | Volume 的 GID |
| runAsNonRoot | 可 | 可 | 是否禁止 root 运行 |
| seccompProfile | 可 | 可 | seccomp 配置 |
| capabilities | 否 | 可 | Linux 能力管理 |
| privileged | 否 | 可 | 是否为特权容器 |
| readOnlyRootFilesystem | 否 | 可 | 根文件系统是否只读 |
| allowPrivilegeEscalation | 否 | 可 | 是否允许提权(setuid) |
5.2 Linux Capabilities
Linux 将 root 权限拆分为细粒度的能力(Capabilities)。Kubernetes 允许精确控制容器拥有的能力:
securityContext: capabilities: add: ["NET_BIND_SERVICE"] # 允许绑定 1024 以下端口 drop: ["ALL"] # 删除所有其他能力| 常见能力 | 说明 | 风险等级 |
|---|---|---|
| NET_BIND_SERVICE | 绑定 1024 以下端口 | 低 |
| CHOWN | 修改文件所有者 | 中 |
| NET_RAW | 使用原始套接字(ping 等) | 中 |
| SYS_ADMIN | 系统管理操作 | 高 |
| SYS_PTRACE | 追踪进程 | 高 |
privileged: true 等同于拥有所有 Linux 能力,容器几乎可以访问宿主机的所有设备。仅在系统组件(如 CNI 插件、CSI 插件)中使用。
六、NetworkPolicy:网络隔离
NetworkPolicy 在 L3/L4 层控制 Pod 间的网络流量。默认情况下,所有 Pod 可以互相通信——NetworkPolicy 实现白名单机制,只允许显式声明的流量。
6.1 默认拒绝所有入站
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: deny-all-ingress namespace: productionspec: podSelector: {} # 空选择器 = Namespace 内所有 Pod policyTypes: - Ingress # 拒绝所有入站6.2 分层网络策略
# API 层策略:只允许 Frontend 访问apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: api-policy namespace: productionspec: podSelector: matchLabels: app: api policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: app: web ports: - port: 8080 egress: - to: - podSelector: matchLabels: app: mysql ports: - port: 3306 - to: # 允许 DNS 解析 - namespaceSelector: {} ports: - port: 53 protocol: UDP6.3 跨 Namespace 策略
# 允许 monitoring Namespace 的 Pod 访问 metricsingress: - from: - namespaceSelector: matchLabels: name: monitoring podSelector: matchLabels: app: prometheus ports: - port: 9090namespaceSelector 和 podSelector 在同一个 from 列表项中是 AND 关系——必须同时满足。不同列表项之间是 OR 关系。
七、Secret 加密与外部密钥管理
7.1 etcd 静态加密
默认情况下,Secret 在 etcd 中以 Base64 明文存储。启用加密后,Secret 写入 etcd 前会被加密:
# EncryptionConfigurationapiVersion: apiserver.config.k8s.io/v1kind: EncryptionConfigurationresources: - resources: - secrets providers: - aescbc: keys: - name: key1 secret: <base64-encoded-32-byte-key> - identity: {} # 回退到明文(用于读取未加密的旧数据)# 配置 API Server 使用加密配置kube-apiserver --encryption-provider-config=/etc/kubernetes/encryption-config.yaml7.2 External Secrets Operator
将密钥管理委托给外部系统(如 HashiCorp Vault、AWS Secrets Manager),通过 External Secrets Operator 同步到 Kubernetes Secret:
# ExternalSecret 示例apiVersion: external-secrets.io/v1beta1kind: ExternalSecretmetadata: name: db-credentialsspec: refreshInterval: 1h secretStoreRef: name: vault-backend kind: ClusterSecretStore target: name: db-credentials # 同步创建的 Kubernetes Secret 名称 data: - secretKey: password # Kubernetes Secret 中的键 remoteRef: key: secret/data/db # Vault 中的路径 property: password # Vault 中的字段7.3 Sealed Secrets
Sealed Secrets 允许将加密的 Secret 安全地提交到 Git:
# 安装 kubeseal CLIkubeseal --format yaml < secret.yaml > sealed-secret.yaml
# sealed-secret.yaml 可以安全提交到 Git# 集群中的 Sealed Secrets Controller 解密并创建真正的 Secretkubectl apply -f sealed-secret.yaml八、安全最佳实践清单
| 维度 | 最佳实践 | 优先级 |
|---|---|---|
| RBAC | 最小权限原则,避免使用 cluster-admin | 高 |
| RBAC | 定期审计 RoleBinding/ClusterRoleBinding | 高 |
| ServiceAccount | 为每个应用创建专用 SA,不使用 default | 高 |
| Pod 安全 | Namespace 设置 restricted 安全标准 | 高 |
| Pod 安全 | 容器以非 root 运行,删除所有能力 | 高 |
| Pod 安全 | 根文件系统设为只读 | 中 |
| 网络隔离 | Namespace 设置默认拒绝 NetworkPolicy | 高 |
| 网络隔离 | 分层网络策略,只允许必要的流量 | 中 |
| 密钥管理 | 启用 etcd 静态加密 | 高 |
| 密钥管理 | 使用 External Secrets 对接 Vault | 中 |
| 密钥管理 | 不将 Secret YAML 提交到 Git | 高 |
| 镜像安全 | 使用最小基础镜像(distroless/alpine) | 中 |
| 镜像安全 | 定期扫描镜像漏洞(Trivy/Grype) | 中 |
| 审计 | 启用 API Server 审计日志 | 中 |
总结
| 安全层 | 核心机制 | 关键原则 |
|---|---|---|
| API 访问控制 | 认证 + RBAC + 准入控制 | 最小权限 |
| Pod 运行时安全 | Pod Security Admission + SecurityContext | 纵深防御 |
| 网络隔离 | NetworkPolicy | 白名单机制 |
| 密钥管理 | etcd 加密 + External Secrets | 不信任静态存储 |
安全不是一次性配置,而是持续的过程。定期审计 RBAC 权限、更新安全标准、扫描镜像漏洞、审查 NetworkPolicy,才能保持集群的安全态势。
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时






