Kubernetes概念: NetworkPolicy 详解

目录

1. 什么是 NetworkPolicy?

2. 为什么需要 NetworkPolicy?

3. 前提条件:网络插件支持

4. NetworkPolicy 核心工作模型

5. NetworkPolicy 资源定义剖析

6. 常见场景示例

场景 1:拒绝所有入站流量(默认拒绝)

场景 2:允许来自特定 Pod 的访问

场景 3:允许访问外部网络和 DNS

场景 4:跨命名空间访问

7. 总结与最佳实践

1. 什么是 NetworkPolicy?

NetworkPolicy 是一种 Kubernetes 资源对象,它通过定义规则来控制 Pod 之间以及 Pod 与外部网络之间的网络流量(入站和出站),就像一个内置的、基于标签的防火墙。

核心思想:默认情况下,Kubernetes 集群内的所有 Pod 是可以相互通信的(“所有流量放行”)。NetworkPolicy 允许你实施 “最小权限原则” ,即只允许必要的通信,拒绝其他所有流量。


2. 为什么需要 NetworkPolicy?

想象一个典型的微服务应用:

  • 前端(frontend) Pods 需要与 后端(backend) Pods 通信。
  • 后端 Pods 需要与 数据库(database) Pods 通信。
  • 但前端不应该直接访问数据库,并且可能没有任何服务需要主动连接前端。

如果没有 NetworkPolicy,如果一个 Pod 被攻击,攻击者可以以此为跳板,在集群内“横向移动”,访问任何其他服务。NetworkPolicy 可以严格限制这种横向移动,极大地提升集群的安全性。


3. 前提条件:网络插件支持

非常重要:NetworkPolicy 本身只是一个 API 定义,它需要由 Container Network Interface (CNI) 网络插件来具体实现其规则。

  • 支持的 CNI 插件:Calico, Cilium, Weave Net, Antrea, Kube-router 等。
  • 不支持的 CNI 插件:Flannel(默认的 host-gw 后端不支持)、Bridge 等。

如果你的网络插件不支持 NetworkPolicy,那么你创建的任何策略都不会生效。请先确认你的 Kubernetes 集群使用了正确的网络插件。


4. NetworkPolicy 核心工作模型

NetworkPolicy 不是通过在 Pod 上添加注解来实现的,而是通过选择器(Selectors)来定义规则:

  • 选择一组 Pods:使用 podSelector 字段来选择此策略要应用到的目标 Pods(“防火墙要保护谁”)。
  • 定义入站规则(Ingress):规定谁可以访问这些目标 Pods,以及可以访问哪些端口。
  • 定义出站规则(Egress):规定这些目标 Pods 可以访问谁,以及可以访问哪些端口。

5. NetworkPolicy 资源定义剖析

下面是一个完整的 NetworkPolicy 示例

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default # NetworkPolicy 是命名空间范围的资源
spec:
  # 1. 策略目标:此策略应用到哪里?
  podSelector:
    matchLabels:
      role: db # 选择所有具有标签 `role=db` 的 Pods

  # 2. 策略类型:定义此策略是管理入站、出站,还是两者都管。
  policyTypes:
  - Ingress
  - Egress

  # 3. 入站规则(白名单):谁可以访问上述 `role=db` 的 Pods?
  ingress:
  - from:
      - podSelector: # (a) 来自集群内的 Pods
          matchLabels:
            role: api
      - namespaceSelector: # (b) 来自特定命名空间的所有 Pods
          matchLabels:
            project: myproject
      - ipBlock: # (c) 来自集群外部的特定 IP 段
          cidr: 172.17.0.0/16
          except:
          - 172.17.1.0/24
    ports:
    - protocol: TCP
      port: 6379

  # 4. 出站规则(白名单):上述 `role=db` 的 Pods 可以访问谁?
  egress:
  - to:
      - podSelector:
          matchLabels:
            role: cache
    ports:
    - protocol: TCP
      port: 6379
  - to: # 允许访问外部 DNS 服务器
      - ipBlock:
          cidr: 8.8.8.8/32
    ports:
    - protocol: UDP
      port: 53

6. 常见场景示例

场景 1:拒绝所有入站流量(默认拒绝)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: default
spec:
  podSelector: {} # 匹配命名空间中的所有 Pods
  policyTypes:
  - Ingress
  # 不指定任何 ingress 规则,意味着拒绝所有入站流量。

场景 2:允许来自特定 Pod 的访问

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

场景 3:允许访问外部网络和 DNS

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

场景 4:跨命名空间访问

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

给命名空间打上标签:

kubectl label namespace frontend name=frontend

7. 总结与最佳实践

  • 默认拒绝:首先为每个命名空间创建 deny-all-ingress 策略,然后再创建允许特定流量的策略。
  • 标签是关键:NetworkPolicy 严重依赖标签(podSelector 和 namespaceSelector)来工作。为 Pod 和命名空间设计清晰的标签体系。
  • 策略是叠加的:如果多个 NetworkPolicy 选择了同一个 Pod,则所有策略的规则会叠加(取并集)。
  • 从简单开始:先从保护最关键的服务(如数据库)开始,逐步扩大范围。
  • 测试策略
    kubectl describe networkpolicy <name>
    kubectl run -it --rm --image=nicolaka/netshoot testpod -- /bin/bash
    
    然后使用 curldignc 等工具测试连通性。

NetworkPolicy 是 Kubernetes 生产环境安全加固的必备工具,能够在容器层面实现网络隔离,防止攻击蔓延,是零信任网络架构在 K8s 中的具体实践。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值