用k8s的networkpolicy模拟租户隔离、组间pod隔离

pod之间的通信默认是不隔离的,他们之是能相互通信的,但如果你想通过IP地址或者端口来管理网络通信,那么就可以使用k8s的networkpolicy功能。该功能的实现原理是默认都不通过,显示添加白名单。如果指定namespace,那么该network policy生效的范围是本namespace内。如果没有指定namespace,那么就是针对default namespace才能生效。另外network policy还会选择相应的pod来设置规则。下面通过两个例子来讲解network policy的使用方法。

模拟租户隔离

以下是一个模拟租户隔离的networkpolicy YAML文件,名称为user1.yaml.它对namespace为user1的有标签“appType=user1App”的Pod生效,只允许有“user=user1”的流入流量,对流出的流量不隔离。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: smlTenant
  namespace: user1
spec:
  podSelector:
    matchLabels:
      appType: user1App
  ingress:
  - from:
    - podSelector:
        matchLabels:
          user: user1
  egress:
  - {}
  policyTypes:
  - Ingress
  - Egress

必备字段:像其他Kubernetes配置一样,一个NetworkPolicy必备的字段有apiVersion, kind, and metadata.

  • spec:NetworkPolicy spec 拥有在给定名称空间中定义特定网络策略所需的所有信息。
  • namespace:注意这里的networkpolicy只对本域名内的资源生效。
  • podSelector:每个NetworkPolicy都包含一个podSelector,它选择策略应用到的pods分组。示例策略选择标签为“appType: user1App”的pods也就是说这个NetworkPolicy应用到标签为appType=user1App的pod中,NetworkPolicy对没有这个标签的pod不生效。一个空的podSelector选择名称空间中的所有pods。若果为{}表示所有pod.
  • policyTypes:每个NetworkPolicy都包含一个policyTypes列表,其中可以包含入口Ingress、出口Egress,也可以同时包含入口和出口。policyTypes字段指示给定的策略是否应用于将流量输入到选定的pod、将流量从选定的pod输出或同时应用于两者。如果在NetworkPolicy上没有指定策略类型,那么默认情况下将始终设置Ingress,如果NetworkPolicy有任何出口规则,则将具体设置Egress规则。
  • ingress:每个NetworkPolicy可能包括一个允许进入规则的列表。每个规则都允许匹配from和ports字段的流量。如果值为{},表示默认允许所有ingress流量;如果没有值表示不允许任何ingress流量。
  • egress:每个网络策略包括一张允许出口规则的列表。每个规则都允许匹配to和ports字段的流量。如果值为{},表示默认允许所有egress流量;如果没有值即egress: []表示不允许任何egress流量。
    因为要配合pod的标签使用,所以创建资源的yaml可以定义在busybox.yaml文件中,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  namespace: user1
  labels:
    app: busybox
spec:
  replicas: 1
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
        appType: user1App
        user: user1
    spec:
      containers:
      - name: busybox
        image: pml/busybox:0.1
        ports:
        - containerPort: 80

这样通过busybox.yaml创建的pod带有两个标签,一个是“appType=user1App”,该标签会让network policy生效。另外一个标签“user=user1”只允许user1的流量流入,从而达到模拟租户隔离的目的。但是egress中没有规则,也就是对egress不作限制,是可以通往外部namespace的。

网段隔离示例

该示例不限制ingress方向,只允许指定网段的出,即 DstIP 在101.1.0.0/16中才能出。因为允许域名解析所以放开53端口的通信。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: test-dvwa
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - {}
  egress:
  - to:
    - ipBlock:
        cidr: 101.1.0.0/16
  - to:          
    ports:
     - protocol: TCP
       port: 53
     - protocol: UDP 
       port: 53

注意ports前面的to不能去掉,否则就变成 101.1.0.0/16 且端口是53的才能出了。另外要限制的容器的namepace必须和networkpolicy的namespace一致。如上面的示例,该策略会生效到default 命名空间且带标签app=test-dvwa的容器上。如果运行两个网段出去,可以像下面这样定义:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: test-dvwa
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - {}
  egress:
  - to:
    - ipBlock:
        cidr: 101.1.0.0/16
  - to:
    - ipBlock:
        cidr: 172.18.8.0/24          
  - to:          
    ports:
     - protocol: TCP
       port: 53
     - protocol: UDP 
       port: 53

egress里面的几个to是或的关系,同一个to里面的多个条件是并且的关系。

参考文档

posted @ 2024-04-15 16:38  JaneySJ  阅读(109)  评论(0编辑  收藏  举报