Kubernetes 学习19基于canel的网络策略

1、概述html

  一、咱们说过,k8s的可用插件有不少,除了flannel以外,还有一个流行的叫作calico的组件,不过calico在不少项目中都会有这个名字被应用,因此他们把本身称为project calico,可是不少时候咱们在kubernets的语境中一般会单独称呼他为calico。其自己支持bgp的方式来构建pod网络。经过bgp协议的路由学习能使得去每一节点上生成到达另外一节点上pod之间的路由表信息。会在变更时自动执行改变和修改,另外其也支持IP-IP,就是基于IP报文来承载一个IP报文,不像咱们VXLAN是经过一个所谓的以太网帧来承载另一个以太网帧的报文的方式来实现的。所以从这个角度来说他是一个三层隧道,也就意外着说若是咱们指望在calico的网络中实现隧道的方式进行应用,来实现更为强大的控制逻辑,他也支持隧道,不过他是IP-IP隧道,和LVS中所谓的IP-IP的方式很相像。不过calico的配置依赖于咱们对bgp等协议的理解工做起来才能更好的去了解他。咱们这儿就再也不讲calico怎么去做为网络插件去提供网络功能的,而是把他重点集中在calico如何去提供网络策略。由于flannel自己提供不了网络策略。而flannel和calico两者自己已经合二为一了,即canel。事实上,就算咱们此前不了解canel的时候相似于使用kubectl的提示根据不少文章的提示直接安装并部署了flannel这样的网络插件都想把flannel换掉。但在这基础之上咱们又想去使用网络策略。其实也是有解决方案的,咱们能够在flannel提供网络功能的基础之上在额外去给他提供calico去提供网络策略。node

  二、在实现部署以前要先知道,calico默认使用的网段不是10.244.0.0,若是要拿calico做为网络插件使用的话它工做于192.168.0.0网络。并且是16位掩码。每个节点网络分配是按照192.168.0.0/24,192.168.1.0/24来分配的。但此处咱们不把其当作网络插件提供者而是当作网络策略提供者,咱们仍然使用10.244.0.0网段。git

2、安装calicoapi

  一、能够在官方文档中看到calico有多种安装方式(目前为止calico还不支持ipvs模式)安全

  

  二、安装教程连接https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/flannel网络

  三、calico新版本中部署比较复杂,calico对集群节点的全部的地址分配都没有本身介入,而是须要依赖于etcd来介入,这就比较麻烦了,首先,你们知道咱们k8s本身有etcd database,而calico也须要etcd database,它是两套集群,各自是各自的etcd,这样子分裂起来进行管理来说对咱们k8s工程师都不是一个轻松的事情,那咱们应该怎么作呢?后来的calico也支持不把数据放在本身专用的etcd集群中,而是掉apiserver的功能,直接把全部的设置都发给apiserver,由apiserver再存储在etcd中,由于整个k8s集群任何节点的功能,任何组件都不能直接写k8s的etcd,必须apiserver写,主要是确保数据一致性。这样一来也就意外着说咱们calico部署有两种方式。第一就是和k8s的etcd分开;第二,直接使用k8s的etcd,不过是要经过apiserver去调用。这儿咱们直接使用第二种方式部署。官网对部署方式描述以下app

Installing with the Kubernetes API datastore (recommended)
Ensure that the Kubernetes controller manager has the following flags set:--cluster-cidr=10.244.0.0/16 and --allocate-node-cidrs=true.

Tip: If you’re using kubeadm, you can pass --pod-network-cidr=10.244.0.0/16 to kubeadm to set the Kubernetes controller flags.

If your cluster has RBAC enabled, issue the following command to configure the roles and bindings that Calico requires.

kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/rbac.yaml

Note: You can also view the manifest in your browser.

Issue the following command to install Calico.

kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
 
Note: You can also view the manifest in your browser.

  四、如今咱们来部署curl

    a、首先咱们部署一个rbac.yaml配置文件ide

[root@k8smaster flannel]# kubectl apply -f  
clusterrole.rbac.authorization.k8s.io/calico created
clusterrole.rbac.authorization.k8s.io/flannel configured
clusterrolebinding.rbac.authorization.k8s.io/canal-flannel created
clusterrolebinding.rbac.authorization.k8s.io/canal-calico created

    b、第二步咱们部署canal.yaml学习

[root@k8smaster flannel]# kubectl apply -f \
 
configmap/canal-config created
daemonset.extensions/canal created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created

    c、接下来咱们来看一下对应的组件是否已经启动起来了

