问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Kubernetes之network policy解析

创作时间:
作者:
@小白创作中心

Kubernetes之network policy解析

引用
CSDN
1.
https://blog.csdn.net/weixin_43539320/article/details/139010692

Kubernetes的Network Policy是实现基于策略的网络控制的重要机制,它允许管理员通过标签选择器来控制Pod之间的网络流量。本文将详细介绍Network Policy的概念、配置方法和使用场景,帮助读者更好地理解和使用这一功能。

一、概念

Network Policy提供了基于策略的网络控制,是针对 TCP、UDP 和 SCTP 协议在 IP 地址或端口层面控制网络流,用于隔离应用并减少攻击面。它使用标签选择器模拟传统的分段网络,并通过策略控制它们之间的流量以及来自外部的流量;目前基于linux iptables实现,使用类似nf_conntrack检查记录网络流量session从而决定流量是否阻断;因此它是状态检测防火墙

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

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

1、前置条件

首先需要有一个支持网络策略的 Kubernetes 集群。已经有许多支持 NetworkPolicy 的网络提供商,包括:

2、pod隔离的两种类型

默认情况下,一个pod的出口和入口都是非隔离的,即pod的所有出站以及入站都是没有限制的

网络策略是相加的,所以不会产生冲突,但是如果要单独允许某一个pod间的连接,源pod和出口策略和目标pod的入口策略都需要配置。

3、NetworkPolicy 资源

以下为资源示例

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
  • 策略作用的对象Pods:default命名空间下带有role=db标签的Pod

    • 内向流量策略

      • 允许属于172.17.0.0/16网段但不属于172.17.1.0/24的源地址访问该对象Pods的TCP 6379端口
      • 允许带有project=myprojects标签的namespace中所有Pod访问该对象Pods的TCP 6379端口
      • 允许default命名空间下带有role=frontend标签的Pod访问该对象Pods的TCP 6379端口
      • 拒绝其他所有主动访问该对象Pods的网络流量
    • 外向流量策略

      • 允许该对象Pods主动访问目的地址属于10.0.0.0/24网段且目的端口为TCP 5978的流量
      • 拒绝该对象Pods其他所有主动外向网络流量

4、选择器to、from

  ingress:
- from:
- namespaceSelector:
        matchLabels:
          user: alice
      podSelector:
        matchLabels:
          role: client

此策略在 from 数组中仅包含一个元素,表示两种条件都必须满足,即只允许来自拥有role=client标签的pod且所有在的名称空间中标有user=alice 的连接

  ingress:
- from:
- namespaceSelector:
        matchLabels:
          user: alice
- podSelector:
        matchLabels:
          role: client

此策略在 from 数组中仅包含两个元素,表示两种条件满足其一即可,即允许来自拥有role=client标签的pod或者任何pod所在的名称空间中标有user=alice 的连接

5、默认策略

默认情况下,则不存在任何策略,但是我们可以更改默认的策略。

默认拒绝所有入站和出站流量

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

此策略可以确保即使没有被其他任何 NetworkPolicy 选择的 Pod 也不会被允许入站或出站流量

6、对端口范围进行限制(1.25 stable)

在编写 NetworkPolicy 时,你可以针对一个端口范围而不是某个固定端口。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: multi-port-egress
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
- Egress
  egress:
- to:
- ipBlock:
            cidr: 10.0.0.0/24
      ports:
- protocol: TCP
          port: 32000
          endPort: 32768

此准则表示允许default名称空间中所有带role: db标签的pod使用tcp协议与10.0.0.0/24网段内,并且目标端口为32000到32768之间。

7、使用hostNetwork 类型的Pod

网络插件无法正确辨别 hostNetwork Pod 流量,因此在匹配 podSelectornamespaceSelector 时会忽略 hostNetwork Pod。流向/来自 hostNetwork Pod 的流量的处理方式与流向/来自节点 IP 的所有其他流量一样。(这是最常见的实现方式。)也就是说会将使用hostNetwork 类型的Pod识别为一个物理机,而不再是pod,可以使用 ipBlock 规则允许来自 hostNetwork Pod 的流量。

二、使用场景

1、拒绝其他的namespace的访问

  • 场景1:你的k8s集群应用按照namespaces区分生产、测试环境,你要确保生产环境不会受到测试环境错误访问影响
  • 场景2:你的k8s集群有多租户应用采用namespaces区分的,你要确保多租户之间的应用隔离

在你需要隔离的命名空间创建如下策略:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  namespace: your-ns
  name: deny-other-namespaces
spec:
  podSelector:
    matchLabels:
  ingress:
- from:
- podSelector: {}

2、允许外部访问服务

# 创建示例应用待暴露服务
$ kubectl run web --image=nginx --labels=app=web --port 80 --expose

# 创建网络策略
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-allow-external
spec:
  podSelector:
    matchLabels:
      app: web
  ingress:
- from: []
    ports:
- protocol: TCP
      port: 80

三、目前无法实现的功能

截止到1.30版本

  • 强制集群内部流量经过某公用网关(这种场景最好通过服务网格或其他代理来实现);

  • 与 TLS 相关的场景(考虑使用服务网格或者 Ingress 控制器);

  • 特定于节点的策略(你可以使用 CIDR 来表达这一需求不过你无法使用节点在 Kubernetes 中的其他标识信息来辩识目标节点);

  • 基于名字来选择服务(不过,你可以使用 标签 来选择目标 Pod 或名字空间,这也通常是一种可靠的替代方案);

  • 创建或管理由第三方来实际完成的“策略请求”;

  • 实现适用于所有名字空间或 Pod 的默认策略(某些第三方 Kubernetes 发行版本或项目可以做到这点);

  • 高级的策略查询或者可达性相关工具;

  • 生成网络安全事件日志的能力(例如,被阻塞或接收的连接请求);

  • 显式地拒绝策略的能力(目前,NetworkPolicy 的模型默认采用拒绝操作, 其唯一的能力是添加允许策略);

  • 禁止本地回路或指向宿主的网络流量(Pod 目前无法阻塞 localhost 访问, 它们也无法禁止来自所在节点的访问请求)。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号