网络策略NetworkPolicy

红米11个月前技术文章265


目的:为了实现细粒度的容器间网络访问隔离策略。

引用:1.3版本NetworkPolicy机制 -> 1.8版本networking.k8s.io/v1稳定版本

功能:对pod、ns之间网络通信限制及准入控制,将目的label作为查询条件,设置允许、禁止访问的客户端pod列表,可作用于pod和ns级别。

原理:引用资源对象NetworkPolicy,配置的仅仅是策略规则,需要策略控制器Policy Controller(第三方网络组件提供)进行策略规则具体实现,目前calico、Kube-router等均支持网络策略实现。

Policy Controller实现API Listener,监听用户设置的NetworkPolicy定义,并将网络访问规则通过各node的Agent进行实际设置,Agent需要通过CNI网络插件实现。

01.png

calico-kube-controllers持续监听kubernetes NetworkPolicy定义,与各pod通过标签进行关联,将允许、拒绝访问的策略通知到各calico-node,最终calico-node完成对pod间网络访问间隔的设置,实现pod网络隔离。

02.png


在 IP 地址或端口层面(3网络层、4传输层)控制网络流量,为集群中特定应用使用网络策略

前置条件

网络策略通过网络插件来实现,要使用网络策略,必须使用支持 NetworkPolicy 的网络解决方案,创建一个 NetworkPolicy 资源对象而没有控制器来使它生效的话,是没有任何作用的。


注:

  1. 默认情况下Pod 是非隔离的,接受任何来源的流量,在设置了指定pod的NetworkPolicy网络策略后访问才会被限制。

  2. 一旦ns中有 NetworkPolicy 选择了特定的 Pod,该 Pod 会拒绝该 NetworkPolicy 所不允许的连接。 (ns下其他未被 NetworkPolicy 所选择的 Pod 会继续接受所有的流量)

  3. 网络策略不会冲突,如果任何一个或多个策略选择了一个 Pod, 则该 Pod 受限于这些策略的 入站(Ingress)/出站(Egress)规则的并集,因此评估的顺序并不会影响策略的结果。

  4. 为了允许两个 Pods 之间的网络数据流,源端 Pod 上的出站(Egress)规则和 目标端 Pod 上的入站(Ingress)规则都需要允许该流量。 如果源端的出站(Egress)规则或目标端的入站(Ingress)规则拒绝该流量, 则流量将被拒绝。

网络策略设置

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

podSelector:定义作用pod的范围,以上匹配标签为role=db的pod;

policyTypes:网络策略的类型ingress、egress,若未指定policyTypes,默认ingress类型;若指定了egress,自动设置egress;

ingress:允许访问目标pod的入站白名单;

egress:允许访问目标pod的出站白名单;

ipBlock:通常为集群外部地址,因为 Pod IP 存在时间短暂的且随机产生。

  1. 集群的入站和出站机制通常需要重写数据包的源 IP 或目标 IP。 在发生这种情况时,不确定在 NetworkPolicy 处理之前还是之后发生, 并且对于网络插件、云提供商、Service 实现等的不同组合,其行为可能会有所不同。

  2. 对入站流量而言,这意味着在某些情况下,你可以根据实际的原始源 IP 过滤传入的数据包, 而在其他情况下,NetworkPolicy 所作用的 源IP 则可能是 LoadBalancer 或 Pod 的节点等。

  3. 对于出站流量而言,这意味着从 Pod 到被重写为集群外部 IP 的 Service IP 的连接可能会或可能不会受到基于 ipBlock 的策略的约束。

selector

NO.1 from同时设置namespaceSelector和podSelector

允许从拥有user=alice标签的ns中 拥有role=client标签的pod发起访问

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

NO.2 from分别设置namespaceSelector和podSelector

允许user: alice标签的ns中任意pod发起访问

允许role: client标签的pod发起访问

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

端口范围

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
      
     允许ns=default中pod role=db的Pod使用TCP协议与10.0.0.0/24范围内的IP通信,目标端口介于32000 和 32768 之间