3、canel的使用

  一、部署完canel后咱们怎么去控制咱们对应的pod间通讯呢?如今咱们在咱们的cluster上建立两个namespaces,一个叫dev,一个叫pro,而后在两个名称空间中建立两个pod,咱们看看两个名称空间中跨名称空间通讯能不能直接进行,若是能进行的话咱们如何让他不能进行。而且咱们还能够这样来设计,咱们能够为一个名称空间设置一个默认通讯策略,任何到达此名称空间的通讯流量都不被容许。简单来说咱们所用的网络控制策略是经过这种方式来定义的。如图,咱们网络控制策略(Network Policy)他经过Egress或Ingress规则分别来控制不一样的通讯需求,什么意思呢?Egress即出栈的意思,Ingress即入栈的意思(此处Ingress和咱们k8sIngress是两回事)。Egress表示咱们pod做为客户端去访问别人的。即本身做为源地址对方做为目标地址来进行通讯,Ingress表示本身是目标,远程是源。因此咱们要控制这两个方向的不一样的通讯,而控制Egress的时候客户端端口是随机的而服务端端口是固定的,所以做为出栈的时候去请求别人很显然对方是服务端,对方的端口可预测,对方的地址也可预测,但本身的地址能预测端口却不能预测。一样的逻辑,若是别人访问本身,本身的地址能预测,本身的端口也能预测,但对方的端口是不能预测的。由于对方是客户端。

    

  二、所以去定义规则时若是定义的是Egress规则(出栈的),那么咱们能够定义目标地址和目标端口。若是咱们定义的是Ingress规则(入栈的),咱们能限制对方的地址,能限制本身的端口,那咱们这种限制是针对于哪个Pod来讲的呢?这个网络策略规则是控制哪一个pod和别人通讯或接受别人通讯的呢?咱们使用podSelector(pod选择器)去选择pod,意思是这个规则生效在哪一个pod上,咱们通常使用单个pod进行控制,也能够控制一组pod,因此咱们使用podSelector就至关于说我这一组pod都受控于这个Egress和Ingress规则,并且更重要的是咱们未来定义规则时还能够指定单方向。意思是入栈咱们作控制出栈都容许或出栈作控制入栈都容许。所以定义时能够很灵活的去定义,能够发现他和iptables没有太大的区别。那种方式最安全呢?确定是拒绝全部放行已知。甚至于若是说你是托管了每个名称空间托管了不一样项目的,甚至不一样客户的项目。咱们名称空间直接设置默认策略。咱们在名称空间内全部pod能够无障碍的通讯,可是跨名称空间都不被容许。这种均可以叫一个名称空间的默认策略。

  三、接下来咱们看这些策略怎么工做起来

    a、咱们能够看到咱们加载的canal pod已经启动起来了

[root@k8smaster ~]# kubectl get pods -n kube-system |grep canal
canal-hmc47                            3/3       Running   0          45m
canal-sw5q6                            3/3       Running   0          45m
canal-xxvzk                            3/3       Running   0          45m

    b、咱们看咱们网络策略怎么定义

[root@k8smaster ~]# kubectl explain networkpolicy
KIND:     NetworkPolicy
VERSION:  extensions/v1beta1

DESCRIPTION:
     DEPRECATED 1.9 - This group version of NetworkPolicy is deprecated by
     networking/v1/NetworkPolicy. NetworkPolicy describes what network traffic
     is allowed for a set of Pods

FIELDS:
   apiVersion    <string>
     APIVersion defines the versioned schema of this representation of an     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
   kind    <string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
   metadata    <Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
   spec    <Object>
     Specification of the desired behavior for this NetworkPolicy.
[root@k8smaster ~]# kubectl explain networkpolicy.spec
KIND:     NetworkPolicy
VERSION:  extensions/v1beta1

RESOURCE: spec <Object>DESCRIPTION:
     Specification of the desired behavior for this NetworkPolicy.

     DEPRECATED 1.9 - This group version of NetworkPolicySpec is deprecated by
     networking/v1/NetworkPolicySpec.

