14、K8S-NetworkPolicy

文章目录

一、概述

在Kubernetes中,NetworkPolicy是一项关键功能,它允许开发者定义和控制Pod之间的网络通信。本文将深入研究Kubernetes中的NetworkPolicy,详细介绍其原理、用途,并通过实际示例演示如何使用NetworkPolicy来确保集群中的网络安全。

1、什么是NetworkPolicy?

NetworkPolicy是Kubernetes中用于定义Pod之间网络通信规则的资源对象。通过NetworkPolicy,开发者可以控制哪些Pod可以与另外哪些Pod通信,以及使用何种方式进行通信。这种细粒度的网络控制有助于提高集群的安全性,防止未经授权的访问和通信。

2、NetworkPolicy的基本原理

NetworkPolicy的工作原理基于以下几个核心概念:

  1. Pod选择器(PodSelector)& namespaceSelector:NetworkPolicy使用标签选择器来选择特定的Pod。通过标签,可以将网络策略应用于特定的Pod群体。
  2. Ingress规则:定义了允许从其他Pod进入被选中Pod的规则,包括允许的协议、端口范围等。
  3. Egress规则:定义了允许被选中Pod访问其他Pod或外部网络的规则。
  4. Peer Pod:NetworkPolicy中的规则是基于Peer Pod(对等Pod)的。通过选择Peer Pod,可以精确定义通信策略。

二、NetworkPolicy资源清单

apl 复制代码
apiVersion: networking.k8s.io/v1          # 使用网络策略的稳定 API 组和版本
kind: NetworkPolicy                       # 资源类型:网络策略
metadata:                                 # 元数据开始
  name: test-network-policy               # 策略名称,用于标识
  namespace: default                      # 策略生效的命名空间(作用于 default 内的 Pod)
spec:                                     # 规格说明开始
  podSelector:                            # 选择哪些 Pod 应用此策略
    matchLabels:                          # 通过标签匹配
      app: backend                        # 选择带有 app=backend 标签的 Pod 作为目标 Pod
  ingress:                                # 入站规则列表(默认拒绝所有未明确允许的入站流量)
    - from:                               # 允许的来源列表
        - podSelector:                    # 来源1:通过 Pod 标签选择
            matchLabels:
              app: frontend               # 允许带有 app=frontend 标签的 Pod 访问目标 Pod
        - ipBlock:                        # 来源2:通过 IP 地址段选择
            cidr: 192.168.1.0/24          # 允许来自 192.168.1.0/24 网段的流量访问目标 Pod
      ports:                              # 允许访问的端口列表
        - protocol: TCP                   # 协议:TCP
          port: 8080                      # 只允许访问目标 Pod 的 8080 端口
  egress:                                 # 出站规则列表(默认拒绝所有未明确允许的出站流量)
    - to:                                 # 允许的目标列表
        - podSelector:                    # 目标1:通过 Pod 标签选择
            matchLabels:
              app: database               # 允许目标 Pod 访问带有 app=database 标签的 Pod
      ports:                              # 允许访问的端口列表
        - protocol: TCP                   # 协议:TCP
          port: 3306                      # 目标 Pod 访问其他 Pod 时只允许使用 3306 端口

三、NetworkPolicy的示例

示例一:不允许相同Namespace下的Pod通信

【注意】提前给命名空间设置labels

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-same-namespace
  namespace: default  # 改成你要限制的命名空间
spec:
  # 作用于命名空间内所有 Pod
  podSelector: {}

  # 拒绝所有入站流量
  policyTypes:
  - Ingress

  # 入站规则为空 = 拒绝所有入站
  ingress: []
  
####禁止default命令空间一切访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: full-isolation
  namespace: default  # 改成你要隔离的命名空间
spec:
  # 匹配命名空间下所有 Pod
  podSelector: {}
  
  # 同时控制 入站 + 出站 流量(核心!缺一不可)
  policyTypes:
  - Ingress
  - Egress
  
  # 1. 拒绝所有入站流量(任何Pod都不能访问我)
  ingress: []
  
  # 2. 拒绝所有出站流量(我不能访问任何Pod)
  egress: []
示例二:限制与外部访问
yaml 复制代码
①
##(被选中的 Pod 被"封闭"在当前命名空间内部,只能与同命名空间内的 Pod 交互,无法与外界通信。常用于保护内网敏感服务、限制容器访问外网等场景。)

apiVersion: networking.k8s.io/v1          # 使用网络策略的稳定 API 组和版本(必须完整填写)
kind: NetworkPolicy                       # 资源类型:网络策略
metadata:                                 # 元数据部分开始
  name: deny-external-traffic             # 策略名称,用于标识
  namespace: network1                     # 策略生效的命名空间(只作用于 network1 内的 Pod)
