Kubernetes Network Policy 详解与实践


Kubernetes Network Policy 详解与实践

Kubernetes 的 NetworkPolicy 是一种强大的工具,用于定义 Pod 之间的网络通信规则。本文将通过详细的解析和示例,帮助您理解如何使用 NetworkPolicy 控制 Pod 的入站(Ingress)和出站(Egress)流量。


一、引言

在 Kubernetes 集群中,NetworkPolicy 提供了一种声明式的方式来指定 Pod 间的通信规则。通过定义 NetworkPolicy,我们可以精细地控制 Pod 的入站和出站流量,从而增强集群的安全性。

本文将分为以下几个部分:

  1. 基础概念:介绍 NetworkPolicy 的基本结构和关键字段。
  2. Ingress 和 Egress 概述:讲解入站和出站流量的概念及其管理方式。
  3. 示例详解:通过 9 个具体示例,详细解析 NetworkPolicy 的配置和使用方法。
  4. 总结:回顾关键点并提供进一步学习的建议。

二、Network Policy 基础

NetworkPolicy 资源对象定义在 networking.k8s.io/v1 API 版本中,主要包含以下关键字段:

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 资源类型为 NetworkPolicy
metadata:
  name: example-networkpolicy # 网络策略名称
  namespace: default # 所属命名空间
spec:
  policyTypes:
  - Ingress # 定义入站流量规则
  podSelector: # 目标 Pod 的选择器
    matchLabels:
      app: web # 匹配标签为 app: web 的 Pod
  ingress: # 入站规则
  - from:
    - podSelector:
        matchLabels:
          app: db # 允许来源:标签为 app: db 的 Pod

关键字段说明:

  • apiVersion:指定使用的 API 版本。
  • kind:资源类型为 NetworkPolicy
  • metadata:包含网络策略的名称和所在的命名空间。
  • spec:网络策略的具体规则,包括 policyTypespodSelectoringressegress 等。

三、Ingress 和 Egress 概述

1. Ingress(入站流量)

Ingress 是 Kubernetes 中用于管理外部访问集群内部服务的 HTTP 和 HTTPS 路由的资源对象。它定义了路由规则,控制流量的路由,但本身不处理流量,而是依赖于 Ingress Controller 来实现流量处理。

Ingress 架构

Ingress 架构通常包括两个主要组件:

  • Ingress Controller:负责监听 Ingress 规则变化并据此更新负载均衡器配置。
  • Ingress 规则:定义了如何将外部流量路由到集群内部的服务。

示例

以下是一个简单的 Ingress 示例,定义了两个规则:

  • 将所有 /demo 请求发送到 demo-service 服务。
  • 将所有其他请求发送到 main-service 服务。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: basic-ingress
spec:
  rules:
  - http:
      paths:
      - path: /demo
        pathType: Prefix
        backend:
          service:
            name: demo-service
            port:
              number: 80
  defaultBackend:
    service:
      name: main-service
      port:
        number: 80

2. Egress(出站流量)

相对于 IngressEgress 代表离开 Kubernetes 集群的流量。在 Kubernetes 中,Egress 流量通常通过 Node 的网络接口直接发送到外部网络。虽然 Ingress 有专门的控制器和规则来管理,但 Egress 流量则相对简单,通常不需要特别的控制器或规则来管理(除非有特定的安全或策略需求)。


四、示例详解

以下是 9 个具体的 NetworkPolicy 示例,详细解析其配置和使用方法。

示例 1:基于 Pod 标签的入站规则

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
  name: tomcat-access--networkpolicy # 网络策略名称
  namespace: python # 所属命名空间
spec:
  policyTypes:
  - Ingress # 定义入站流量规则 也就是允许哪个 Pod 访问这个 Pod
  podSelector: # 目标 Pod 的选择器
    matchLabels:
      app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
  ingress: # 入站规则
  - from:
    - podSelector:
        matchLabels:
          project: "python" # 允许来源:标签为 project: python 的 Pod

示例 1:基于 Pod 标签的入站规则

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
  name: tomcat-access--networkpolicy # 网络策略名称
  namespace: python # 所属命名空间