FIELDS:
   egress    <[]Object> #出栈规则
     List of egress rules to be applied to the selected pods. Outgoing traffic
     is allowed if there are no NetworkPolicies selecting the pod (and cluster
     policy otherwise allows the traffic), OR if the traffic matches at least
     one egress rule across all of the NetworkPolicy objects whose podSelector
     matches the pod. If this field is empty then this NetworkPolicy limits all
     outgoing traffic (and serves solely to ensure that the pods it selects are
     isolated by default). This field is beta-level in 1.8

   ingress    <[]Object> #入栈规则
     List of ingress rules to be applied to the selected pods. Traffic is
     allowed to a pod if there are no NetworkPolicies selecting the pod OR if
     the traffic source is the pod's local node, OR if the traffic matches at     
     least one ingress rule across all of the NetworkPolicy objects whose
     podSelector matches the pod. If this field is empty then this NetworkPolicy
     does not allow any traffic (and serves solely to ensure that the pods it
     selects are isolated by default).

   podSelector    <Object> -required-   #规则应用在哪一个pod上
     Selects the pods to which this NetworkPolicy object applies. The array of
     ingress rules is applied to any pods selected by this field. Multiple
     network policies can select the same set of pods. In this case, the ingress
     rules for each are combined additively. This field is NOT optional and
     follows standard label selector semantics. An empty podSelector matches all
     pods in this namespace.

   policyTypes    <[]string>  #策略类型,指的是假如我在当前这个策略中即定义了Egress又定义了Ingress,那么谁生效呢?虽然他们并不冲突,可是你能够定义在某个时候某一方向的规则生效。
     List of rule types that the NetworkPolicy relates to. Valid options are
     Ingress, Egress, or Ingress,Egress. If this field is not specified, it will
     default based on the existence of Ingress or Egress rules; policies that
     contain an Egress section are assumed to affect Egress, and all policies
     (whether or not they contain an Ingress section) are assumed to affect
     Ingress. If you want to write an egress-only policy, you must explicitly
     specify policyTypes [ "Egress" ]. Likewise, if you want to write a policy
     that specifies that no egress is allowed, you must specify a policyTypes
     value that include "Egress" (since such a policy would not include an
     Egress section and would otherwise default to just [ "Ingress" ]). This
     field is beta-level in 1.8

      咱们来看egress定义

[root@k8smaster ~]# kubectl explain networkpolicy.spec.egress
KIND:     NetworkPolicy
VERSION:  extensions/v1beta1

RESOURCE: egress <[]Object>DESCRIPTION:
     List of egress rules to be applied to the selected pods. Outgoing traffic
     is allowed if there are no NetworkPolicies selecting the pod (and cluster
     policy otherwise allows the traffic), OR if the traffic matches at least
     one egress rule across all of the NetworkPolicy objects whose podSelector
     matches the pod. If this field is empty then this NetworkPolicy limits all
     outgoing traffic (and serves solely to ensure that the pods it selects are
     isolated by default). This field is beta-level in 1.8

     DEPRECATED 1.9 - This group version of NetworkPolicyEgre***ule is
     deprecated by networking/v1/NetworkPolicyEgre***ule.
     NetworkPolicyEgre***ule describes a particular set of traffic that is
     allowed out of pods matched by a NetworkPolicySpec's podSelector. The
     traffic must match both ports and to. This type is beta-level in 1.8FIELDS:
   ports    <[]Object> #目标端口,能够是端口名和相关的协议
     List of destination ports for outgoing traffic. Each item in this list is
     combined using a logical OR. If this field is empty or missing, this rule
     matches all ports (traffic not restricted by port). If this field is
     present and contains at least one item, then this rule allows traffic only     
     if the traffic matches at least one port in the list.

   to    <[]Object>
     List of destinations for outgoing traffic of pods selected for this rule.
     Items in this list are combined using a logical OR operation. If this field
     is empty or missing, this rule matches all destinations (traffic not
     restricted by destination). If this field is present and contains at least
     one item, this rule allows traffic only if the traffic matches at least one
     item in the to list.

       咱们看看这个to,to表示目标地址,能够是三种状况中的一个,也能够是合并起来的,若是同时使用的话是要取交集。

[root@k8smaster ~]# kubectl explain networkpolicy.spec.egress.to
KIND:     NetworkPolicy
VERSION:  extensions/v1beta1

RESOURCE: to <[]Object>DESCRIPTION:
     List of destinations for outgoing traffic of pods selected for this rule.
     Items in this list are combined using a logical OR operation. If this field
     is empty or missing, this rule matches all destinations (traffic not
     restricted by destination). If this field is present and contains at least
     one item, this rule allows traffic only if the traffic matches at least one
     item in the to list.

     DEPRECATED 1.9 - This group version of NetworkPolicyPeer is deprecated by
     networking/v1/NetworkPolicyPeer.

