云原生安全避坑:镜像、网络和密钥管理的常见疏忽

📅 2026/7/28 15:23:26
云原生安全避坑:镜像、网络和密钥管理的常见疏忽
云原生安全避坑镜像、网络和密钥管理的常见疏忽基础设施不需要漂亮话。云原生安全不是装个扫描工具就完事了。过去一年我们做了三次安全审计发现了 47 个安全问题其中 31 个是日常运维中的疏忽——不是攻击手法有多高明而是我们自己没做最基本的防护。这篇文章从镜像、网络和密钥管理三个维度列出最常见的疏忽每个都附带风险说明和修复方案。一、背景云原生安全的特殊性传统安全关注边界防护——防火墙、WAF、DDoS 防御。云原生环境的安全边界是模糊的Pod 在集群内可以互相访问Service 暴露了内部端口密钥可能散落在 ConfigMap、Secret 和环境变量里。三个维度的疏忽互相关联不安全的镜像在不受限的网络里传播更快明文密钥让入侵者一旦突破边界就能横移。二、镜像类四个疏忽疏忽 1用 latest 标签部署不可回溯image: myapp:latest是最常见的偷懒做法。问题是latest 指向的镜像随时可能变化你不知道当前线上跑的是哪个版本。回滚时kubectl rollout undo回到的上一个版本可能是两天前的 latest不是你期望的版本。更严重的问题某天镜像仓库被污染latest 被替换成恶意镜像。所有用 latest 的 Pod 下次重启时就会拉取恶意镜像。如果是固定版本号污染不会自动生效。修复方案所有镜像使用固定版本号标签如myapp:v2.3.1。CI/CD 流水线自动生成版本号不允许手动写 latest。集群准入控制器Admission Controller拒绝 latest 标签的部署。疏忽 2镜像没做漏洞扫描就直接上线Docker 镜像的基础层可能包含已知漏洞。我们审计时发现一个推理服务镜像基于 Ubuntu 20.04里面有 23 个已知 CVE其中 3 个是高危。更常见的情况镜像里装了curl、wget、apt等工具入侵者拿到容器后可以直接用它下载恶意软件。修复方案CI 流水线集成 Trivy 或 Grype 扫描高危 CVE 不修复就阻断构建。使用 distroless 或 scratch 基础镜像里面只有你的应用二进制没有 shell 和包管理器。定期每周重新扫描线上镜像新发现的 CVE 要及时修补。基础镜像类型大小包含工具安全等级scratch0无最高distroless~2MB无 shell/apt高alpine~5MBbusybox中ubuntu/debian~70MBapt/curl/wget低疏忽 3特权容器运行——给入侵者 root 权限securityContext: privileged: true让容器拥有宿主机 root 的所有能力。GPU 推理服务经常需要这个权限来访问 NVIDIA 驱动但 privileged 容器的风险极大入侵者可以从容器逃逸到宿主机控制整个节点。修复方案不要用 privileged。用securityContext.capabilities.add只添加必需的 capability如CAP_SYS_PTRACE或CAP_NET_RAW。GPU 容器使用 NVIDIA GPU Operator 的默认安全配置不需要 privileged 就能访问 GPU。启用 Pod Security AdmissionPSA在 namespace 级别 enforce Restricted 策略自动拒绝 privileged Pod。疏忽 4镜像包含调试工具——给入侵者送武器开发阶段为了方便调试镜像里塞了bash、python、strace、tcpdump。生产环境直接用这个镜像上线。入侵者拿到容器后这些工具就是他们的武器。修复方案构建两个镜像debug 镜像含调试工具只在开发环境用和 production 镜像最小化不含调试工具。用 Docker 多阶段构建最终阶段只拷贝编译产物丢弃所有中间层。# 阶段1构建 FROM golang:1.21 AS builder COPY . /src RUN go build -o /app/myapp # 阶段2生产 FROM gcr.io/distroless/static-debian:nonroot COPY --frombuilder /app/myapp /myapp ENTRYPOINT [/myapp] # 没有 shell、没有 apt、没有 curl三、网络类三个疏忽疏忽 5Pod 间默认全通——入侵后一键横移Kubernetes 默认的 NetworkPolicy 是所有 Pod 可以和所有 Pod 通信。这意味着一旦一个 Pod 被入侵入侵者可以访问集群内任何其他 Pod——数据库、消息队列、模型服务全部暴露。修复方案每个 namespace 至少有一个 default-deny NetworkPolicy禁止所有入站和出站流量然后逐个放通需要的连接。apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all spec: podSelector: {} # 选中所有 Pod policyTypes: - Ingress - Egress # 不定义任何规则 拒绝所有流量然后为每个服务添加具体的 NetworkPolicy只允许必要的通信路径。疏忽 6Service 暴露内部端口到公网推理服务用type: LoadBalancer暴露到公网。但 LoadBalancer Service 默认暴露所有声明的端口包括管理端口如 metrics 的 9090、debug 的 8080。管理端口没有认证任何人都能访问。修复方案生产 Service 只暴露业务端口管理端口通过内部 ServiceClusterIP暴露只允许集群内访问。使用 Ingress 而不是 LoadBalancer 直接暴露Ingress 可以统一加认证和限流。监控端口用单独的 Service 和 ServiceMonitor不走公网。疏忽 7mTLS 没有全员部署——内部流量被嗅探集群内 Pod 间通信默认是明文的。即使外部流量用了 TLS内部流量依然是 HTTP。如果有人能在集群内嗅探流量比如入侵了一个 Pod就能看到所有内部 API 调用的内容包括密钥、用户数据。修复方案部署服务网格Istio 或 Cilium自动为所有 Pod 间通信加 mTLS。如果不想用服务网格的完整功能至少启用 mTLS 模式。Istio 可以只做 mTLS 不做流量管理。不用服务网格的话在应用层自己实现 mTLS每个服务有自己的 TLS 证书通过 cert-manager 自动管理。四、密钥管理类三个疏忽疏忽 8Secret 明文存 ETCD——集群数据库就是密钥库Kubernetes Secret 默认在 ETCD 中以 Base64 编码存储不是加密。任何人有 ETCD 访问权限就能读取所有 Secret。审计时我们发现 ETCD 中有 12 个数据库密码、8 个 API Key、5 个 TLS 私钥全是 Base64 编码的。Base64 编码不是加密。编码是可逆的任何人都能base64 -d解码。修复方案启用 ETCD 静态加密在 kube-apiserver 配置--encryption-provider-config指定加密算法推荐 AES-CBC 或 AES-GCM。使用外部密钥管理Vault 或 AWS KMSSecret 只存引用不存值。定期审计 ETCD 中的 Secret 内容确保没有新增明文密钥。# encryption-provider-config 示例 apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration resources: - resources: - secrets providers: - aescbc: keys: - name: key1 secret: 32-byte-base64-encoded-key - identity: {} # 回退未加密的 Secret 也能读取疏忽 9密钥写进环境变量——进程信息泄露密钥env.valueFrom.secretKeyRef把密钥注入环境变量。问题是ps aux或/proc/pid/environ能看到任何进程的环境变量。如果容器被入侵入侵者一条命令就能获取所有密钥。更隐蔽的风险容器崩溃时错误日志可能打印环境变量某些框架默认行为密钥被写进日志系统。修复方案密钥用文件挂载secret.volumeMounts而不是环境变量。文件挂载后密钥在/etc/secrets/目录下不会出现在环境变量或进程信息中。如果必须用环境变量某些框架只支持环境变量至少确保容器内没有 shell用 distroless 镜像入侵者无法执行ps命令。疏忽 10密钥轮换没有自动化——过期密钥在线上跑半年密钥应该定期轮换但手动轮换的工作量太大没人愿意做。我们审计时发现一个数据库密码已经在线上跑了一年没改过一个 TLS 证书过期了 3 个月没人发现。过期 TLS 证书的后果比想象严重证书过期后mTLS 验证失败Pod 间通信中断集群功能部分停止。不是安全风险是可用性风险。修复方案用 cert-manager 自动管理 TLS 证书生命周期过期前自动续签。数据库密码等非证书密钥用 Vault 的动态密钥功能每次请求生成短期密码过期自动失效。建立密钥过期监控所有 Secret 的metadata.annotations记录过期时间Prometheus 定期扫描即将过期的密钥并告警。五、安全疏忽全景图入侵链路不安全的镜像多余工具 特权→ 容器被入侵 → Pod 全通网络让入侵者横移 → 环境变量中的密钥被窃取 → ETCD 中更多明文密钥暴露。每一层的疏忽都在为入侵链路开绿灯。六、总结云原生安全的三个基本动作镜像最小化distroless 基础镜像 固定版本号 CI 扫描漏洞。给入侵者一个空容器比装防火墙更有效。网络隔离化default-deny NetworkPolicy mTLS 端口最小暴露。不是所有 Pod 都需要互相访问。密钥专业化ETCD 加密 文件挂载 自动轮换。密钥是安全的核心不是运维的边角。这三件事做完能挡住 80% 的常见入侵。不需要买昂贵的安全产品只需要把该做的基本动作做到位。基础设施不需要漂亮话安全漏洞不会因为你没注意到就不存在。