使用此字段时存在以下限制:

  1. 作为一种 Beta 阶段的特性,端口范围设定默认是被启用的,如需要在整个集群范围内禁止使用 endPort 字段,需要为 API 服务器设置 -feature-gates=NetworkPolicyEndPort=false,... 以禁用 NetworkPolicyEndPort 特性门控。

  2. endPort 字段必须 >= port字段的值

  3. 两个字段的设置值都只能是数字

  4. 集群所使用的CNI插件必须支持在 NetworkPolicy 规约中使用 endPort 字段。 如果网络插件不支持 endPort 字段,而又指定了包含 endPort 字段的 NetworkPolicy, 策略只对单个 port 字段生效。

      在1.20版本中,以下功能在网络策略仍无法实现,如需可以选择SELINUX,Open vSwitch,IPTables等;或7层网络技术Ingress Controller、Service Mesh等。

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

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

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

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

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

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

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

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

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

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

默认网络策略

namespace:设置默认全局网络策略,以便对整个命名空间进行统一网络管理。

1、默认拒绝所有入站流量:禁止任意客户端访问该ns下的任意pod,起到隔离访问的作用,确保即使容器没有选择其他任何 NetworkPolicy,也仍然可以被隔离,而不会更改默认的出口隔离行为。

service/networking/network-policy-default-deny-ingress.yaml

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

2、默认允许入站流量

service-networking-network-policy-allow-all-ingress-yaml

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

3、默认拒绝所有出站流量

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

4、默认允许所有出站流量

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

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

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

应用

允许client客户端匹配标签role:nginxclient访问server端nginx容器

server:nginx

client01 -> role:nginxclient

client02

1、Server

03.png

2、server:nginx设置网络策略

# cat networkpolicy-allow-nginxclient.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-nginx-client
  namespace: networkpolicy
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: nginxclient
    ports:
    - protocol: TCP
      port: 80

04.png

3、客户端pod

client01.yaml
apiVersion: v1
kind: Pod
metadata:
  name: client01
  labels:
    role: nginxclient
spec:
  containers:
  - name: client01
    image: busybox:1.28
    command: [ 'sleep', '3600' ]
===============
client02.yaml
apiVersion: v1
kind: Pod
metadata:
  name: client02
spec:
  containers:
  - name: client02
    image: busybox:1.28
    command: [ 'sleep', '3600' ]

05.png

4、验证

进入client01客户端,成功访问nginx服务,NetworkPolicy生效。

06.png

进入client02客户端,访问超时,NetworkPolicy生效,对没有role=nginxclient标签的客户端pod拒绝访问。

07.png





相关文章

CDH实操--集群关闭Kerberos

CDH实操--集群关闭Kerberos

1、关掉整个集群2、zookeeper配置搜索kerberos,将enable Kerberos配置关掉3、hdfs配置在输入框中填入[hadoop.security.auth] 进行搜索将安全身份认...

8.0 新特性-Generated Invisible Primary Key

8.0 新特性-Generated Invisible Primary Key

说明MySQL Innodb 引擎采用的是 IOT(索引组织表)存储方式,主键的重要性就不言而喻。在早期版本用户如果没有显式指定主键,会自动生成隐藏主键 row_id 来组织 B+ 树,隐藏主键 ro...

PromQL语法

PromQL语法

一、PromQL语法1.1、什么是PromQLPromQL(Prometheus Query Language)是 Prometheus 自己开发的表达式语言,语言表现力很丰富,内置函数也很多。使用它...

MongoDB的In-Memory存储引擎

   在企业版 3.2.6版本开始,MongoDB开始有In-Memory存储引擎,除了一些元数据和诊断数据外,In-Memory存储引擎不会存储任何数据到磁盘,包括配置数据、索引、用户凭证等。   ...

Kubernetes源码解读(四)--Lister&Watcher源码分析

Kubernetes源码解读(四)--Lister&Watcher源码分析

Lister&&Watcher是Reflector的一个主要能力提供者,我们来看看Lister&&Watcher是如何实现List()和watch()的过程的。List...

podman相关使用

Podman介绍Podman 是一个开源的容器运行时项目,可在大多数 Linux 平台上使用。Podman 提供与 Docker 非常相似的功能。正如前面提到的那样,它不需要在你的系统上运行任何守护进...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。