云原生架构越来越普及,Kubernetes、Docker、微服务这些技术已经成为很多公司的标配。但随着云原生的普及,安全问题也越来越突出。

容器逃逸、镜像漏洞、权限过大、网络暴露、数据泄露,这些都是云原生环境的常见安全风险。很多团队关注功能开发,却忽视了安全配置,导致线上环境存在很多安全隐患。

我最近帮公司做了一次云原生安全审计,发现了不少问题,也做了很多加固。今天分享云原生安全配置,从基础到高级,帮你搭建一个安全的云原生环境。

一、云原生安全的挑战

云原生环境和传统环境不同,安全面临新的挑战。

1. 环境动态变化

容器是短暂的,随时创建和销毁。传统的安全工具(比如基于IP的防火墙)在动态环境里不好用。

2. 攻击面大

云原生环境组件多:容器、镜像、编排平台、服务网格、存储、网络,每个组件都可能有漏洞。

3. 共享内核

容器共享宿主机内核。如果容器逃逸,就能访问宿主机,影响其他容器。

4. 供应链复杂

容器镜像来自各种来源,基础镜像、依赖包,都可能有漏洞。供应链攻击越来越多。

5. 权限管理复杂

Kubernetes的RBAC、ServiceAccount、Secret,权限管理复杂,配置不当就会权限过大。

所以,云原生安全需要全栈防护,从镜像到运行时,从网络到权限,每个环节都要加固。

二、镜像安全

镜像是云原生的基础,镜像安全是第一道防线。

1. 使用最小基础镜像

很多人喜欢用Ubuntu、CentOS作为基础镜像,这些镜像体积大,包含很多不必要的工具,攻击面大。

建议用更小的基础镜像:

  • Alpine:只有5MB左右,包含基本工具
  • Distroless:只包含应用和运行时依赖,没有shell,攻击面最小
  • Scratch:空镜像,适合静态编译的应用

比如,Go应用可以用Scratch或Distroless,Java应用可以用Distroless的JRE镜像。

2. 扫描镜像漏洞

构建镜像后,要扫描漏洞。常用工具:

  • Trivy:简单易用,支持扫描镜像、文件系统、Git仓库
  • Clair:CoreOS出品,和CI/CD集成好
  • Snyk:商业工具,功能强大

建议在CI/CD流程里加入镜像扫描步骤,发现高危漏洞就阻断构建。

3. 不要用latest标签

latest标签不稳定,每次构建可能不一样,不利于追溯和回滚。

建议用具体的版本号,比如myapp:v1.2.3,或者用Git commit hash作为标签。

4. 多阶段构建

用Docker的多阶段构建,构建阶段用有编译工具的镜像,运行阶段用最小镜像。这样最终镜像里不包含编译工具,攻击面小。

# 构建阶段
FROM golang:1.18 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# 运行阶段
FROM gcr.io/distroless/base
COPY --from=builder /app/myapp /myapp
ENTRYPOINT ["/myapp"]

5. 不要在镜像里存敏感信息

不要把密码、密钥、证书写在Dockerfile里,也不要打包进镜像。敏感信息应该用Kubernetes的Secret或配置中心管理。

.dockerignore排除敏感文件,避免不小心打包进镜像。

6. 验证镜像签名

镜像可能被篡改,建议用镜像签名验证。常用工具:

  • Docker Content Trust
  • Cosign(Sigstore项目)
  • Harbor的镜像签名功能

三、容器运行时安全

镜像安全之后,是容器运行时的安全。

1. 不要以root用户运行

容器里默认是root用户,这很危险。如果容器被攻破,攻击者就是root,虽然是容器里的root,但也能做很多事。

建议在Dockerfile里创建普通用户,用普通用户运行:

RUN useradd -u 10001 appuser
USER appuser

在Kubernetes里,可以用securityContext.runAsUser指定用户:

securityContext:
  runAsUser: 10001
  runAsNonRoot: true

2. 只读文件系统

容器的文件系统应该是只读的,防止攻击者写入恶意文件。需要写入的地方,用emptyDir或PV挂载。

securityContext:
  readOnlyRootFilesystem: true
volumes:
- name: tmp
  emptyDir: {}
volumeMounts:
- name: tmp
  mountPath: /tmp

