k8s-使用Network Policies实现网络隔离

打印 上一主题 下一主题

主题 862|帖子 862|积分 2586

一、需求

Kubernetes 的定名空间主要用于组织和隔离资源,但默认情况下,不同定名空间中的 Pod 之间是可以相互通信的。为了实现更严格的网络隔离,同一套k8s需要根据不同的定名空间举行网络情况隔离,比方开发(dev01)测试(test01)情况。Network Policies 是 Kubernetes 提供的一种机制,用于控制 Pod 间的网络流量。你可以为每个定名空间定义 Network Policies 来限制 Pod 之间的通信。
二、相关解释

  • spec.PodSelector
它是pod选择器,基于标签选择与Network Policy处于同一namespace下的pod,如果pod被选中,则对其应用Network Policy中定义的规则。此为可选字段,当没有此字段时,表现选中所有pod。

  • spec.PolicyTypes
Network Policy定义的规则可以分成两种,一种是入pod的Ingress规则,一种是出pod的Egress规则。本字段可以看作是一个开关,如果其中包含Ingress,则Ingress部分定义的规则收效,如果是Egress则Egress部分定义的规则收效,如果都包含则全部收效。当然此字段也可选,如果没有指定的话,则默认Ingress收效,如果Egress部分有定义的话,Egress才收效。怎么明白这句话,下文会提到,没有明确定义Ingress、Egress部分,它也是一种规则,默认规则而非没有规则。

  • spec.ingress与spec.egress
spec.ingress 和 spec.egress 字段分别用于定义答应进入 Pod 的流量规则和答应离开 Pod 的流量规则。下面详细解释这两个字段的结构和包含的子项。
spec.ingress 结构
  1. spec:
  2.   ingress:
  3.   - from:
  4.     - podSelector:
  5.         matchLabels: {} # 选择具有特定标签的 Pod
  6.     - namespaceSelector:
  7.         matchLabels: {} # 选择具有特定标签的命名空间
  8.     - ipBlock:
  9.         cidr: 0.0.0.0/0 # CIDR 地址范围
  10.         except:
  11.         - 10.0.0.0/8 # 排除的 CIDR 地址范围
  12.   - ports:
  13.     - protocol: TCP # 协议类型
  14.       port: 80 # 具体端口
  15.       endPort: 8080 # 如果是端口范围,则需要指定结束端口
复制代码
spec.egress 结构
  1. spec:
  2.   egress:
  3.   - to:
  4.     - podSelector:
  5.         matchLabels: {} # 选择具有特定标签的 Pod
  6.     - namespaceSelector:
  7.         matchLabels: {} # 选择具有特定标签的命名空间
  8.     - ipBlock:
  9.         cidr: 0.0.0.0/0 # CIDR 地址范围
  10.         except:
  11.         - 10.0.0.0/8 # 排除的 CIDR 地址范围
  12.   - ports:
  13.     - protocol: TCP # 协议类型
  14.       port: 80 # 具体端口
  15.       endPort: 8080 # 如果是端口范围,则需要指定结束端口
复制代码
示例
假设你有一个 NetworkPolicy,它答应 Pod 接收来自 CIDR 地点范围 192.168.1.0/24 的流量,并答应 Pod 发送流量到 CIDR 地点范围 10.0.0.0/8,同时只答应通过 TCP 协议的端口 80 和 443 举行通信。
  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4.   name: allow-traffic
  5.   namespace: my-namespace
  6. spec:
  7.   podSelector: {}
  8.   ingress:
  9.   - from:
  10.     - ipBlock:
  11.         cidr: 192.168.1.0/24
  12.   - ports:
  13.     - protocol: TCP
  14.       port: 80
  15.     - protocol: TCP
  16.       port: 443
  17.   egress:
  18.   - to:
  19.     - ipBlock:
  20.         cidr: 10.0.0.0/8
  21.   - ports:
  22.     - protocol: TCP
  23.       port: 80
  24.     - protocol: TCP
  25.       port: 443
  26.   policyTypes:
  27.   - Ingress
  28.   - Egress