spec:                                     # 规格说明开始
  podSelector:                            # 选择哪些 Pod 应用此策略
    matchLabels:                          # 通过标签匹配
      app: nginx                          # 只作用于标签为 app=nginx 的 Pod
  policyTypes:                            # 声明此策略控制哪些方向的流量
  - Ingress                               # 控制入站流量(进入 Pod)
  - Egress                                # 控制出站流量(从 Pod 发出)
  ingress:                                # 入站规则列表
  - from:                                 # 允许的来源列表
    - podSelector: {}                     # 空的选择器表示允许同命名空间内所有 Pod 的入站流量
  egress:                                 # 出站规则列表
  - to:                                   # 允许的目标列表
    - podSelector: {}                     # 空的选择器表示允许访问同命名空间内所有 Pod 的出站流量
  
  
#### 该策略不会影响同一个命名空间内没有 app: nginx 标签的其他 Pod,也不会影响从本 Pod 发往集群内部 DNS、kube-apiserver 等关键服务的流量(如果需要额外放通,可在 egress 中添加对应规则,例如允许访问 kube-system 命名空间的 DNS Pod)。


    
②
#######允许本命名空间的pod之间的访问,及与default命名空间下的访问,但不允许对其他网络的访问

###在 network1 命名空间中,对标签为 app: nginx 的 Pod 实施网络隔离,允许它们与同命名空间内的所有 Pod 双向通信,同时允许它们访问 default 命名空间中的所有 Pod (出站方向),但拒绝所有其他流量。

apiVersion: networking.k8s.io/v1          # 使用网络策略的稳定 API 组和版本(必须完整)
kind: NetworkPolicy                       # 资源类型:网络策略
metadata:                                 # 元数据开始
  name: deny-external-traffic             # 策略名称,用于标识
  namespace: network1                     # 策略生效的命名空间(只作用于 network1 内的 Pod)
spec:                                     # 规格说明开始
  podSelector:                            # 选择要应用策略的 Pod
    matchLabels:                          # 通过标签匹配
      app: nginx                          # 只作用于标签为 app=nginx 的 Pod
  policyTypes:                            # 声明此策略控制哪些方向的流量
  - Ingress                               # 控制入站流量(进入 Pod)
  - Egress                                # 控制出站流量(从 Pod 发出)
  ingress:                                # 入站规则列表
  - from:                                 # 允许的来源列表
    - podSelector: {}                     # 空的选择器表示允许同命名空间内所有 Pod 的入站流量
  egress:                                 # 出站规则列表
  - to:                                   # 允许的目标列表
    - podSelector: {}                     # 允许访问同命名空间内任意 Pod
    - namespaceSelector:                  # 允许访问特定命名空间内的所有 Pod
        matchLabels:                      # 通过命名空间的标签匹配
          kubernetes.io/metadata.name: default   # 匹配名称为 default 的命名空间

在这个示例中,我们创建了一个名为"deny-external-traffic"的NetworkPolicy,限制了标签为app: sensitive-app的Pod的Ingress和Egress。该策略允许Pod之间的通信,但不允许访问任何外部网络。

示例三:指定端口范围
yaml 复制代码
apiVersion: networking.k8s.io/v1          # 使用网络策略的稳定 API 组和版本(必须完整)
kind: NetworkPolicy                       # 资源类型:网络策略
metadata:                                 # 元数据开始
  name: allow-specific-ports              # 策略名称,用于标识
spec:                                     # 规格说明开始
  podSelector:                            # 选择哪些 Pod 应用此策略
    matchLabels:                          # 通过标签匹配
      app: frontend                       # 只作用于标签为 app=frontend 的 Pod
  ingress:                                # 入站规则列表(注意:未声明 policyTypes,默认只控制入站)
  - ports:                                # 允许的端口列表
    - protocol: TCP                       # 协议类型:TCP
      port: 80                            # 端口号:80
    - protocol: UDP                       # 协议类型:UDP
      port: 53                            # 端口号:53

在这个示例中,我们创建了一个名为"allow-specific-ports"的NetworkPolicy,指定了标签为app: frontend的Pod的Ingress规则。该规则允许从其他Pod进入的流量,其中包括TCP端口80和UDP端口53。

四、限制其他命名空间中的pod访问podSelector匹配到的pod
apl 复制代码
apiVersion: networking.k8s.io/v1          # 使用网络策略的稳定 API 组和版本(必须完整)
kind: NetworkPolicy                       # 资源类型:网络策略
metadata:                                 # 元数据开始
  name: deny-external-traffic             # 策略名称,用于标识
  namespace: network1                     # 策略生效的命名空间(作用于 network1 内的 Pod)
spec:                                     # 规格说明开始
  podSelector:                            # 选择哪些 Pod 应用此策略
    matchLabels:                          # 通过标签匹配
      app: nginx                          # 只作用于标签为 app=nginx 的 Pod
  policyTypes:                            # 声明此策略控制的流量方向
  - Ingress                               # 只控制入站流量(进入 Pod),出站不受影响
  ingress:                                # 入站规则列表(默认拒绝所有未明确允许的入站)
  - from:                                 # 允许的来源列表
    - podSelector: {}                     # 来源1:允许同命名空间(network1)内所有 Pod 的入站流量
    - namespaceSelector:                  # 来源2:通过命名空间标签选择来源
        matchLabels:                      # 匹配命名空间的标签
          ns: network1                    # 允许带有标签 ns=network1 的命名空间内的所有 Pod 访问