FIELDS:
   ipBlock    <Object> #目标地址也能够是一个IP地址块,是一个IP地址范围内的全部端点。无论它是pod或主机都行。
     IPBlock defines policy on a particular IPBlock. If this field is set then
     neither of the other fields can be.

   namespaceSelector    <Object> #意思是名称空间选择器,意思是咱们控制的pod能到达其它名称空间的,那个名称空间内的全部pod都在这个范围内。我使用这个选择器选择一组名称空间是指用于控制这组源pod是怎么去访问这组名称空间以内的全部pod或者某一个pod。
     Selects Namespaces using cluster-scoped labels. This field follows standard
     label selector semantics; if present but empty, it selects all namespaces.
     If PodSelector is also set, then the NetworkPolicyPeer as a whole selects
     the Pods matching PodSelector in the Namespaces selected by
     NamespaceSelector. Otherwise it selects all Pods in the Namespaces selected
     by NamespaceSelector.

   podSelector    <Object> #目标地址也能够是另一组pod,控制两组pod之间通讯。源是一组pod,目标地址也是一组pod。
     This is a label selector which selects Pods. This field follows standard
     label selector semantics; if present but empty, it selects all pods. If
     NamespaceSelector is also set, then the NetworkPolicyPeer as a whole
     selects the Pods matching PodSelector in the Namespaces selected by
     NamespaceSelector. Otherwise it selects the Pods matching PodSelector in
     the policy's own Namespace.

      Ingress只是由to变成了from

    c、policyTypes下有几个规则须要咱们注意,若是这个字段没有定义,那么只要存在的Egress和Ingress都会生效。但凡出现的定义的都会生效。若咱们只定义了Ingress规则,可是在policyTypes中定义了Egress和Ingress,那么Egress的默认规则会生效。若是默认是容许的那么全部规则都被容许,若是默认是拒绝的那么全部规则都被拒绝。咱们默认的规则是拒绝的。这里Egress将会使用默认规则拒绝全部。

  四、咱们去设置一个Ingress默认策略。咱们把一个名称空间上全部的入栈规则都关了,都拒绝,谁都不容许入栈。而后咱们只放行特定的,这样更安全。好比咱们dev名称空间默认全部pod都是被别人能访问的,咱们不容许别人访问应该是一个默认规则,那么咱们怎么去定义这个规则呢?

    a、首先咱们建立名称空间dev,pro

[root@k8smaster networkpolicy]# kubectl create namespace dev
namespace/dev created
[root@k8smaster networkpolicy]# kubectl create namespace prod
namespace/prod created

    b、接下来咱们建立Ingress默认规则并运用于dev名称空间中

复制代码

[root@k8smaster networkpolicy]# cat ingress-def.yml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {} #空表示选择全部pod,表示指定名称空间中的全部pod,就至关于控制整个名称空间了
  policyTypes:  - Ingress  #表示只对Ingress生效,由于没有定义Ingress所以没有任何规则是生效的。没有任何显示定义的规则就意味着默认是拒绝全部的。可是咱们没有加Egress意味着,由于policyTypes没有将其定义进来因
此默认是容许的。[root@k8smaster networkpolicy]# kubectl apply -f ingress-def.yml -n dev
networkpolicy.networking.k8s.io/deny-all-ingress created
[root@k8smaster networkpolicy]#

复制代码

      查看咱们定义的NetworkPolicy

[root@k8smaster networkpolicy]# kubectl get netpol -n dev
NAME               POD-SELECTOR   AGE
deny-all-ingress   <none>         1m

    c、接下来咱们dev名称空间建立一个pod看可否被访问到

复制代码

[root@k8smaster networkpolicy]# cat pod-a.yaml 
apiVersion: v1
kind: Pod
metadata: 
  name: pod1
spec:
  containers:  - name: myapp
    image: ikubernetes/myapp:v1
[root@k8smaster networkpolicy]# kubectl apply -f pod-a.yaml -n dev
pod/pod1 created
[root@k8smaster networkpolicy]# kubectl get pods -n dev
NAME      READY     STATUS    RESTARTS   AGE
pod1      1/1       Running   0          7s

复制代码

[root@k8smaster networkpolicy]# kubectl get pods -n dev -o wide
NAME      READY     STATUS    RESTARTS   AGE       IP           NODE
pod1      1/1       Running   0          1m        10.244.2.2   k8snode2
[root@k8smaster networkpolicy]# curl 10.244.2.2 #能够看到没法访问^C

    d、咱们在prod名称空间中建立一个pod看可否被访问

