• k8s系列---基于canal的网络策略


    文章拷自:http://blog.itpub.net/28916011/viewspace-2215383/ 加上自己遇到的问题简单记录

    安装文档:https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/flannel

        我们知道flannel只能提供网络通讯,而不能提供网络策略。因此,我们本节学习canal,让它来提供网络策略,来配合flannel使用。 

    前提条件

        1、kubelet必须配置为CNI网络插件(即--network-plugin-cni,默认新版本默认就是CNI) 

        2、kube-proxy必须以iptables模式启动,不能以ipvs方式启动; 

        3、kube-proxy不能以--masquerade-all方式启动,因为这和calico策略冲突; 

        4、k8s版本至少要v1.3.0 

    部署canal

    1、

    [root@master ~]# kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
    

      

    2、

    [root@master ~]# kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/canal.yaml
    

      

    3、

    [root@master ~]# kubectl get pods -n kube-system -o wide
    NAME                                   READY     STATUS    RESTARTS   AGE       IP             NODE
    canal-7q4k7                            3/3       Running   0          4m        172.16.1.101   node1
    canal-dk2tc                            3/3       Running   0          4m        172.16.1.102   node2
    canal-zr8l4                            3/3       Running   0          4m        172.16.1.100   master
    

      

    我这边部署完成之后,发现flannel的directrouting模式又没了。然后后面去pod内ping的时候发现跨node节点已经不通了。于是又把flannel删了重建,最后正常了。很奇怪的现象。还有就是有个最后他妈的卡住了,canal一直不running状态,node节点磁盘io跑满了,导致该node上的pod都无法连接。最后重启该node,就好了。

    建立网络策略:  

    [root@master ~]# mkdir networkpolicy
    [root@master ~]# cd networkpolicy/
    [root@master networkpolicy]# vim ingress-def.yaml
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-all-ingress
    spec:
      podSelector: {} #pod选择器设置为空,表示选择所有pod,即控制整个名称空间
      policyTypes: 
      - Ingress #表示只对ingress生效,但是我们上面又把podSelector设置为空,表示默认是ingress拒绝所有的
        #但是我们这里面又没有加egress,所以默认egress是允许所有的
    

      

    [root@master networkpolicy]# kubectl apply -f ingress-def.yaml -n dev  #-n表示只对哪个名称空间生效
    networkpolicy.networking.k8s.io/deny-all-ingress created
    

      

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

      

     建立个容器,放在dev名称空间里面: 

    [root@master networkpolicy]# cat pod-a.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod1
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
    

      

    [root@master networkpolicy]# kubectl apply -f pod-a.yaml -n dev
    pod/pod1 created
    

      

    root@master 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   node2
    

      

    [root@master networkpolicy]# curl   10.244.2.2 #看到我们在宿主机上访问不到dev名称空间里面的pod10.244.2.2,这是因为dev名称空间里面有个deny-all-ingress网络策略,拒绝任何入站请求导致的。
    

      

     接下来我们在prod名称空间里面建立个pod: 

    [root@master networkpolicy]#  kubectl apply -f pod-a.yaml  -n prod
    pod/pod1 created
    

      

    [root@master networkpolicy]# kubectl get pods -n prod -o wide
    NAME      READY     STATUS    RESTARTS   AGE       IP           NODE
    pod1      1/1       Running   0          1m        10.244.2.3   node2
    

      

    [root@master networkpolicy]# curl 10.244.2.4 #我们看到在宿主机上可以访问到prod名称空间里面的pod
    Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
    

      

    [root@master networkpolicy]# cat ingress-def.yaml 
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-all-ingress
    spec:
      podSelector: {} #pod选择器设置为空,表示选择所有pod,即控制整个名称空间
      ingress:
      - {} #空表示允许所有入站访问
      policyTypes:
      - Ingress #表示只对ingress生效
        #但是我们这里面又没有加egress,所以默认egress是允许所有的
    

      

    [root@master networkpolicy]# kubectl apply -f ingress-def.yaml -n dev
    networkpolicy.networking.k8s.io/deny-all-ingress configured
    

      

    [root@master networkpolicy]# curl 10.244.2.2 #这时我们就能在宿主机上访问到dev名称空间里面的容器了
    Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
    

      

        我们接下来再还原会原来的网络策略,即拒绝入所有入站请求: 

    [root@master networkpolicy]# cat ingress-def.yaml 
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-all-ingress
    spec:
      podSelector: {} #pod选择器设置为空,表示选择所有pod,即控制整个名称空间
      policyTypes:
      - Ingress #表示只对ingress生效
        #但是我们这里面又没有加egress,所以默认egress是允许所有的
    

      

    [root@master networkpolicy]# kubectl apply -f ingress-def.yaml -n dev
    networkpolicy.networking.k8s.io/deny-all-ingress unchanged
    

      

    [root@master networkpolicy]# curl 10.244.2.2 #发现在宿主机上又不能访问访问到dev里面的pod了
    

      

            下面我们给dev名称空间里面的pod1打个标签叫app=myapp 

    [root@master networkpolicy]# kubectl label pods pod1 app=myapp -n dev
    pod/pod1 labeled
    

      

    [root@master networkpolicy]# cat allow-netpol-demo.yaml 
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-myapp-ingress
    spec:
      podSelector:
        matchLabels:
          app: myapp
      ingress: #入站
      - from:
        - ipBlock:
            cidr: 10.244.0.0/16 #指定网段,允许从10.244.0.0/16入站到pod里面
            except:
            - 10.244.1.2/32 #排除这个地址
        ports:
        - protocol: TCP
          port: 80
    

      

    [root@master networkpolicy]# kubectl apply -f allow-netpol-demo.yaml -n dev
    networkpolicy.networking.k8s.io/allow-myapp-ingress created
    

      

    [root@master networkpolicy]# kubectl get netpol -n dev
    NAME                  POD-SELECTOR   AGE
    allow-myapp-ingress   app=myapp      1m
    deny-all-ingress      <none>         5h
    

      

    [root@master networkpolicy]# curl 10.244.2.2 #看到加了allow-myapp-ingress网络策略后,立即就能访问dev里面的pod了
    Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
    

      

        上面我们介绍了ingress入站规则,下面我们介绍egress出站规则。

    [root@master networkpolicy]# cat egress-def.yaml
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-all-egress
    spec:
      podSelector: {} #pod选择器设置为空,表示选择所有pod,即控制整个名称空间
      policyTypes:
      - Egress #表示只对egress生效
    

      

    [root@master networkpolicy]# kubectl apply -f egress-def.yaml -n prod
    networkpolicy.networking.k8s.io/deny-all-egress created
    

      

    [root@master ~]# kubectl get pods -n kube-system -o wide
    NAME                                   READY     STATUS    RESTARTS   AGE       IP             NODE
    canal-7q4k7                            3/3       Running   0          6h        172.16.1.101   node1
    canal-dk2tc                            3/3       Running   0          6h        172.16.1.102   node2
    canal-zr8l4                            3/3       Running   0          6h        172.16.1.100   master
    coredns-78fcdf6894-2l2cf               1/1       Running   18         24d       10.244.0.46    master
    coredns-78fcdf6894-dkkfq               1/1       Running   17         24d       10.244.0.45    master
    etcd-master                            1/1       Running   18         24d       172.16.1.100   master
    kube-apiserver-master                  1/1       Running   19         24d       172.16.1.100   master
    kube-controller-manager-master         1/1       Running   18         24d       172.16.1.100   master
    [root@master networkpolicy]# kubectl get pods -n prod
    NAME      READY     STATUS    RESTARTS   AGE
    pod1      1/1       Running   0          1h
    [root@master networkpolicy]# kubectl exec pod1 -it  -n prod -- /bin/sh
    / # ping 10.244.0.45  #看到ping其他名称空间的容器被拒绝,这就是因为网络策略deny-all-egress起的作用,它表示拒绝容器所有出口流量
    PING 10.244.0.45 (10.244.0.45): 56 data bytes
    

      

    [root@master networkpolicy]# cat egress-def.yaml 
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-all-egress
    spec:
      podSelector: {} #pod选择器设置为空,表示选择所有pod,即控制整个名称空间
      egress:
      - {} #表示允许所有egress出去的流量
      policyTypes:
      - Egress #表示只对egress生效
    

      

    [root@master networkpolicy]# kubectl apply -f egress-def.yaml -n prod
    

      

    [root@master networkpolicy]# kubectl exec pod1 -it  -n prod -- /bin/sh #看到放行出站后,容器就可以ping通外部的容器了
    / # ping 10.244.0.45
    PING 10.244.0.45 (10.244.0.45): 56 data bytes
    64 bytes from 10.244.0.45: seq=0 ttl=62 time=0.227 ms
    64 bytes from 10.244.0.45: seq=1 ttl=62 time=0.284 ms
    

      

     我们为了更安全,我们可以设置每个名称空间拒绝所有入站,拒绝所有出站,然后再单独放行。不过,这样也出现一个问题,就是一个名称空间中,所有pod之间也不能通信了。所以还要加条策略就是允许本名称空间中的pod之间可以互相通信(放行所有出站目标本名称空间内的所有pod),但是不允许和外部名称空间之间进行通信。 

  • 相关阅读:
    [学习日记]进程、线程和模块
    [学习日记]对SOAP头内添加信息的验证,可实现对请求WEB服务进行身份验证。
    [梦里原创]关于猫和老鼠的问题(程序算法)
    [学习日记]对控件的继承和重载
    [学习日记]VB图像处理之像素的获取和输出
    猫和老鼠问题的讨论
    [音乐欣赏]丁香花
    推荐一个WINDOWS系统文件介绍的网站
    [转]查查在中国有多少人的名字和你一样!
    计算机语言发展图解
  • 原文地址:https://www.cnblogs.com/dribs/p/10318936.html
Copyright © 2020-2023  润新知