Kubernetes 集群安全最佳实践:从 Pod 安全上下文(SecurityContext)防护到 NetworkPolicy 东西向网络隔离

cover

在现代企业级 Kubernetes(K8s)集群中,安全防御已不再仅仅是外网边界防火墙和网关的职责。在云原生微服务架构下,一旦某一个面向公网的业务容器被攻击者攻破,如果集群内部缺乏细粒度的纵深防御(Defense-in-Depth),攻击者便可轻易通过**容器提权(Container Privilege Escalation)获取宿主机的 Root 权限,或利用集群扁平化网络的特性,进行横向移动(Horizontal Movement)**渗透至其他敏感的核心服务(如数据库或配置中心)。为了遏制这种风险,我们必须在集群内部构筑两道安全防线:利用 Pod 的 SecurityContext 限制容器运行时权限,以及通过 NetworkPolicy 实现东西向(East-West)网络流量的强隔离。


一、 Pod 安全上下文(SecurityContext)内核权限调优

SecurityContext 是 Kubernetes 提供的一个安全功能,用于限制 Pod 或 Container 的运行行为和内核系统调用范围。

1.1 容器提权风险与安全策略

默认情况下,容器内的进程可能以宿主机的 root 权限运行,或者具备向内核请求获取特权的能力。我们需要通过以下核心字段彻底剥夺这些危险特权:

  • runAsNonRoot: true:强制 K8s 检测容器镜像在构建时是否指定了非 root 用户。如果是以 root 运行,Kubernetes 会直接拒绝拉起该容器,避免容器内进程具备系统级读写权限。
  • readOnlyRootFilesystem: true:将容器的根文件系统设置为只读。这样,即使攻击者利用远程代码执行(RCE)控制了容器,也无法向系统中下载恶意木马或修改 /etc/shadow 等系统配置文件。所有临时数据读写必须挂载专门的内存临时目录(emptyDir)。
  • allowPrivilegeEscalation: false:禁止容器内的子进程获取比父进程更多的特权(如通过 setuidsetgid 二进制文件提权)。
  • capabilities 剥夺:Linux 内核将原本由 root 独占的特权细分为了数十个 Capability(如绑定低于 1024 端口的 NET_BIND_SERVICE、修改时间的 SYS_TIME)。我们应通过 drop: ["ALL"] 剥夺全部特权,仅按需添加最安全的几个子项。

二、 东西向网络流量隔离:NetworkPolicy 原理

Kubernetes 的默认网络设计原则是扁平化与互通性——所有 Pod 均可跨命名空间(Namespace)直接通过 Pod IP 与其他任意 Pod 建立连接。这就给攻击者提供了极佳的横向移动温床。

flowchart TD
    subgraph Default_Network [默认无安全网络]
        Attacker[黑客攻破的前端 Pod] -->|无阻碍扫描与渗透| DB_Hacked[(敏感数据库 Pod)]
    end

    subgraph Secured_Network [NetworkPolicy 安全网络]
        AttackerSecured[前端 Pod] -.->|X 阻断非授权请求| Policy{NetworkPolicy 控制阀}
        Frontend[合规的前端网关 Pod] -->|允许通行| Policy
        Policy -->|只放行指定端口 5432| DB_Secured[(数据库 Pod)]
    end
end

2.1 东西向网络政策 (NetworkPolicy) 的实现逻辑

NetworkPolicy 是 K8s 的声明式防火墙策略。它通过选择器(podSelectornamespaceSelector),定义哪些 Pod(Ingress/Egress)被允许与当前目标 Pod 进行通信。

  • 网络阻断由谁执行?NetworkPolicy 本身只是控制面配置,具体的拦截执行依赖于底层实现了该标准的 CNI 网络插件(如 Calico、Cilium)。Calico 会根据 YAML 策略在对应的宿主机上自动生成 Linux iptables 规则或 IPVS 映射表,对数据包执行强行丢弃(Drop)。
  • 默认拒绝所有(Default Deny All):最佳实践是在命名空间级别部署一条默认拒绝所有入站和出站流量的策略,再通过白名单方式逐一放行经过安全审计的服务调用链路。

三、 生产级安全防护配置 YAML 完整实现

下面提供一套完整的、无占位符的声明式安全配置。包含了限制 Root 权限和只读文件系统的 Deployment,以及限制东西向网络流量、仅允许前端服务访问特定端口的 NetworkPolicy 配置文件。

# =========================================================================
# 1. 声明严格安全上下文控制的 Deployment
# =========================================================================
apiVersion: apps/v1
kind: Deployment
metadata:
  name: secured-backend-service
  namespace: production
  labels:
    app: secured-backend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: secured-backend
  template:
    metadata:
      labels:
        app: secured-backend
    spec:
      # Pod 级别的安全上下文
      securityContext:
        runAsNonRoot: true # 限制必须以非 root 运行
        runAsUser: 10001   # 指定运行的非特权用户 UID
        runAsGroup: 10001  # 指定运行组 GID
        fsGroup: 10001     # 挂载卷的属组
        seccompProfile:
          type: RuntimeDefault # 开启默认的内核系统调用过滤 (Seccomp)
      containers:
        - name: backend-app
          image: alpine:3.18
          # 模拟一个前台长连接业务
          command: ["/bin/sh", "-c", "while true; do echo 'Secured process running'; sleep 30; done"]
          
          # 容器级别的安全上下文
          securityContext:
            allowPrivilegeEscalation: false # 禁止特权升级
            readOnlyRootFilesystem: true    # 强制将根文件系统设为只读
            capabilities:
              drop:
                - ALL # 剥夺所有 Linux 内核 Capability 特权
          
          # 由于根目录只读,如需写入日志或临时数据,必须挂载内存空卷 (emptyDir)
          volumeMounts:
            - name: tmp-storage
              mountPath: /tmp
          ports:
            - containerPort: 8080
              name: http
          resources:
            limits:
              cpu: "1"
              memory: 1Gi
            requests:
              cpu: "0.2"
              memory: 512Mi
      volumes:
        - name: tmp-storage
          emptyDir:
            medium: Memory # 使用 RAM 限制该临时卷以防持久写入

---

# =========================================================================
# 2. 声明 NetworkPolicy,限制仅允许 frontend 标签的 Pod 访问 8080 端口
# =========================================================================
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-network-isolation
  namespace: production
spec:
  # 作用于带有 app=secured-backend 标签的 Pod
  podSelector:
    matchLabels:
      app: secured-backend
  policyTypes:
    - Ingress # 开启入站控制规则
  ingress:
    # 白名单配置规则
    - from:
        - podSelector:
            matchLabels:
              app: public-frontend # 仅允许带有该标签的前端 Pod 访问
      ports:
        - protocol: TCP
          port: 8080 # 仅放行 8080 端口,阻断其他端口

通过这一安全体系的配置,哪怕前端容器由于漏洞失守,黑客既无法在后端容器内下载脚本写入可执行文件(受限于 readOnlyRootFilesystem),也无法利用扫描工具横向渗透后端容器(受限于 NetworkPolicy 对未授权入站流量的直接静默丢弃),从而在物理上切断了攻击链的横向蔓延。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