k8s-基于canel的网络策略-十九

一、前提

上一节学习了flannel,但是我们应该了解flannel只能提供网络通讯,而不能提供网络策略。因此,我们本节学习canal,让它来提供网络策略,来配合flannel使用。

canal是calico的一个项目;

calico的网址:https://docs.projectcalico.org/v3.6/introduction/

Installing Calico for policy and flannel for networking:

https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/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

https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/flannel

部署:

(1)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

image

(2)Issue the following command to install Calico.

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

image

稍等片刻,查看:

[root@master ~]# kubectl get pods -n kube-system

image

image

    Egres:出站,表示pod自己是客户端,访问别人。
     Ingress:入站,表示Pod自己是目标,别人来访问自己。
     通常,客户端的端口是随机的,服务端的端口是固定的。
     Network Policy:用来控制哪个pod来和外部或内部进行通信。
     podSelecto:pod选择器
     policyTypes:用来控制Ingres和Egres哪个生效。

 

使用:

(3)示例: ingress

建立两个namespace,在两个namespace里再创建pod,让两个namespace里的pod通信,并添加策略控制;

建立两个名称空间,一个模拟测试,一个模拟生产;

image

a、查看资源定义清单字段

[root@master ~]# kubectl explain networkpolicy

[root@master ~]# kubectl explain networkpolicy.spec

b、定义一个ingress,拒绝的所有的,只对特定的开放;

image

image

可以出去,但是别人不能进来

c、创建ingress

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

查看

image

d、在dev命名空间中创建pod,看能不能被访问

[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     NOMINATED NODE   READINESS GATES
pod1   1/1     Running   0          9m5s   10.244.1.2   node01   <none>           <none>

[root@master networkpolicy]# curl 10.244.1.2       #测试证明不能被访问

 

e、在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     NOMINATED NODE   READINESS GATES
pod1   1/1     Running   0          31s   10.244.1.3   node01   <none>           <none>
[root@master networkpolicy]# curl 10.244.1.3
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>  #可以访问到

f、下面改一下ingress资源定义清单,允许所有入站;

[root@master networkpolicy]# vim ingress-def.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {}
  ingress:
  - {}  #表示允许所有
  policyTypes:
  - Ingress
[root@master networkpolicy]# kubectl apply -f ingress-def.yaml -n dev
networkpolicy.networking.k8s.io/deny-all-ingress configured
[root@master networkpolicy]# kubectl get pods -n dev -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
pod1   1/1     Running   0          28m   10.244.1.2   node01   <none>           <none>
[root@master networkpolicy]# curl 10.244.1.2
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>  #此时可以访问了
[root@master networkpolicy]# curl 10.244.1.3
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

g、将dev命令空间中的pod1打标,稍后设定能访问有此标签的pod的80端口;

[root@master networkpolicy]# kubectl label pods pod1 app=myapp -n dev  #打标签
pod/pod1 labeled
[root@master networkpolicy]# vim 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    #但是不允许这个地址
    ports:
    - protocol: TCP
      port: 80        #开放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      16s
deny-all-ingress      <none>         76m
[root@master networkpolicy]# 
[root@master networkpolicy]# curl 10.244.1.2    #访问
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

(4)egress

a、创建egress(拒绝所有),并生效到prod名称空间

[root@master networkpolicy]# vim egress-def.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress        #拒绝所有出站流量

[root@master networkpolicy]# kubectl apply -f egress-def.yaml -n prod
networkpolicy.networking.k8s.io/deny-all-egress created
[root@master networkpolicy]# kubectl get pods -n prod
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          63m
[root@master ~]# kubectl get pods -n kube-system -o wide |grep coredns
coredns-86c58d9df4-8lwrg                1/1     Running   9          74d    10.244.0.18     master   <none>           <none>
coredns-86c58d9df4-z66dd                1/1     Running   8          74d    10.244.0.19     master   <none>           <none>

[root@master networkpolicy]# kubectl exec pod1 -it -n prod -- /bin/sh    
/ # ping 10.244.0.18    #连入prod下的pod,ping coredns,发现ping不通

b、放行所有

[root@master networkpolicy]# vim egress-def.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
spec:
  podSelector: {}
  egress:
  - {}     #允许所有出站流量
  policyTypes:
  - Egress

[root@master networkpolicy]# kubectl  apply -f egress-def.yaml -n prod
networkpolicy.networking.k8s.io/deny-all-egress configured
[root@master networkpolicy]# 
[root@master networkpolicy]# kubectl exec pod1 -it -n prod -- /bin/sh    #连入
/ # ping 10.244.0.18
PING 10.244.0.18 (10.244.0.18): 56 data bytes
64 bytes from 10.244.0.18: seq=0 ttl=62 time=43.914 ms   #可以ping通了
64 bytes from 10.244.0.18: seq=1 ttl=62 time=0.403 ms

 

为了安全,我们可以先设置每个名称空间拒绝所有入站、拒绝所有出站,然后单独放行;

但是这样也会有一个问题,就是同一名称空间的pod也不能通信;

所以还要加条策略就是允许本名称空间的pod之间可以互相通信(放行所有出站目标为本名称空间内的所有pod),但是不允许和外部名称空间之间进行通信;

posted @ 2019-03-14 14:58  米兰的小铁將  阅读(1102)  评论(0编辑  收藏  举报