[root@k8smaster networkpolicy]# kubectl apply -f pod-a.yaml -n prod
pod/pod1 created
[root@k8smaster networkpolicy]# kubectl get pods -n prod -o wide
NAME      READY     STATUS    RESTARTS   AGE       IP           NODE
pod1      1/1       Running   0          12s       10.244.1.2   k8snode1
[root@k8smaster networkpolicy]# curl 10.244.1.2 #能够看到由于没有定义规则因此可以访问Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

  五、如今咱们放行2.2,dev名称空间中默认是拒绝一切入栈请求的,如今咱们要放行别人对于dev中咱们单个pod  pod1

[root@k8smaster networkpolicy]# cat ingress-def.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {} #空表示选择全部pod,表示指定名称空间中的全部pod,就至关于控制整个名称空间了
  ingress:  - {}  #这个全部就表示全部的都容许
  policyTypes:  - Ingress  #表示只对Ingress生效,此时咱们ingress是容许的,Egress也是容许的
[root@k8smaster networkpolicy]# kubectl get pods -n dev -o wide
NAME      READY     STATUS    RESTARTS   AGE       IP           NODE
pod1      1/1       Running   0          15m       10.244.2.2   k8snode2
[root@k8smaster networkpolicy]# curl 10.244.2.2 #能够看到能够访问了Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

  六、接下来加一组规则说咱们指望容许别人去访问咱们这个2.2这个pod,或者容许一组pod,咱们要定义一组pod咱们能够这么来定义,好比这组pod给其打一个标签为myapp

    a、首先咱们给dev中的pod1打上标签myapp,再此以前咱们仍是先设置为拒绝全部

[root@k8smaster networkpolicy]# cat ingress-def.yml.bak 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {} #空表示选择全部pod,表示指定名称空间中的全部pod,就至关于控制整个名称空间了
  policyTypes:  - Ingress  #表示只对Ingress生效,由于没有定义Ingress所以没有任何规则是生效的。没有任何显示定义的规则就意味着默认是拒绝全部的。可是咱们没有加Egress意味着,由于policyTypes没有将其定义进来因
此默认是容许的。[root@k8smaster networkpolicy]# kubectl apply -f ingress-def.yml.bak -n dev
networkpolicy.networking.k8s.io/deny-all-ingress unchanged
[root@k8smaster networkpolicy]# kubectl label pods pod1 app=myapp -n dev
pod/pod1 labeled
[root@k8smaster networkpolicy]# kubectl get pods -n dev -o wide --show-labels
NAME      READY     STATUS    RESTARTS   AGE       IP           NODE       LABELS
pod1      1/1       Running   0          22m       10.244.2.2   k8snode2   app=myapp

    b、咱们设置这样一条Ingress规则:咱们放行特定的入栈流量。即咱们容许来自于10.244.0.0/16网段的客户端访问咱们本地拥有app标签且值为myapp的一组本地pod,对这组pod的访问只要访问到80端口都是容许的,其它端口都没有说明。默认是拒绝的

[root@k8smaster networkpolicy]# cat allow-netpol-demo.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-myapp-ingress
spec:
  podSelector:
    matchLabels:
      app: myapp #匹配标签为myapp的pod
  ingress:  - from: 
    - ipBlock: #网段
        cidr: 10.244.0.0/16 #放行这个网络
        except:  #排除这个网络        - 10.244.1.2/32  #即排除10.244.1.2这个地址
    ports: #容许访问本机的哪一个端口,咱们myapp只开放了一个80端口所以咱们开放80端口的访问    - protocol: TCP
      port: 80[root@k8smaster networkpolicy]# kubectl apply -f allow-netpol-demo.yaml -n dev
networkpolicy.networking.k8s.io/allow-myapp-ingress unchanged
[root@k8smaster networkpolicy]# kubectl get netpol -n dev
NAME                  POD-SELECTOR   AGE
allow-myapp-ingress   app=myapp      34s
deny-all-ingress      <none>         49m
[root@k8smaster networkpolicy]# curl 10.244.2.2
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

    咱们访问443端口发现也被拒绝,当咱们放行后发现能收到访问失败的信息