复制代码
注意事项

  • 适用性: 该 NetworkPolicy 适用于 my-namespace 定名空间中的所有 Pod。
  • 流量控制: 控制了 Ingress 和 Egress 流量。
  • CIDR 地点范围: 192.168.1.0/24 和 10.0.0.0/8 通常用于私有网络。
  • 端口控制: 只答应通过 TCP 协议的端口 80 和 443 举行通信。
三、测试规划1、创建定名空间

2、创建pod和nodeport

3、应用策略之前测试

4、创建网络策略1-pod隔离

5、创建网络策略2-定名空隔断离

6、创建网络策略3-业务定名空隔断离

四、具体实施

1、创建定名空间

创建测试使用的3个定名空间sub1,sub2,sub3。
如果背面的网络策略使用到namespaceSelector,在创建定名空间时需要带label,也可在需要时手动添加label。
  1. kubectl create ns sub1 --labels ns=sub1
  2. kubectl create ns sub2 --labels ns=sub2
  3. kubectl create ns sub3 --labels ns=sub2
复制代码

  如果使用的是私有仓库,注意ns要创建docker-secret。
  1. kubectl create secret docker-registry my-registry-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD -n namespace
复制代码
2、创建pod和nodeport

 2.1、sub1创建sub1-pod1和sub1-pod1-nodeport,sub1-pod2;
 2.2、sub2创建sub2-pod1和sub2-pod1-nodeport,sub2-pod2;
 2.3、sub3创建sub3-pod1;
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4.   name: sub1-pod1
  5.   namespace: sub1
  6. spec:
  7.   selector:
  8.     matchLabels:
  9.       app: sub1pod1
  10.   replicas: 1
  11.   template:
  12.     metadata:
  13.       labels:
  14.         app: sub1pod1
  15.     spec:
  16.       containers:
  17.       - name: my-test01-01
  18.         image: swr.cn-east-3.myhuaweicloud.com/k8s-imgs/account-platform-admin:dev01-084e7d9
  19.         imagePullPolicy: IfNotPresent
  20.       imagePullSecrets:
  21.       - name: default-secret
  22.       imagePullSecrets:
  23.         - name: swr-secret
  24. ---
  25. apiVersion: v1
  26. kind: Service
  27. metadata:
  28.   name: sub1-pod1-nodeport
  29.   namespace: sub1
  30. spec:
  31.   type: NodePort
  32.   selector:
  33.     app: sub1pod1
  34.   ports:
  35.     - protocol: TCP
  36.       port: 80
  37.       targetPort: 8103
  38.       nodePort: 32700
  39. ---
  40. apiVersion: apps/v1
  41. kind: Deployment
  42. metadata:
  43.   name: sub1-pod2
  44.   namespace: sub1
  45. spec:
  46.   selector:
  47.     matchLabels:
  48.       app: sub1pod2
  49.   replicas: 1
  50.   template:
  51.     metadata:
  52.       labels:
  53.         app: sub1pod2
  54.     spec:
  55.       containers:
  56.       - name: my-test01-02
  57.         image: swr.cn-east-3.myhuaweicloud.com/k8s-imgs/account-platform-admin:dev01-084e7d9
  58.         imagePullPolicy: IfNotPresent
  59.       imagePullSecrets:
  60.       - name: default-secret
  61.       imagePullSecrets:
  62.         - name: swr-secret
  63.        
  64. ---
  65. apiVersion: apps/v1
  66. kind: Deployment
  67. metadata:
  68.   name: sub2-pod1
  69.   namespace: sub2
  70. spec:
  71.   selector:
  72.     matchLabels:
  73.       app: sub2pod1
  74.   replicas: 1
  75.   template:
  76.     metadata:
  77.       labels:
  78.         app: sub2pod1
  79.     spec:
  80.       containers:
  81.       - name: my-test02-01
  82.         image: swr.cn-east-3.myhuaweicloud.com/k8s-imgs/account-platform-admin:dev01-084e7d9
  83.         imagePullPolicy: IfNotPresent
  84.       imagePullSecrets:
  85.       - name: default-secret
  86.       imagePullSecrets:
  87.         - name: swr-secret
  88. ---
  89. apiVersion: v1
  90. kind: Service
  91. metadata:
  92.   name: sub2-pod1-nodeport
  93.   namespace: sub2
  94. spec:
  95.   type: NodePort
  96.   selector:
  97.     app: sub2pod1
  98.   ports:
  99.     - protocol: TCP
  100.       port: 80
  101.       targetPort: 8103
  102.       nodePort: 32701
  103. ---
  104. apiVersion: apps/v1
  105. kind: Deployment
  106. metadata:
  107.   name: sub2-pod2
  108.   namespace: sub2
  109. spec:
  110.   selector:
  111.     matchLabels:
  112.       app: sub2pod2
  113.   replicas: 1
  114.   template:
  115.     metadata:
  116.       labels:
  117.         app: sub2pod2
  118.     spec:
  119.       containers:
  120.       - name: my-test02-02
  121.         image: swr.cn-east-3.myhuaweicloud.com/k8s-imgs/account-platform-admin:dev01-084e7d9
  122.         imagePullPolicy: IfNotPresent
  123.       imagePullSecrets:
  124.       - name: default-secret
  125.       imagePullSecrets:
  126.         - name: swr-secret
  127. ---
  128. apiVersion: apps/v1
  129. kind: Deployment
  130. metadata:
  131.   name: sub3-pod1
  132.   namespace: sub3
  133. spec:
  134.   selector:
  135.     matchLabels:
  136.       app: sub3pod1
  137.   replicas: 1
  138.   template:
  139.     metadata:
  140.       labels:
  141.         app: sub3pod1
  142.     spec:
  143.       containers:
  144.       - name: my-test03-01
  145.         image: swr.cn-east-3.myhuaweicloud.com/k8s-imgs/account-platform-admin:dev01-084e7d9
  146.         imagePullPolicy: IfNotPresent
  147.       imagePullSecrets:
  148.       - name: default-secret
  149.       imagePullSecrets:
  150.         - name: swr-secret  