spec:
  policyTypes:
  - Ingress # 定义入站流量规则
  podSelector: # 目标 Pod 的选择器
    matchLabels:
      app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
  ingress: # 入站规则
  - from:
    - podSelector:
        matchLabels:
          project: "python" # 允许来源:标签为 project: python 的 Pod

示例 2:基于 Pod 标签和端口的入站规则

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
  name: tomcat-access--networkpolicy # 网络策略名称
  namespace: python # 所属命名空间
spec:
  policyTypes:
  - Ingress # 定义入站流量规则
  podSelector: # 目标 Pod 的选择器
    matchLabels:
      app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
  ingress: # 入站规则
  - from:
    - podSelector:
        matchLabels:
          project: "python" # 允许来源:标签为 project: python 的 Pod
    ports:
    - protocol: TCP # 指定协议:TCP
      port: 8080 # 指定端口:8080

注释说明

  • ports 字段限制了允许访问的协议和端口。
  • 在此示例中,仅允许来自标签为 project: python 的 Pod 通过 TCP 协议访问目标 Pod 的 8080 端口。

示例 3:多端口入站规则

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
  name: tomcat-access--networkpolicy # 网络策略名称
  namespace: python # 所属命名空间
spec:
  policyTypes:
  - Ingress # 定义入站流量规则
  podSelector: # 目标 Pod 的选择器
    matchLabels:
      app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
  ingress: # 入站规则
  - from:
    - podSelector: {} # 不限制来源 Pod
    ports:
    - protocol: TCP # 指定协议:TCP
      port: 8080 # 指定端口:8080
    - protocol: TCP
      port: 3306 # 指定端口:3306
    - protocol: TCP
      port: 6379 # 指定端口:6379

注释说明

  • from 中的 podSelector: {} 表示不限制来源 Pod。
  • ports 列出了多个端口和协议,允许访问的目标 Pod 的这些端口。

示例 4:不限制源 Pod 的入站规则

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
  name: tomcat-access--networkpolicy # 网络策略名称
  namespace: python # 所属命名空间
spec:
  policyTypes:
  - Ingress # 定义入站流量规则
  podSelector: # 目标 Pod 的选择器
    matchLabels: {} # 匹配所有目标 Pod
  ingress: # 入站规则
  - from:
    - podSelector: {} # 不限制来源 Pod

注释说明

  • podSelector: {} 表示该规则适用于命名空间中的所有 Pod。
  • from 中的 podSelector: {} 表示不限制来源 Pod。

示例 5:基于 IP 段的入站规则

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
  name: tomcat-access--networkpolicy # 网络策略名称
  namespace: python # 所属命名空间
spec:
  policyTypes:
  - Ingress # 定义入站流量规则
  podSelector: # 目标 Pod 的选择器
    matchLabels:
      app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
  ingress: # 入站规则
  - from:
    - ipBlock:
        cidr: 10.200.0.0/16 # 允许来自 10.200.0.0/16 网段的 IP 地址

注释说明

  • ipBlock 定义了允许访问的 IP 地址范围。
  • 在此示例中,仅允许来自 10.200.0.0/16 网段的 IP 地址访问目标 Pod。

示例 6:基于 Namespace 标签的入站规则

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
  name: tomcat-access--networkpolicy # 网络策略名称
  namespace: python # 所属命名空间
spec:
  policyTypes:
  - Ingress # 定义入站流量规则
  podSelector: # 目标 Pod 的选择器
    matchLabels: {} # 匹配命名空间中的所有 Pod
  ingress: # 入站规则
  - from:
    - namespaceSelector:
        matchLabels:
          nsname: linux # 允许来源:标签为 nsname: linux 的 Namespace
    ports:
    - protocol: TCP # 指定协议:TCP
      port: 8080 # 指定端口:8080
    - protocol: TCP
      port: 3306 # 指定端口:3306
    - protocol: TCP
      port: 6379 # 指定端口:6379

注释说明

  • namespaceSelector 定义了允许访问的 Namespace。
  • 在此示例中,仅允许来自标签为 nsname: linux 的 Namespace 中的 Pod 访问目标 Pod 的指定端口。

示例 7:基于 IP 段的出站规则

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
  name: egress-access-networkpolicy # 网络策略名称
  namespace: python # 所属命名空间