[root@k8smaster networkpolicy]# curl 10.244.2.2:443 #能够看到被拒绝^C
[root@k8smaster networkpolicy]# cat allow-netpol-demo.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-myapp-ingress
spec:
  podSelector:
    matchLabels:
      app: myapp #匹配标签为myapp的pod
  ingress:  - from: 
    - ipBlock: #网段
        cidr: 10.244.0.0/16 #放行这个网络
        except:  #排除这个网络        - 10.244.1.2/32  #即排除10.244.1.2这个地址
    ports: #容许访问本机的哪一个端口,咱们myapp只开放了一个80端口所以咱们开放80端口的访问    - protocol: TCP
      port: 80
    - protocol: TCP
      port: 443[root@k8smaster networkpolicy]# kubectl apply -f allow-netpol-demo.yaml -n dev
networkpolicy.networking.k8s.io/allow-myapp-ingress configured
[root@k8smaster networkpolicy]# curl 10.244.2.2:443 #能够看到被放行了
curl: (7) Failed connect to 10.244.2.2:443; Connection refused

    c、咱们要管控出栈流量的方式和管控入栈流量的方式是同样的,只不过将其Ingress改成Egress。

  七、以prod名称空间为例,咱们将其出栈规则先设置为拒绝,而后咱们再慢慢放行,能访问出去,咱们让进来都容许

    a、首先咱们定义netpol

[root@k8smaster networkpolicy]# cat egress-def.yml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
spec:
  podSelector: {} #空表示选择全部pod,表示指定名称空间中的全部pod,就至关于控制整个名称空间了
  policyTypes:  - Egress  #表示只对Egress生效,此时咱们egress默认拒绝全部,ingress是容许的
[root@k8smaster networkpolicy]# kubectl apply -f egress-def.yml -n prod
networkpolicy.networking.k8s.io/deny-all-egress created
[root@k8smaster networkpolicy]# kubectl get netpol -n prod
NAME              POD-SELECTOR   AGE
deny-all-egress   <none>         16s

    b、此时咱们看到咱们prod 中的pod1是ping不出去的,由于egress默认拒绝了全部流量,要放行全部egress流量也很简单,和ingress处定义方式同样

[root@k8smaster networkpolicy]# cat egress-def.yml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
spec:
  podSelector: {} #空表示选择全部pod,表示指定名称空间中的全部pod,就至关于控制整个名称空间了
  egress:  - {}
  policyTypes:  - Egress  #表示只对Egress生效,此时咱们egress默认拒绝全部,ingress是容许的
[root@k8smaster networkpolicy]# kubectl apply -f egress-def.yml -n prod
networkpolicy.networking.k8s.io/deny-all-egress unchanged

[root@k8smaster networkpolicy]# kubectl exec -it pod1 -n prod /bin/sh/ # ping 10.244.0.26
PING 10.244.0.26 (10.244.0.26): 56 data bytes
64 bytes from 10.244.0.26: seq=0 ttl=62 time=3.317 ms
64 bytes from 10.244.0.26: seq=1 ttl=62 time=0.630 ms

    此时咱们仍是将egress改回拒绝状态,发现没法ping通

[root@k8smaster networkpolicy]# kubectl exec -it pod1 -n prod /bin/sh
PING 10.244.0.26 (10.244.0.26): 56 data bytes^C

    egress咱们要定义他们特定的放行出站流量的时候咱们只能定义对方的端口和对方的地址,事实上本身做为客户端的话是容许访问全部的客户端和全部的远程地址的。应该放行全部,出栈通常没问题,入栈咱们控制只有哪些能进来就行,就再也不详细说了。若是想作的苛刻一点,对全部名称空间,拒绝全部入栈,拒绝全部出栈,单独放行。可是拒绝全部入栈和出栈就有一个问题,使用podselect写完之后会致使同一个名称空间中pod与pod之间也无法通讯了,由于podselect不是在namespace级别控制的而是在pod级别控制的。就表示不管他在不在名称空间彼此之间都不能通讯。因此必要的状况下就应该定义先拒绝全部出栈拒绝全部入栈之后再加两条规则,就是本名称空间中的pod出,而后又到本名称空间的pod是容许的。这样就能放行同一个名称空间中的pod通讯。

  八、通常来讲网络策略咱们能够这样干

    对于名称空间来讲,咱们先拒绝全部出栈和入栈,而后再放行全部出栈目标为本地全部名称空间内的全部pod;这样至少内部通讯没问题了,剩下的跨名称空间再单独定义就行。而放行全部出栈为本名称空间,入栈也是本名称空间,所以此时Ingress和Egress都须要定义。可是咱们使用namespaceselector来选择哪一个名称空间,或者入栈和出栈的时候都写成podselector,写Ingress和Egress时都写成{},即本地全部的就好了

相关文章
相关标签/搜索