K8S - NetworkPolicy的使用

  • [1 前置条件](#1 前置条件)
  • [2 控制范围](#2 控制范围)
  • [3 隔离类型](#3 隔离类型)
  • [4 如何识别](#4 如何识别)
  • [5 主要字段](#5 主要字段)
  • [6 案例演示](#6 案例演示)

前置条件

网络策略通过网络插件来实现。 要使用网络策略,你必须使用支持 NetworkPolicy 的网络解决方案。 创建一个 NetworkPolicy 资源对象而没有控制器来使它生效的话,是没有任何作用的。那么如何查看我们的集群中是否有这个资源呢?如果你使用的CNI网络查件是Flannel, 是不支持的, Calico是支持的.

复制代码
检查API版本兼容性
]# kubectl api-versions | grep networking.k8s.io
networking.k8s.io/v1
]# kubectl api-resources | grep -i networkpolicy
globalnetworkpolicies                          crd.projectcalico.org/v1               false        GlobalNetworkPolicy
networkpolicies                                crd.projectcalico.org/v1               true         NetworkPolicy
networkpolicies                   netpol       networking.k8s.io/v1                   true         NetworkPolicy

下面我们简单创建一个networkpolicy资源来检查下是否能正常使用.

复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-policy
spec:
  podSelector: {}
  policyTypes:
  - Ingress

]# kubectl apply -f networkpolicy_functest.yaml
]# kubectl get networkpolicy   #可以看到创建成功了

控制范围

OSI 第 3 层或第 4 层. 如果你想在7层控制流量,可以考虑使用istio,后面我会专门演示istio的使用案例

隔离类型

  1. 出口的隔离 policyTypes: "Egress"
  2. 入口的隔离 policyTypes: "Ingress"

如何识别

Pod 可以与之通信的实体是通过如下三个标识符的组合来辩识的:

  • 其他被允许的 Pod(例外:Pod 无法阻塞对自身的访问)
  • 被允许的名字空间
  • IP 组块(例外:与 Pod 运行所在的节点的通信总是被允许的, 无论 Pod 或节点的 IP 地址)

主要字段

apiVersion : 必须字段,不同版本可能group和version有所差别,通过explain命令可以查看当前k8s版本支持的apiVersion,如下图所示,我的k8s版本是1.28,所以他的networkpolicy 接口的apiVersion应该是 networking.k8s.io/v1

kind : 必须字段, 填NetworkPolicy

metadata : 必须字段,需要指定一些元数据,例如name

spec : 包含了在一个名字空间中定义特定网络策略所需的所有信息

podSelector : 对该策略所适用的一组 Pod 进行选择。示例中的策略选择带有 "role=db" 标签的 Pod。 空的 podSelector 选择名字空间下的所有 Pod。

policyTypes : 包含 Ingress 或 Egress 或两者兼具。policyTypes 字段表示给定的策略是应用于进入所选 Pod 的入站流量还是来自所选 Pod 的出站流量,或两者兼有。 如果 NetworkPolicy 未指定 policyTypes 则默认情况下始终设置 Ingress; 如果 NetworkPolicy 有任何出口规则的话则设置 Egress。

ingress : 每个 NetworkPolicy 可包含一个 ingress 规则的白名单列表。 每个规则都允许同时匹配 from 和 ports 部分的流量。

egress : 每个 NetworkPolicy 可包含一个 egress 规则的白名单列表。 每个规则都允许匹配 to 和 ports 部分的流量。

下面我们来分析一个示例:

复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

该示例表达的是:

 1. 隔离 default 名字空间下 role=db 的 Pod 
 2. Ingress 规则)允许以下 Pod 连接到 default 名字空间下的带有 role=db 标签的所有 Pod 的 6379 TCP 端口:
	- default 名字空间下带有 role=frontend 标签的所有 Pod
	- 带有 project=myproject 标签的所有名字空间中的 Pod
	- IP 地址范围为 172.17.0.0--172.17.0.255 和 172.17.2.0--172.17.255.255 (即,除了 172.17.1.0/24 之外的所有 172.17.0.0/16)
 3. (Egress 规则)允许 default 名字空间中任何带有标签 role=db 的 Pod 到 CIDR 10.0.0.0/24 下 5978 TCP 端口的连接。

案例演示

下面我来演示一个案例. 我已经安装好了一个k8s集群 版本是1.28的, 而且部署好了monitoring. 我们就简单的拿grafana来举个例子, grafana我开放了两种访问方式,

一种是4层,通过NodePort方式,

一种是创建了Ingress七层访问,不过他们的最终链路都是一样的

可以看到不管是浏览器还是curl,都正常跳转和返回数据



可以看到目前我访问grafana页面正常,下面是我的ing和svc资源


下面我创建networkpolicy资源,yaml如下

复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: grafana-network-policy
  namespace: monitoring
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: grafana 
  policyTypes:
  - Ingress
  ingress:
  - from:
    - ipBlock:
        cidr: 10.233.58.225/32
    ports:
    - protocol: TCP
      port: 80 
我来apply 一下

ok. 已经生效. 我们再次访问grafana测试下


为了验证下这个networkpolicy确实只作用于monitoring命名空间下的grafana这个pod上,我们进入Alert

Pod去nc 探测grafana svc的端口是否被阻断。

那我们进入Grafana的pod上去反向探测下alert端口。

可以看到,符合预期. 下面我们删除networkpolicy.在测试下

再次从alert pod内部去nc grafana的Svc:80端口。

网页也恢复正常. 后面我会测试7层 service mesh相关的Istio案例.

相关推荐
致宏Rex15 小时前
Docker 实战教程(7) | 镜像管理和仓库操作
运维·docker·容器
罗技12315 小时前
不用每次都改 `easysearch.yml` 也能改启动参数 —— 用 Docker 环境变量搞定一切
docker·容器·eureka
落日漫游17 小时前
Kubernetes容器运行时:cri-docker vs containerd
docker·kubernetes
2501_920047031 天前
k8s-ingress控制器
云原生·容器·kubernetes
K_i1341 天前
Docker、容器、虚拟机到底是什么
docker·微服务·云原生·容器·kubernetes
江湖有缘1 天前
【Docker项目实战】使用Docker部署ShowDoc文档管理工具
java·docker·容器
XYiFfang1 天前
【Docker】解决Docker中“exec format error”错误:架构不匹配的完整指南
docker·容器·架构
致宏Rex2 天前
Docker 完整教程(3,4) | 网络与挂载
运维·docker·容器
Broken Arrows2 天前
k8s学习(二)——kubernetes整体架构及组件解析
学习·架构·kubernetes
荣光波比2 天前
Docker(三)—— Docker Compose 编排与 Harbor 私有仓库实战指南
运维·docker·容器·云计算