spec:
  policyTypes:
  - Egress # 定义出站流量规则
  podSelector: # 目标 Pod 的选择器
    matchLabels:
      app: python-tomcat-app1-selector # 匹配标签为 app: python-tomcat-app1-selector 的 Pod
  egress: # 出站规则
  - to:
    - ipBlock:
        cidr: 10.200.0.0/16 # 允许访问 10.200.0.0/16 网段的 IP 地址

注释说明

  • egress 定义了出站流量规则。
  • 在此示例中,仅允许目标 Pod 访问 10.200.0.0/16 网段的 IP 地址。

示例 8:基于 Pod 标签的出站规则

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
  name: egress-access-networkpolicy # 网络策略名称
  namespace: python # 所属命名空间
spec:
  policyTypes:
  - Egress # 定义出站流量规则
  podSelector: # 目标 Pod 的选择器
    matchLabels:
      app: python-nginx-selector # 匹配标签为 app: python-nginx-selector 的 Pod
  egress: # 出站规则
  - to:
    - podSelector:
        matchLabels:
          app: python-tomcat-app1-selector # 允许访问:标签为 app: python-tomcat-app1-selector 的 Pod
    ports:
    - protocol: TCP # 指定协议:TCP
      port: 8080 # 指定端口:8080
    - protocol: TCP
      port: 53 # 指定端口:53
    - protocol: UDP
      port: 53 # 指定端口:53

注释说明

  • to 定义了允许访问的目标 Pod。
  • 在此示例中,仅允许目标 Pod 访问标签为 app: python-tomcat-app1-selector 的 Pod 的指定端口。

示例 9:基于 Namespace 标签的出站规则

apiVersion: networking.k8s.io/v1 # API 版本
kind: NetworkPolicy # 网络策略资源类型
metadata:
  name: egress-access-networkpolicy # 网络策略名称
  namespace: python # 所属命名空间
spec:
  policyTypes:
  - Egress # 定义出站流量规则
  podSelector: # 目标 Pod 的选择器
    matchLabels:
      app: python-nginx-selector # 匹配标签为 app: python-nginx-selector 的 Pod
  egress: # 出站规则
  - to:
    - namespaceSelector:
        matchLabels:
          nsname: python # 允许访问:标签为 nsname: python 的 Namespace
    - namespaceSelector:
        matchLabels:
          nsname: linux # 允许访问:标签为 nsname: linux 的 Namespace
    ports:
    - protocol: TCP # 指定协议:TCP
      port: 8080 # 指定端口:8080
    - protocol: TCP
      port: 53 # 指定端口:53
    - protocol: UDP
      port: 53 # 指定端口:53

注释说明

  • namespaceSelector 定义了允许访问的 Namespace。
  • 在此示例中,仅允许目标 Pod 访问标签为 nsname: pythonnsname: linux 的 Namespace 中的 Pod 的指定端口。


五、总结

1. 核心概念回顾

  • NetworkPolicy:用于定义 Pod 间通信规则的核心资源对象。
  • Ingress:管理进入集群的流量,通常通过 Ingress Controller 实现。
  • Egress:管理离开集群的流量,通常需要额外的安全策略。

2. 关键字段

  • apiVersionkind:定义资源类型和 API 版本。
  • metadata:指定资源名称和命名空间。
  • spec:定义具体的规则,包括 policyTypespodSelectoringressegress

3. 应用场景

  • 安全性:通过限制 Pod 间的通信,防止未经授权的访问。
  • 流量管理:精确控制流量的流向,优化资源利用率。
  • 多租户环境:隔离不同租户的网络通信,确保数据安全。

4. 下一步学习建议

  • 学习更多关于 CNI 插件的知识,了解它们如何支持 NetworkPolicy
  • 探索 Ingress Controller 的高级功能,例如 SSL/TLS 支持和负载均衡。
  • 实践复杂的网络策略,结合实际业务场景进行优化。

希望本文能帮助您更好地理解和应用 Kubernetes 的 NetworkPolicy!如果您有任何疑问或需要进一步的帮助,请随时留言交流!


如果还有其他需求,请告诉我!