3. 禁用特权模式

特权模式(--privileged)给了容器几乎所有宿主机权限,非常危险。绝对不要在生产环境用特权模式。

如果需要某些权限,用capabilities精确添加,而不是给全部权限。

securityContext:
  capabilities:
    drop:
    - ALL
    add:
    - NET_BIND_SERVICE

先drop所有能力,再按需添加。

4. 禁止特权升级

禁止容器内的进程通过setuid等方式提升权限:

securityContext:
  allowPrivilegeEscalation: false

5. 限制资源

限制容器的CPU和内存,防止一个容器占用所有资源,影响其他容器:

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 512Mi

还要限制进程数,防止fork炸弹:

securityContext:
  procMount: Default

配合ulimitpids_limit限制进程数。

四、Kubernetes安全配置

Kubernetes是云原生的核心,它的安全配置很重要。

1. RBAC权限最小化

Kubernetes的RBAC要遵循最小权限原则。不要给ServiceAccount cluster-admin权限,只给需要的权限。

比如,一个应用只需要读取ConfigMap,就只给get和list权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: configmap-reader
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]

定期审计RBAC权限,删除不需要的权限。

2. 命名空间隔离

不同的环境(开发、测试、生产)、不同的团队,用不同的命名空间隔离。配合ResourceQuota和LimitRange,限制每个命名空间的资源。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi

3. NetworkPolicy网络隔离

默认情况下,Kubernetes里所有Pod之间都能互相访问。这很危险,一个Pod被攻破,攻击者就能访问其他Pod。

用NetworkPolicy限制Pod之间的网络访问:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

先默认拒绝所有流量,再按需放行。

比如,只允许前端访问后端的8080端口:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-access
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

4. Pod安全标准

Kubernetes 1.25引入了Pod Security Standards,替代了原来的PodSecurityPolicy。

有三个级别:

  • Privileged:不受限制,不推荐
  • Baseline:基本安全,禁止特权容器等
  • Restricted:严格安全,适合生产环境

通过命名空间标签启用:

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

生产环境建议用restricted级别。

5. Secret管理

Kubernetes的Secret默认是base64编码的,不是加密的。要注意:

  • 不要把Secret提交到Git
  • 开启etcd加密,让Secret在存储时加密
  • 用外部密钥管理系统(如Vault、AWS Secrets Manager)管理敏感信息
  • 限制Secret的访问权限,只给需要的Pod

6. API Server安全

Kubernetes API Server是集群的入口,要加固:

  • 开启RBAC,禁用匿名访问
  • 开启TLS,用证书认证
  • 限制API Server的访问来源,只允许内网访问
  • 开启审计日志,记录所有API调用
  • 定期升级Kubernetes版本,修复安全漏洞

五、网络安全

云原生环境的网络安全也很重要。

1. Ingress安全

Ingress是外部流量进入集群的入口,要加固:

  • 用HTTPS,配置TLS证书
  • 配置WAF(Web应用防火墙),防御SQL注入、XSS等攻击
  • 限制请求大小,防止大文件攻击
  • 配置速率限制,防止DDoS
  • 隐藏服务版本信息,不要暴露Server头

2. 服务网格安全

如果用了Istio等服务网格,可以开启:

  • mTLS:服务之间双向TLS加密
  • 授权策略:限制服务之间的访问
  • 流量管理:金丝雀发布、熔断、限流

3. 出口流量控制

默认情况下,Pod可以访问外部网络。这有风险,被攻破的Pod可能向外发送数据。

用NetworkPolicy或服务网格限制出口流量,只允许访问需要的外部地址。

六、高级安全配置

1. 运行时安全监控

除了静态配置,还要监控运行时的异常行为。

常用工具:

  • Falco:CNCF项目,监控容器运行时的异常行为,比如异常的系统调用、文件访问
  • Sysdig:商业工具,功能强大
  • Aqua/Twistlock:容器安全平台,包含运行时防护

配置规则,检测:

  • 容器内启动shell
  • 访问敏感文件(/etc/shadow等)
  • 异常的网络连接
  • 权限提升尝试

发现异常就告警,或者直接杀死容器。

2. 镜像准入控制

