云原生安全:从 Pod 到策略的纵深防御
本文揭示云原生环境常见安全误区,提出从Pod安全到网络策略的全方位防护方案。关键措施包括:强制Pod以非root用户运行并启用只读文件系统,通过NetworkPolicy实现零信任网络,使用Trivy扫描镜像漏洞并签名验证,借助Gatekeeper实施策略即代码,开启Kubernetes审计日志实现操作追溯。文章强调云原生安全需要平台层与应用层协同防护,将最小权限、不可变基础设施等原则贯穿交付全流
“我们的服务跑在 Kubernetes 里,应该很安全吧?”
“Docker 镜像能跑就行,漏洞扫描太麻烦了。”
“Pod 默认用 root 启动,有什么问题吗?”
如果你也有类似想法,那么你的系统可能正暴露在高危攻击面之下。
云原生不是“自动安全”。恰恰相反,容器和编排系统的灵活性带来了更多安全边界:镜像、Pod、网络、API Server、配置策略……任何一个环节疏忽,都可能导致数据泄露或集群沦陷。
本文将带你构建一套最小权限、可审计、自动化的云原生安全体系,覆盖从 Pod 运行时到策略合规的纵深防御链。
一、Pod 安全:从非 root 到只读文件系统
Kubernetes Pod 默认以 root 用户运行,且根文件系统可写——这在安全上是灾难性的。
关键加固措施(通过 securityContext):
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsNonRoot: true # 禁止 root 启动
runAsUser: 65532 # 指定 UID(如 distroless 的 nonroot)
readOnlyRootFilesystem: true # 根文件系统只读
capabilities:
drop: ["ALL"] # 剥离所有 Linux 能力
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false
✅ 效果:
- 即使应用被攻破,攻击者也无法写入恶意文件;
- 无法提权或挂载敏感设备;
- 符合 CIS Kubernetes Benchmark 安全基线。
若应用需写临时文件,可挂载 emptyDir 到 /tmp:
volumeMounts:
- name: tmp-volume
mountPath: /tmp
volumes:
- name: tmp-volume
emptyDir: {}
二、网络策略:用 NetworkPolicy 实现零信任
默认情况下,K8s 集群内所有 Pod 可互相通信。这违背了“最小权限”原则。
NetworkPolicy 允许你定义“谁可以访问谁”:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
meta
name: user-svc-policy
spec:
podSelector:
matchLabels:
app: user-service
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
role: frontend
- podSelector:
matchLabels:
app: order-service
ports:
- protocol: TCP
port: 8080
egress:
- to:
- namespaceSelector:
matchLabels:
name: database
ports:
- protocol: TCP
port: 3306
💡 解读:
- 只允许
frontend命名空间中的 Pod 或order-service访问user-service; user-service只能向外连接数据库命名空间的 3306 端口。
⚠️ 注意:NetworkPolicy 需 CNI 插件支持(如 Calico、Cilium),Flannel 不支持。
三、镜像安全:Trivy 扫描 + Notary 签名
一个包含 CVE 漏洞的镜像,等于给攻击者留了后门。
1. 镜像漏洞扫描(Trivy)
在 CI 中集成 Trivy:
trivy image --exit-code 1 --severity CRITICAL harbor.example.com/app:v1.0
- 发现 CRITICAL 漏洞则阻断流水线;
- 支持 OS 包、Go 模块、Python pip 等多语言依赖扫描。
2. 镜像签名(Notary / Cosign)
防止“镜像被篡改”:
- 使用 Cosign 对镜像签名:
cosign sign --key cosign.key harbor.example.com/app:v1.0
- 在部署时验证签名(通过 OPA/Gatekeeper 或 Kyverno)。
✅ 目标:确保“只有经过扫描且签名的镜像才能部署”。
四、策略即代码:OPA / Gatekeeper 强制合规
人工审查 YAML 不现实。安全策略应作为代码自动执行。
使用 Gatekeeper(OPA 的 K8s 实现):
- 定义 ConstraintTemplate(策略模板):
# 禁止 root 用户
violation[{"msg": msg}] {
container := input.review.object.spec.containers[_]
not container.securityContext.runAsNonRoot
msg := sprintf("container <%v> must set runAsNonRoot=true", [container.name])
}
- 应用 Constraint(策略实例):
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequireSecurityContext
meta
name: require-nonroot
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
🔒 效果:任何未设置 runAsNonRoot: true 的 Pod 创建请求将被 拒绝。
类似策略还可覆盖:
- 禁止使用
latest标签; - 强制资源限制(requests/limits);
- 禁止特权容器。
五、审计:开启 K8s 审计日志
即使防护到位,也需记录“谁做了什么”,用于事后追溯。
Kubernetes 审计日志(Audit Log) 记录所有 API Server 请求:
- 谁(user/group)
- 做了什么(create/delete/update)
- 操作对象(Pod/Service/Secret)
- 源 IP
启用方式(kube-apiserver 参数):
--audit-log-path=/var/log/kube-audit/audit.log
--audit-policy-file=/etc/kubernetes/audit-policy.yaml
示例策略(仅记录敏感操作):
apiVersion: audit.k8s.io/v1
rules:
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
- level: RequestResponse
resources:
- group: "rbac.authorization.k8s.io"
resources: ["roles", "rolebindings"]
日志可接入 Loki + Grafana 或 SIEM 系统,实现告警与可视化。
六、安全体系全景图

七、平台层 vs 应用层安全
云原生安全是分层的:
- 平台层(K8s):负责 mTLS、网络隔离、Pod 安全上下文;
- 应用层:负责业务逻辑安全,如请求签名、OAuth2 鉴权、敏感数据脱敏。
🔗 mTLS 证书管理由平台层完成(如 Istio),而服务间请求签名仍需在应用层实现(《微服务》【安全篇】)。
例如,即使流量已加密,仍需在 HTTP Header 中携带 HMAC 签名,防止重放攻击。
结语:安全不是功能,而是默认状态
真正的云原生安全,不是“加个防火墙”,而是将最小权限、不可变、可验证、可审计融入交付全流程。
从今天起:
- 所有 Pod 必须非 root 运行;
- 所有镜像必须通过 Trivy 扫描;
- 所有部署必须受 Gatekeeper 策略约束。
让安全成为默认,而非例外。
📌 关注专栏《云原生从入门到精通》,系统掌握从交付到安全的完整能力。
更多推荐
所有评论(0)