12.基于canel的网络策略

参考文档:https://docs.projectcalico.org/v3.8/getting-started/kubernetes/

一、Calico作为网络插件提供网络功能

Calico:基于BGP网络协议来通过自动学习判定生成路由条目。

隧道方式:IPIP

路由方式:BGP

默认网段192.168.0.0/16。

二、Calico提供网络策略

1、安装部署

不同环境,使用目的不同,安装方式不同,参考官方文档

也依赖etcd,可通过api-server去写k8s的etcd,或独立部署一个etcd集群。

当使用flannel提供网络功能,calico提供策略控制时,部署如下:

[root@master ~]# curl https://docs.projectcalico.org/v3.8/manifests/canal.yaml -O
[root@master ~]# kubectl apply -f canal.yaml

2、网络策略控制

网络策略都是针对Pod的入和出,Pod级别。

创建两个namespace -- dev,prod

[root@master ~]# kubectl explain networkpolicy.spec
[root@master ~]# kubectl explain networkpolicy.spec.policyTypes  
  # 如果不指定此值,并且Ingress,Egress都没有定义规则,则二者都使用默认规则,一般情况下,我们会把默认规则都设置为拒绝。只需要哪一个生效,就必须显式指明,否则都会生效,没有定义策略的情况下会走到默认策略。

(1)设置ingress默认策略

默认ingress策略为拒绝所有入站请求,egress不处理。

 

[root@master networkpolicy]# kubectl apply -f ingress-def.yaml -n dev

测试:

[root@master networkpolicy]# kubectl apply -f pod-demo.yaml  -n dev
[root@master networkpolicy]# kubectl apply -f pod-demo.yaml  -n prod 

 

此时dev名称空间访问不到,但prod可以,因为dev定义了ingress策略。

(2)设置策略为允许所有入站

 

测试:

[root@master networkpolicy]# kubectl apply -f ingress-def.yaml -n dev
[root@master networkpolicy]# curl 10.244.2.2 

(3)指定特定入站访问策略

允许特定网段访问标签为app=myapp的Pod的80,443端口。

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

[root@master networkpolicy]# kubectl apply -f allow-netpol-demo.yaml -n dev

测试:

 

主机不可达是有问题的,需排查。正常被网络策略限制不可达的情况应该是无响应,挂起。

主机不可达,是因为是两个Pod在同一台节点上。具体原因待查。初步排查:部署canal时,路由被calico改变了,具体问题待确定。

 

(4)问题汇总

问题1:如果设置flannel的后端为Directing的VxLAN,则部署canal时应修改一下配置清单,canal.yaml默认有指定flannel后端为默认的VxLAN,之前的路由会被改变为如上图。

部署时canal.yaml会覆盖部署flannel时的clusterrole.rbac.authorization.k8s.io,删除也是。

问题2:删除重装等各种折腾,会因为之前划分的网络有缓存,出现奇奇怪怪的问题,比如路由表不全导致node不能与Pod通信,解决办法,挨个重启。网络不熟还是不要乱折腾。

[root@node2 ~]# systemctl stop kubelet
[root@node2 ~]# systemctl stop docker
[root@node2 ~]# ifconfig cni0 down
[root@node2 ~]# systemctl start kubelet
[root@node2 ~]# systemctl start docker
[root@node2 ~]# ifconfig cni0 up

并且网络重置后,之前运行的Pod都启动不了,更新不到新的网络(error: unable to upgrade connection: container not found ("myapp")),并且新建pod也是一样,具体报错如下:

解决方案:

莫名其妙自己好了。???不清楚什么情况

可能是因为刚开始装过canal,所以在/etc/cni/net.d/目录下有cnnal的配置(10-canal.conflist、calico-kubeconfig),然后集群自己去加载了,在修复过程中,找到了删除了,但是问题还是存在,没立即解决,所以不确定是不是这个问题。

问题3:

相同node的pod间不能通信,不同node的通信没有问题,现象如下:

 

原因分析:出现此现象是在[root@master canal]# kubectl apply -f canal.yaml后,之前创建的Pod在同节点仍然可以通信,但新建的pod如果在同节点就不能通信。初步判断为应用canal.yaml时,改变了集群使用的cni组件(查看新建Pod的详细信息及pod所在主机的路由表可以确认),导致新建的pod使用的网络服务是calico,所以通信存在问题。与问题2类似。具体原因需了解apply具体做了哪些操作。

 

[root@node1 net.d]# cd /etc/cni/net.d/
[root@node1 net.d]#  rm -f 10-canal.conflist calico-kubeconfig

删除所有节点上的canal的配置文件,再次创建Pod,不会出现上述问题。故猜测,是多种网络插件共用导致。部署时未能将两种网络插件分别使用的功能区分开(flannel提供网络服务,用calico提供网络策略),还需好好了解。

3、总结:

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

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

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

原文地址:https://www.cnblogs.com/cmxu/p/12255532.html