zoukankan      html  css  js  c++  java
  • ⑦.kubernetes网络策略Networkpolicy

    配置网络策略

    在Kubernetes系统中,报文的流入和流出的核心组件是Pod资源,它们也是网络策略功能的主要应用对象。NetworkPolicy对象通过podSelector选择 一组Pod资源作为控制对象。NetworkPolicy是定义在一组Pod资源之上用于管理入站流量,或出站流量的一组规则,有可以是出入站规则一起生效,规则的生效模式通常由spec.policyTypes进行 定义。如下图:

    img

    默认情况下,Pod对象的流量控制是为空的,报文可以自由出入。在附加网络策略之后,Pod对象会因为NetworkPolicy而被隔离,一旦名称空间中有任何NetworkPolicy对象匹配了某特定的Pod对象,则该Pod将拒绝NetworkPolicy规则中不允许的所有连接请求,但是那些未被匹配到的Pod对象依旧可以接受所有流量。

    就特定的Pod集合来说,入站和出站流量默认是放行状态,除非有规则可以进行匹配。还有一点需要注意的是,在spec.policyTypes中指定了生效的规则类型,但是在networkpolicy.spec字段中嵌套定义了没有任何规则的Ingress或Egress时,则表示拒绝入站或出站的一切流量。定义网络策略的基本格式如下:

    apiVersion: networking.k8s.io/v1		#定义API版本
    kind: NetworkPolicy					   #定义资源类型
    metadata:
      name: allow-myapp-ingress			    #定义NetwokPolicy的名字
      namespace: default
    spec:								  #NetworkPolicy规则定义
      podSelector: 						   #匹配拥有标签app:myapp的Pod资源
        matchLabels:
          app: myapp
      policyTypes ["Ingress"]			    #NetworkPolicy类型,可以是Ingress,Egress,或者两者共存
      ingress:							  #定义入站规则
      - from:
        - ipBlock:						  #定义可以访问的网段
            cidr: 10.244.0.0/16
            except:						  #排除的网段
            - 10.244.3.0/24
        - podSelector:					  #选定当前default名称空间,标签为app:myapp可以入站
            matchLabels:
              app: myapp
        ports:							 #开放的协议和端口定义
        - protocol: TCP
          port: 80
      
    该网络策略就是将default名称空间中拥有标签"app=myapp"的Pod资源开放80/TCP端口给10.244.0.0/16网段,并排除10.244.3.0/24网段的访问,并且也开放给标签为app=myapp的所有Pod资源进行访问。  
    

    为了看出Network Policy的效果,先部署一个httpd的应用。配置清单文件如下:

    [root@k8s-master ~]# mkdir network-policy-demo
    [root@k8s-master ~]# cd network-policy-demo/
    [root@k8s-master network-policy-demo]# vim httpd.yaml
    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: httpd
    spec:
      replicas: 3
      template:
        metadata:
          labels:
            run: httpd
        spec:
          containers:
          - name: httpd
            image: httpd:latest
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 80
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: httpd-svc
    spec:
      type: NodePort
      selector:
        run: httpd
      ports:
      - protocol: TCP
        nodePort: 30000
        port: 8080
        targetPort: 80
    

    创建三个副本,通过NodePort类型的Service对外方服务,部署应用:

    [root@k8s-master network-policy-demo]# kubectl apply -f httpd.yaml 
    deployment.apps/httpd unchanged
    service/httpd-svc created
    [root@k8s-master network-policy-demo]# kubectl get pods -o wide |grep httpd
    httpd-75f655479d-882hz                1/1       Running    0          4m        10.244.0.2     k8s-master
    httpd-75f655479d-h7lrr                1/1       Running    0          4m        10.244.2.2     k8s-node02
    httpd-75f655479d-kzr5g                1/1       Running    0          4m        10.244.1.2     k8s-node01
    
    [root@k8s-master network-policy-demo]# kubectl get svc httpd-svc
    NAME        TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    httpd-svc   NodePort   10.99.222.179   <none>        8080:30000/TCP   4m
    

    当前没有定义任何Network Policy,验证应用的访问:

    #启动一个busybox Pod,可以访问Service,也可以ping副本的Pod
    
    [root@k8s-master ~]# kubectl run busybox --rm -it --image=busybox /bin/sh
    If you don't see a command prompt, try pressing enter.
    / # wget httpd-svc:8080
    Connecting to httpd-svc:8080 (10.99.222.179:8080)
    index.html           100% |*********************************************************************************************|    45  0:00:00 ETA
    / # ping -c 2 10.244.1.2
    PING 10.244.1.2 (10.244.1.2): 56 data bytes
    64 bytes from 10.244.1.2: seq=0 ttl=63 time=0.507 ms
    64 bytes from 10.244.1.2: seq=1 ttl=63 time=0.228 ms
    
    --- 10.244.1.2 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.228/0.367/0.507 ms
    
    
    #集群节点也可以访问Sevice和ping通副本Pod
    [root@k8s-node01 ~]# curl 10.99.222.179:8080
    <html><body><h1>It works!</h1></body></html>
    [root@k8s-node01 ~]# ping -c 2 10.244.2.2
    PING 10.244.2.2 (10.244.2.2) 56(84) bytes of data.
    64 bytes from 10.244.2.2: icmp_seq=1 ttl=63 time=0.931 ms
    64 bytes from 10.244.2.2: icmp_seq=2 ttl=63 time=0.812 ms
    
    --- 10.244.2.2 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1001ms
    rtt min/avg/max/mdev = 0.812/0.871/0.931/0.066 ms
    
    #集群外部访问192.168.56.11:30000也是通的
    [root@localhost ~]# curl 192.168.56.11:30000
    <html><body><h1>It works!</h1></body></html>
    

    那么下面再去设置不同的Network Policy来管控Pod的访问。

    1、管控入站流量

    NetworkPolicy资源属于名称空间级别,它的作用范围为其所属的名称空间。

    1、设置默认的Ingress策略

    用户可以创建一个NetworkPolicy来为名称空间设置一个默认的隔离策略,该策略选择所有的Pod对象,然后允许或拒绝任何到达这些Pod的入站流量,如下:

    [root@k8s-master network-policy-demo]# vim policy-demo.yaml
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-all-ingress
    spec:
      podSelector: {}
      policyTypes: ["Ingress"]	
      #指明了Ingress生效规则,但不定义任何Ingress字段,因此不能匹配任何源端点,从而拒绝所有的入站流量
    
    [root@k8s-master network-policy-demo]# kubectl apply -f policy-demo.yaml 
    networkpolicy.networking.k8s.io/deny-all-ingress created
    [root@k8s-master network-policy-demo]# kubectl get networkpolicy
    NAME               POD-SELECTOR   AGE
    deny-all-ingress   <none>         11s
    
    #此时再去访问测试,是无法ping通,无法访问的
    [root@k8s-master ~]# kubectl run busybox --rm -it --image=busybox /bin/sh
    If you don't see a command prompt, try pressing enter.
    / # wget httpd-svc:8080
    Connecting to httpd-svc:8080 (10.99.222.179:8080)
    wget: can't connect to remote host (10.99.222.179): Connection timed out
    

    如果要将默认策略设置为允许所有入站流量,只需要定义Ingress字段,并将这个字段设置为空,以匹配所有源端点,但本身不设定网络策略,就已经是默认允许所有入站流量访问的,下面给出一个定义的格式:

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

    实践中,通常将默认的网络策略设置为拒绝所有入站流量,然后再放行允许的源端点的入站流量。

    2、放行特定的入站流量

    [root@k8s-master network-policy-demo]# vim policy-demo.yaml 
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: access-httpd
    spec:
      podSelector: 
        matchLabels:
          run: httpd
      policyTypes: ["Ingress"]
      ingress:
      - from:
        - ipBlock:
            cidr: 10.244.0.0/16
            except:
            - 10.244.2.0/24
            - 10.244.1.0/24
        - podSelector:
            matchLabels:
              access: "true"
        ports:
        - protocol: TCP
          port: 80
    
    [root@k8s-master network-policy-demo]# kubectl apply -f policy-demo.yaml 
    networkpolicy.networking.k8s.io/access-httpd created
    [root@k8s-master network-policy-demo]# kubectl get networkpolicy
    NAME           POD-SELECTOR   AGE
    access-httpd   run=httpd      6s
    

    验证NetworkPolicy的有效性:

    #创建带有标签的busybox pod访问,是可以正常访问的,但是因为仅开放了TCP协议,所以PING是无法ping通的
    [root@k8s-master ~]# kubectl run busybox --rm -it --labels="access=true" --image=busybox /bin/sh
    If you don't see a command prompt, try pressing enter.
    / # wget httpd-svc:8080
    Connecting to httpd-svc:8080 (10.99.222.179:8080)
    index.html           100% |*********************************************************************************************|    45  0:00:00 ETA
    / # ping -c 3 10.244.0.2
    PING 10.244.0.2 (10.244.0.2): 56 data bytes
    
    --- 10.244.0.2 ping statistics ---
    3 packets transmitted, 0 packets received, 100% packet loss
    

    2、管控出站流量

    通常,出站的流量默认策略应该是允许通过的,但是当有精细化需求,仅放行那些有对外请求需要的Pod对象的出站流量,也可以先为名称空间设置“禁止所有”的默认策略,再细化制定准许的策略。networkpolicy.spec中嵌套的Egress字段用来定义出站流量规则。

    1、设定默认Egress策略

    和Igress一样,只需要通过policyTypes字段指明生效的Egress类型规则,然后不去定义Egress字段,就不会去匹配到任何目标端点,从而拒绝所有的出站流量。

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

    实践中,需要进行严格隔离的环境通常将默认的策略设置为拒绝所有出站流量,再去细化配置允许到达的目标端点的出站流量。

    2、放行特定的出站流量

    下面举个例子定义一个Egress规则,对标签run=httpd的Pod对象,到达标签为access=true的Pod对象的80端口的流量进行放行。

    [root@k8s-master network-policy-demo]# vim egress-policy.yaml 
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: httpd-egress
    spec:
      podSelector: 
        matchLabels:
          run: httpd
      policyTypes: ["Egress"]
      egress:
      - to:
        - podSelector:
            matchLabels:
              access: "true"
        ports:
        - protocol: TCP
          port: 80
    
    
    #NetworkPolicy检测,一个带有access=true标签,一个不带
    [root@k8s-master ~]# kubectl run busybox --rm -it --labels="access=true" --image=busybox /bin/sh
    If you don't see a command prompt, try pressing enter.
    / # wget httpd-svc:8080
    Connecting to httpd-svc:8080 (10.99.222.179:8080)
    index.html           100% |*********************************************************************************************|    45  0:00:00 ETA
    / # exit
    Session ended, resume using 'kubectl attach busybox-686cb649b6-6j4qx -c busybox -i -t' command when the pod is running
    deployment.apps "busybox" deleted
    
    [root@k8s-master ~]# kubectl run busybox2 --rm -it --image=busybox /bin/sh
    If you don't see a command prompt, try pressing enter.
    / # wget httpd-svc:8080
    Connecting to httpd-svc:8080 (10.99.222.179:8080)
    wget: can't connect to remote host (10.99.222.179): Connection timed out
    

    从上面的检测结果可以看到,带有标签access=true的Pod才能访问到httpd-svc,说明上面配置的Network Policy已经生效。

    3、隔离名称空间

    实践中,通常需要彼此隔离所有的名称空间,但是又需要允许它们可以和kube-system名称空间中的Pod资源进行流量交换,以实现监控和名称解析等各种管理功能。下面的配置清单示例在default名称空间定义相关规则,在出站和入站都默认均为拒绝的情况下,它用于放行名称空间内部的各Pod对象之间的通信,以及和kube-system名称空间内各Pod间的通信。

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: namespace-deny-all
      namespace: default
    spec:
      policyTypes: ["Ingress","Egress"]
      podSelector: {}
    ---
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: namespace-allow
      namespace: default
    spec:
      policyTypes: ["Ingress","Egress"]
      podSelector: {}
      ingress:
      - from:
        - namespaceSelector:
            matchExpressions:
            - key: name
              operator: In
              values: ["default","kube-system"]
      egress:
      - to:
        - namespaceSelector:
            matchExpressions:
            - key: name
              operator: In
              values: ["default","kube-system"]
    

    需要注意的是,有一些额外的系统附件可能会单独部署到独有的名称空间中,比如将prometheus监控系统部署到prom名称空间等,这类具有管理功能的附件所在的名称空间和每一个特定的名称空间的出入流量也是需要被放行的。

  • 相关阅读:
    js异步编程
    gitreset
    js数据类型
    vuex报错
    个人管理系统综述
    ffmpeg第7篇:数据流选择神器map指令
    eltable多选框根据条件隐藏显示
    [域渗透内网渗透] 从 web 到域控,你未曾设想的攻击链
    宽字节第二期线下培训开始招生啦!!!
    cve20212394 weblogic反序列化漏洞分析
  • 原文地址:https://www.cnblogs.com/yangtao416/p/15222016.html
Copyright © 2011-2022 走看看