复制代码
检察创建的资源

3、应用策略之前测试

在应用网络策略之前测试各pod之间、pod和外网之间是否可以通信。
sub1-pod1 ping sub1-pod2、sub2-pod1、sub3-pod1、qq.com

外部节点ping sub1-pod1-nodeport、sub2-pod1-nodeport
取k8s集群任一节点ip  10.34.106.14

 总结:通过以上测试证实未加网络策略之前pod之间,pod外网之间都是互通的。
4、创建网络策略1-pod隔离 

策略描述:在sub1中创建策略,使sub1中pod之间无法通信且和其他定名空间pod也无法通信,只能进出外网。
测试流程:
  4.1、sub1-pod1、sub1-pod2、sub2-pod1三者之间互ping不通;
  4.2、sub1-pod1、sub1-pod2可以ping通外网(包含域名),外网也能和sub1-pod1-nodeport通信;
本k8s集群pod cidr为:10.243.0.0/16
  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4.   name: pod-policy
  5.   namespace: sub1
  6. spec:
  7.   podSelector: {}
  8.   ingress:
  9.     - from:
  10.       - ipBlock:
  11.           cidr: 0.0.0.0/0
  12.           except:
  13.           - 10.243.0.0/16
  14.   egress:
  15.     - to:
  16.       - ipBlock:
  17.           cidr: 0.0.0.0/0
  18.           except:
  19.           - 10.243.0.0/16
  20.   policyTypes:
  21.   - Egress
  22.   - Ingress
复制代码
解释:

  • podSelector: {} 表现选择定名空间中的所有 Pod。
  • ingress: 定义了进入定名空间的流量控制规则。

    • from: 表现答应来自哪些来源的流量。
    • ipBlock: 表现答应来自除了 10.243.0.0/16 CIDR 地点范围之外的所有 IP 地点的流量。

  • egress: 定义了离开定名空间的流量控制规则。

    • to: 表现答应流向哪些目的地的流量。
    • ipBlock: 表现答应流向除了 10.243.0.0/16 CIDR 地点范围之外的所有 IP 地点的流量。

  • policyTypes: 指定 NetworkPolicy 控制的流量类型,这里包括 Ingress 和 Egress。
效果:

  • Ingress: 答应所有来源的流量,除了 CIDR 地点范围 10.243.0.0/16。
  • Egress: 答应流向所有目的地的流量,除了 CIDR 地点范围 10.243.0.0/16。