用Kubernetes的准入控制器,只允许符合安全标准的镜像运行:

  • 只允许来自可信镜像仓库的镜像
  • 镜像必须通过漏洞扫描,没有高危漏洞
  • 镜像必须有签名
  • 不允许用latest标签

常用工具:

  • OPA Gatekeeper:通用策略引擎
  • Kyverno:Kubernetes原生策略引擎
  • Trivy Operator:自动扫描集群里的镜像

3. 基础设施即代码安全

Kubernetes的YAML文件、Terraform代码,也要做安全检查:

  • checkov:扫描IaC代码的安全问题
  • kube-linter:检查Kubernetes YAML的最佳实践
  • kubesec:评估Pod安全配置

在CI/CD里加入这些检查,不符合安全标准的代码不能合并。

4. 零信任架构

云原生环境适合零信任架构:

  • 不信任任何内部流量,所有访问都要认证和授权
  • 服务之间用mTLS加密
  • 每个请求都要验证身份和权限
  • 持续监控和评估信任度

5. 安全左移(DevSecOps)

把安全融入开发流程,而不是上线前才检查:

  • 开发阶段:IDE插件实时检查安全问题
  • 代码提交:pre-commit钩子检查
  • CI/CD:镜像扫描、IaC扫描、依赖检查
  • 部署阶段:准入控制,只允许安全的镜像
  • 运行阶段:持续监控和防护

七、常见安全漏洞

分享几个常见的云原生安全漏洞,帮你避坑。

1. 容器逃逸

攻击者通过漏洞从容器里逃到宿主机。常见原因:

  • 特权容器
  • 挂载了宿主机的Docker socket
  • 内核漏洞

防护:不用特权容器,不挂载Docker socket,及时升级内核。

2. 镜像漏洞

镜像里的软件有已知漏洞,被攻击者利用。

防护:定期扫描镜像,及时更新基础镜像和依赖。

3. 权限过大

ServiceAccount有cluster-admin权限,Pod被攻破后,攻击者就能控制整个集群。

防护:RBAC最小权限,定期审计。

4. Secret泄露

Secret被提交到Git,或者通过环境变量暴露。

防护:用Secret管理工具,不要硬编码,定期轮换密钥。

5. 未授权访问

Dashboard、API Server、数据库等服务暴露在公网,没有认证。

防护:只在内网暴露,开启认证,用NetworkPolicy限制访问。

八、安全检查清单

给大家一个简单的安全检查清单,可以对照着检查自己的集群。

镜像安全:

  • [ ] 使用最小基础镜像
  • [ ] 镜像经过漏洞扫描
  • [ ] 不用latest标签
  • [ ] 多阶段构建
  • [ ] 镜像里没有敏感信息

容器安全:

  • [ ] 不以root用户运行
  • [ ] 只读文件系统
  • [ ] 不用特权模式
  • [ ] 禁用特权升级
  • [ ] 限制CPU和内存

Kubernetes安全:

  • [ ] RBAC最小权限
  • [ ] 命名空间隔离
  • [ ] NetworkPolicy网络隔离
  • [ ] Pod安全标准(restricted)
  • [ ] Secret加密管理
  • [ ] API Server加固

网络安全:

  • [ ] Ingress用HTTPS
  • [ ] 服务之间mTLS
  • [ ] 出口流量控制
  • [ ] WAF防护

运行时安全:

  • [ ] 运行时异常监控
  • [ ] 镜像准入控制
  • [ ] IaC安全扫描
  • [ ] 审计日志

九、写在最后

云原生安全是一个系统工程,不是配置几个参数就能搞定的。它需要从镜像、容器、编排、网络、运行时等多个层面综合防护。

很多团队觉得安全会影响开发效率,但其实安全做好了,反而能减少事故,提高效率。而且现在有很多自动化工具,能把安全融入开发流程,不增加太多负担。

安全不是一次性的工作,而是持续的过程。新的漏洞不断出现,新的攻击手段不断涌现,需要持续关注和加固。

2022年了,云原生已经成为主流,安全也越来越重要。希望这篇文章能帮你搭建一个更安全的云原生环境。

最后,用一句话总结:"安全不是产品,而是一个过程。它需要每个人的参与,每个环节的重视。"

祝大家的系统都能安全稳定运行。