五、只访问外部网络和同命名空间下的pod

现在有如下需求: 使用networkpolicy实现在myns1命名空间下的所有label为app: alpine的pod可以与myns1命名空间中的其他pod和外部互联网通信,不能与其他命名空间中的任何pod通信。请编写资源清单文件。

【注意】 pod访问带有svc的pod时,可以通过svcFQDN访问。

apl 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: alpine-communication-policy
  namespace: network1  # 策略仅作用于 myns1 命名空间
spec:
  podSelector:
    matchLabels:
      app: nginx  # 目标 Pod:network1 中所有标签为 app: nginx 的 Pod
  policyTypes:
  - Ingress  # 控制入站流量
  - Egress   # 控制出站流量

  # ------------------------------
  # 入站规则:仅允许 network1 内 Pod 访问
  # ------------------------------
  ingress:
  - from:
    - podSelector: {}  # 匹配 network1 命名空间内的所有 Pod(无标签过滤)
    # 无端口限制(允许所有端口),如需限制端口可添加 ports 字段

  # ------------------------------
  # 出站规则:允许访问 network1 内 Pod 和外部互联网,拒绝其他命名空间
  # ------------------------------
  egress:
  # 规则 1:允许访问 network1 命名空间内的所有 Pod(包括自身)
  - to:
    - podSelector: {}  # 匹配当前命名空间(network1)的所有 Pod

  # 规则 2:允许访问外部互联网(非集群内部 IP)
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0  # 允许所有 IPv4 地址(需排除集群内部 CIDR)
        except:
        # 重要:替换为集群实际的 Pod CIDR 和 Service CIDR
        - 10.244.0.0/16  # 示例:calico 默认 Pod CIDR(需根据集群调整)
        - 10.96.0.0/12   # 示例:Kubernetes Service 默认 CIDR(需根据集群调整)

  # 规则 3:允许 DNS 解析(关键!否则无法访问外部域名)
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system  # kube-dns 所在命名空间
      podSelector:
        matchLabels:
          k8s-app: kube-dns  # kube-dns Pod 标签(可能因集群不同而变化)
    ports:
      - protocol: UDP
        port: 53  # DNS UDP 端口
      - protocol: TCP
        port: 53  # DNS TCP 端口(用于长查询) 

四、NetworkPolicy的高级用法(了解)

除了基本的示例外,NetworkPolicy还支持一些高级用法,如网络策略的继承、Peer Pod选择器的高级匹配等。以下是一些高级用法的示例:

1、网络策略的继承
yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: parent-policy
spec:
  podSelector:
    matchLabels:
      role: parent
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: child

---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: child-policy
spec:
  podSelector:
    matchLabels:
      role: child
  policyTypes:
  - Ingress
  - Egress

在这个示例中,我们创建了两个NetworkPolicy。"parent-policy"用于选择标签为role: parent的Pod,并定义了一个Ingress规则,允许来自标签为role: child的Pod的通信。"child-policy"选择标签为role: child的Pod,并定义了Ingress和Egress规则。这样,"child-policy"继承了"parent-policy"的规则。

2、高级Peer Pod选择器匹配
yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: advanced-selector-matching
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - podSelector:
        matchExpressions:
        - {key: role, operator: In, values: [frontend, middleware]}

在这个示例中,我们通过matchExpressions定义了更复杂的Peer Pod选择器匹配条件。该规则选择标签为app: backend的Pod,并定义了一个Ingress规则,允许来自标签为rolefrontendmiddleware的Pod的通信。

相关推荐
日取其半万世不竭1 小时前
Tekton:Kubernetes 原生 CI/CD 流水线
ci/cd·kubernetes·tekton
Splashtop高性能远程控制软件1 小时前
切屏时代终结,Splashtop 统一 IT 运维平台助力 MSP 高效运营
运维·自动化·远程控制·splashtop
9命怪猫1 小时前
[K8S小白问题集] - Flannel是K8S默认CNI吗?怎么实现的Overlay网络?
网络·容器·kubernetes
小此方1 小时前
Re:Linux系统篇(十二)工具篇 · 四:make与Makefile:高效管理 C++ 工程项目构建
linux·运维·c++·开发工具
隔窗听雨眠1 小时前
读懂AI自动化的两种范式
运维·人工智能·自动化
老陈聊架构1 小时前
『DevOps运维』从零搭建企业微信告警机器人:接口对接、消息模板与自动化通知
运维·企业微信·devops·消息·群机器人
Harvy_没救了1 小时前
【虚拟容器-docker】docker核心“铁三角“--网络、存储、镜像管理
网络·docker·容器
手揽回忆怎么睡1 小时前
京东云Ubuntu22..04安装jdk21、MySQL8、nginx
运维·nginx·京东云
小此方1 小时前
Re:Linux系统篇(十一)工具篇 · 三:三分钟学会gcc/g++编译工具&&初步认识动静态库&&重温编译基本原理
linux·运维·服务器·开发工具