测试:
创建策略

 sub1-pod1  ping  sub1-pod2和sub2-pod1 (不通)

 sub2-pod1  ping  sub1-pod1和sub1-pod2(不通)

 sub1-pod1  ping  外网ip(通)
 sub1-pod1  ping  域名(不通)-- 因为域名分析服务dns在kube-system空间,而sub1屏蔽了所有空间,下面示例可解决。

外部访问sub1-pod1-nodeport(通)
取k8s集群任一节点ip  10.34.106.14

5、创建网络策略2-定名空隔断离

策略描述:在sub2中创建策略,使sub2中pod之间可以通信但和其他定名空间pod无法通信,也能进出外网。
测试流程:
  5.1、sub2-pod1和sub2-pod2之间互ping可通;
  5.2、sub2-pod1、sub2-pod2和sub3-pod1之间互ping不通;
  5.3、sub2-pod1、sub2-pod2可以ping通外网(包含域名),外网也能和sub2-pod1-nodeport通信;
  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4.   name: sub2
  5.   namespace: sub2
  6. spec:
  7.   podSelector: {}
  8.   egress:
  9.   - to:
  10.     - ipBlock:
  11.         cidr: 0.0.0.0/0
  12.         except:
  13.         - 10.243.0.0/16
  14.     - namespaceSelector:    # 如果不想给命名空间加label,可以换成   - podSelector: {} # 允许来自同一命名空间中的所有 Pod 的流量
  15.         matchLabels:
  16.           ns: sub2
  17.   ingress:
  18.   - from:
  19.     - ipBlock:
  20.         cidr: 0.0.0.0/0
  21.         except:
  22.         - 10.243.0.0/16
  23.     - namespaceSelector:    # 如果不想给命名空间加label,可以换成   - podSelector: {} # 允许来自同一命名空间中的所有 Pod 的流量
  24.         matchLabels:
  25.           ns: sub2
  26.   policyTypes:
  27.   - Egress
  28.   - Ingress
复制代码
解释

  • podSelector: {} 表现选择定名空间中的所有 Pod。
  • ingress: 定义了进入定名空间的流量控制规则。

    • from: 表现答应来自哪些来源的流量。
    • ipBlock: 表现答应来自除了 10.243.0.0/16 CIDR 地点范围之外的所有 IP 地点的流量。
    • namespaceSelector: 表现答应来自具有标签 ns=sub2 的定名空间中的 Pod 的流量。
    • from字段中的 podSelector: {} 表现答应来自同一定名空间中的所有 Pod 的流量。

  • egress: 定义了离开定名空间的流量控制规则。

    • to: 表现答应流向哪些目的地的流量。
    • ipBlock: 表现答应流向除了 10.243.0.0/16 CIDR 地点范围之外的所有 IP 地点的流量。
    • namespaceSelector: 表现答应流向具有标签 ns=sub2 的定名空间中的 Pod 的流量。
    • to字段中的 podSelector: {} 表现答应流向同一定名空间中的所有 Pod 的流量。

  • policyTypes: 指定 NetworkPolicy 控制的流量类型,这里包括 Ingress 和 Egress。
效果

  • Ingress: 答应所有来源的流量,除了 CIDR 地点范围 10.243.0.0/16 和来自其他定名空间的流量,如果使用namespaceSelector则答应进入定名空间具有标签 ns=sub2中的pod,如果使用podSelector: {}表现答应来自同一定名空间中的所有 Pod 的流量。
  • Egress: 答应流向所有目的地的流量,除了 CIDR 地点范围 10.243.0.0/16 和流向其他定名空间的流量,如果使用namespaceSelector则答应流向定名空间具有标签 ns=sub2中的pod,如果使用podSelector: {}表现答应流向同一定名空间中的所有 Pod 的流量。
测试

创建策略

sub2-pod1  ping  sub2-pod2(通)

sub2-pod1  ping  sub3-pod1(不通)

sub3-pod1  ping  sub2-pod1、sub2-pod2(不通)

sub2-pod1  ping  外网ip(通)
sub2-pod1  ping  域名(不通)-- 因为域名分析服务dns在kube-system空间,而sub1屏蔽了所有空间,下面示例可解决。

外部 访问sub2-pod1-nodeport(通)
取k8s集群任一节点ip  10.34.106.14

6、创建网络策略3-业务定名空隔断离

