K8S之NetworkPolicy介绍

AI 总结

Kubernetes NetworkPolicy是用于控制Pod间及Pod与外部网络流量的资源对象,类似防火墙规则。其核心模块包括Ingress(入站)、Egress(出站)、CNI插件支持、默认拒绝行为、podSelector、namespaceSelector和ipBlock。常用命令有kubectl apply/get/describe/delete netpol。演示场景涵盖默认全部拒绝、仅允许同命名空间流量、隔离前后端通信、限制出站等。最佳实践示例展示了通过标签选择Pod,结合命名空间选择器和IP块,精细控制特定端口和协议的入站与出站流量,实现多策略组合。

什么是NetworkPolicy?

在Kubernetes 中,NetworkPolicy是一种用于控制Pod间网络流量以及Pod与外部网络之间的流量的资源对象。通过配置NetworkPolicy,可以在Kubernetes集群中实现基于网络的安全策略,类似防火墙规则。

NetworkPolicy 的作用

  • 限制哪些流量可以进入或离开某个Pod。
  • 控制Pod间的网络通信,以及Pod与外部服务的通信。
  • 提供网络层的隔离,使得默认情况下Pod 不允许相互通信,除非允许。

理解 Kubernetes 网络策略的关键在于掌握其核心构建模块

  • Ingress (入站) & Egress (出站):Ingress 指的是进入 Pod 的流量,Egress 指的是从 Pod 发出的流量。网络策略可以分别或同时对这两种流量进行控制。
  • CNI 插件:Kubernetes 本身不执行网络策略,而是依赖于容器网络接口(CNI)插件,例如 Calico 或 Cilium。CNI 必须支持网络策略才能使其生效。
  • 默认拒绝行为:一旦为某个 Pod 应用了任何网络策略,该 Pod 的网络模式就会自动切换为“默认拒绝”。所有未被策略明确允许的流量都将被阻止。
  • podSelector:策略的核心。它通过标签来选择该策略应用于哪些 Pod。如果为空 {}, 则应用于命名空间下的所有 Pod
  • namespaceSelector:在 ingress 或 egress 规则中使用,用于根据标签选择允许通信的源或目标命名空间。
  • ipBlock:允许根据 CIDR 地址块定义流量规则,常用于控制与集群外部服务的通信。

常用命令

# 创建策略
kubectl apply -f policy.yaml

# 查看当前命名空间的所有策略
kubectl get networkpolicy  # 缩写:kubectl get netpol

# 查看策略详情(包括规则)
kubectl describe netpol <策略名称>

# 删除策略
kubectl delete netpol <策略名称>

场景演示

场景一:默认全部拒绝

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

应用效果:此命名空间下的所有 Pod 之间、与外部的所有通信均被阻止。

场景二:仅允许同命名空间内流量

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-same-namespace
  namespace: my-app
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}

应用效果:my-app 命名空间内的 Pod 可以相互通信,但无法与外部及其他命名空间的 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

应用效果:只有标签为 app: frontend 的 Pod 能够连接到标签为 app: backend 的 Pod 的 8080 端口;其他 Pod 均无法访问。

场景四:限制出站

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: app-to-db-egress
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.32/32
    ports:
    - protocol: TCP
      port: 3306

应用效果:标签为 app: myapp 的 Pod 只能向 10.0.0.32 的 3306端口发起连接,其他所有出站流量均被阻止。

最佳实践示例

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: whisker-ru
  namespace: calico-system
spec:
  #应用规则的pod
  podSelector:
    matchLabels:
      app.kubernetes.io/name: whisker
  #对以上匹配规则的pod应用的策略
  policyTypes:
  - Ingress
  - Egress
  #控制入站流量
  ingress:
  #代表允许kube-system名称空间下的所有pod访问calico-system空间下标签带有app.kubernetes.io/name: whiske服务的8081端口
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
  #代表允许ingress-nginx名称空间下的所有pod访问calico-system空间下标签带有app.kubernetes.io/name: whiske服务的8081端口的8081端口
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: ingress-nginx
  - ports:
    - protocol: TCP
      port: 8081
  #控制出站流量
  egress:
  #允许calico-system空间下标签带有app.kubernetes.io/name: whiske服务使用TCP访问标签带有app.kubernetes.io/name: goldmane服务的7443端口
  - ports:
    - port: 7443
      protocol: TCP
    to:
    - podSelector:
        matchLabels:
          app.kubernetes.io/name: goldmane
  #允许calico-system空间下标签带有app.kubernetes.io/name: whiske服务使用TCP/UDP访问kube-system空间下标签为k8s-app: kube-dns服务的53端口
  - ports:
    - port: 53
      protocol: TCP
    - port: 53
      protocol: UDP
    to:
    - namespaceSelector:
        matchLabels:
          projectcalico.org/name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns

评论 (0)