云原生安全
→ 返回 云原生
云原生安全遵循 Zero Trust(零信任) 原则:默认不信任任何请求,无论来自内部还是外部,每次访问都需要验证。
安全分层
┌─────────────────────────────────────────────┐
│ 外部安全:WAF、DDoS、CDN │
├─────────────────────────────────────────────┤
│ 传输安全:TLS、mTLS │
├─────────────────────────────────────────────┤
│ 身份安全:RBAC、OIDC、ServiceAccount │
├─────────────────────────────────────────────┤
│ 网络安全:NetworkPolicy、Service Mesh │
├─────────────────────────────────────────────┤
│ 运行时安全:Falco、Seccomp、AppArmor │
├─────────────────────────────────────────────┤
│ 供应链安全:镜像扫描、SBOM、签名验证 │
└─────────────────────────────────────────────┘
Zero Trust 模型
传统安全:“内网是可信的” Zero Trust:“永不信任,持续验证”
传统:
外部 → 防火墙 → 内网(自由通行)
Zero Trust:
外部 → 验证 → 服务 A
│ 访问服务 B
▼ 再次验证(mTLS + RBAC)
服务 B
四要素:
- 验证所有用户:不因为在内网就免验证
- 验证所有设备:设备需注册、合规
- 最小权限:每个服务只能访问自己需要的资源
- 持续监控:假设已被攻破,实时检测异常
mTLS(双向 TLS)
Service Mesh(Istio)自动为服务间通信启用 mTLS:
服务 A 服务 B
│ │
│ 1. 发起连接 │
│──────────────────────────────►│
│ │
│ 2. 服务 B 发送证书 │
│◄──────────────────────────────│
│ 3. 服务 A 验证 B 的证书 │
│ │
│ 4. 服务 A 发送自己的证书 │
│──────────────────────────────►│
│ 5. 服务 B 验证 A 的证书 │
│ │
│ 6. 双向验证通过,加密通信 │
证书由 Istio Citadel 自动颁发和轮换,无需手动管理。
K8s RBAC
Role-Based Access Control,控制谁能对 K8s 资源做什么操作:
ServiceAccount(身份)
│ 绑定
▼
RoleBinding / ClusterRoleBinding
│ 关联
▼
Role / ClusterRole(权限规则)
│ 定义
▼
Resources + Verbs(如:pods / get,list,watch)
最小权限原则示例:
# order-service 只能读取自己命名空间的 ConfigMap
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: order-service-role
namespace: prod
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]Secret 管理
K8s Secret 默认只是 Base64 编码,不是加密。生产环境需要专门的 Secret 管理工具。
HashiCorp Vault
应用启动
│
▼
向 Vault 请求 Secret(携带 K8s ServiceAccount Token)
│
▼
Vault 验证身份(K8s Auth Method)
│
▼
返回动态 Secret(短期有效,自动轮换)
│
▼
应用使用 Secret,过期后重新申请
动态 Secret 优势: 数据库密码每次申请都不同,即使泄露也很快失效。
云厂商 KMS
| 工具 | 特点 |
|---|---|
| AWS Secrets Manager | 自动轮换,与 EKS 深度集成 |
| 阿里云 KMS | 国内合规,密钥硬件保护 |
| HashiCorp Vault | 多云通用,开源 |
| SealedSecret | GitOps 友好,加密后存 Git |
SealedSecret(GitOps 场景)
Secret(明文)
│ kubeseal 加密
▼
SealedSecret(密文,可安全存 Git)
│ 推送到 Git
▼
ArgoCD 部署到 K8s
│ Controller 解密
▼
普通 Secret(集群内使用)
镜像安全(供应链安全)
代码提交
│
CI 构建镜像
│
▼
Trivy / Snyk 扫描
├── OS 包漏洞(CVE 数据库)
├── 依赖漏洞(npm / Maven / pip)
├── Dockerfile 最佳实践检查
└── 敏感信息扫描(hardcoded secrets)
│
▼
镜像签名(Cosign)
│
▼
推送到 Registry
│
▼
K8s 准入控制(Kyverno / OPA)验证签名
Dockerfile 安全实践:
# ✅ 使用非 root 用户
FROM eclipse-temurin:21-jre
RUN useradd -m appuser
USER appuser
# ✅ 使用最小基础镜像(distroless)
FROM gcr.io/distroless/java21
# ❌ 避免 root 运行
# USER root运行时安全
Falco(异常行为检测)
Pod 运行时
│ 系统调用监控(eBPF / 内核模块)
▼
Falco 规则引擎
│ 匹配规则:容器内执行 shell、读取 /etc/passwd...
▼
├── 告警到 Slack / SIEM
└── 自动响应(杀掉 Pod)
典型检测规则:
- 容器内执行 bash / sh
- 读取
/etc/shadow、/proc/1/environ - 向外网发起异常连接
- 挂载宿主机敏感目录
K8s 准入控制
kubectl apply
│
▼
kube-apiserver
│
▼
Admission Webhook(Kyverno / OPA Gatekeeper)
│
├── 验证(Validate):不符合策略 → 拒绝
└── 变更(Mutate):自动注入 Sidecar、修改配置
Kyverno 策略示例(禁止 latest 镜像):
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
spec:
rules:
- name: require-image-tag
match:
resources:
kinds: [Pod]
validate:
message: "镜像必须指定具体版本号,不允许使用 latest"
pattern:
spec:
containers:
- image: "!*:latest"NetworkPolicy(网络隔离)
# 只允许 order-service 访问 payment-service
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: payment-network-policy
namespace: prod
spec:
podSelector:
matchLabels:
app: payment-service
ingress:
- from:
- podSelector:
matchLabels:
app: order-service
ports:
- port: 8080默认拒绝所有,只开放必要端口,实现最小网络权限。