现实应用中某些定名空间中的pod大概和其他定名空间中的pod有调用关系,还大概用到一些系统定名空间中的服务(如DNS服务),所以不能将某个定名空间完全和其他所有定名空隔断离,只需要将确定没有业务调用的定名空隔断离。
策略描述:更新第5步sub2中创建的策略,使sub2中的pod除了不能和sub3中的pod通信外,和其他所有地点都可通信。
测试流程:
  6.1、sub2-pod1和sub2-pod2互ping可通;
  6.2、sub2-pod1和kube-system定名空间中的coredns-pod之间互ping可通;
  6.3、sub2-pod1和sub3-pod1互ping不通;
  6.4、sub2-pod1可以ping通外网(域名),外网也能和sub2-pod1-nodeport通信;
由于没有直接制止具有某个label的定名空间配置,所有只能间接通过放行具有某些labels的定名空间以达到制止的目的。
label设置比较机动,可根据现实情况配置,有一下几种方式可供参考:
1、可以将放行的所有定名空间配置一个同一的label,这样只需要在配置中放行具有这个label的定名空间即可;
2、也可给每个定名空间配置一个label,这样需要在配置中放行各个不同label的定名空间;
3、可以将通用的系统定名空间设置一个同一的label,给业务定名空间配置不同的label;
本例采用第2种,给所有需要放行的定名空间配置不同的label;
定名空间加label
  1. kubectl label ns kube-system ns=kube-system
  2. kubectl label ns kuboard ns=kuboard
  3. kubectl label ns kube-public ns=kube-public
复制代码
网络隔离配置
  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4.   name: ns-policy-2
  5.   namespace: sub2
  6. spec:
  7.   podSelector: {}
  8.   ingress:
  9.   - from:
  10.     - podSelector: {}
  11.     - ipBlock:
  12.         cidr: 0.0.0.0/0
  13.         except:
  14.         - 10.243.0.0/16
  15.   - from:
  16.     - namespaceSelector:
  17.         matchLabels:
  18.           ns: kube-system
  19.   - from:
  20.     - namespaceSelector:
  21.         matchLabels:
  22.           ns: kuboard
  23.   - from:
  24.     - namespaceSelector:
  25.         matchLabels:
  26.           ns: kube-public
  27.   egress:
  28.   - to:
  29.     - podSelector: {}
  30.     - ipBlock:
  31.         cidr: 0.0.0.0/0
  32.         except:
  33.         - 10.243.0.0/16
  34.   - to:
  35.     - namespaceSelector:
  36.         matchLabels:
  37.           ns: kube-system
  38.   - to:
  39.     - namespaceSelector:
  40.         matchLabels:
  41.           ns: kuboard
  42.   - to:
  43.     - namespaceSelector:
  44.         matchLabels:
  45.           ns: kube-public
  46.   policyTypes:
  47.   - Egress
  48.   - Ingress
复制代码
解释

  • podSelector: {} 表现选择定名空间中的所有 Pod。
  • policyTypes: Ingress 和 Egress 表现同时控制进入和离开定名空间的流量。
  • ingress: from 字段中的 podSelector: {} 表现答应来自同一定名空间中的所有 Pod 的流量;ipBlock 表现答应来自除了 Kubernetes 内部网络 CIDR 地点范围10.243.0.0/16
    之外的所有 IP 地点的流量。
  • egress: to 字段中的 podSelector: {} 表现答应流向同一定名空间中的所有 Pod 的流量;ipBlock 表现答应流向除了 Kubernetes 内部网络 CIDR 地点范围10.243.0.0/16
     之外的所有 IP 地点的流量。
  • from 和 to: 使用 namespaceSelector 答应放行具有标签 ns=kube-system、ns=kuboardns、ns=kube-public的定名空间中的 Pod 的流量,间接制止了其他定名空间的流量。
测试
创建策略

sub2-pod1  ping  sub2-pod2(通)

sub2-pod1  ping  kube-system定名空间中的coredns-pod(通)


sub2-pod1  ping  sub3-pod1(不通)


sub2-pod1可以ping通外网、域名(通)

外部 访问sub2-pod1-nodeport(通)
取k8s集群任一节点ip  10.34.106.14

 
 
 
 
 
 
 
 
 
 
 
  
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

用户国营

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表