参考文档: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提供策略控制时,部署如下:
[[email protected] ~]# curl https://docs.projectcalico.org/v3.8/manifests/canal.yaml -O [[email protected] ~]# kubectl apply -f canal.yaml
2、网络策略控制
网络策略都是针对Pod的入和出,Pod级别。
创建两个namespace -- dev,prod
[[email protected] ~]# kubectl explain networkpolicy.spec [[email protected] ~]# kubectl explain networkpolicy.spec.policyTypes # 如果不指定此值,并且Ingress,Egress都没有定义规则,则二者都使用默认规则,一般情况下,我们会把默认规则都设置为拒绝。只需要哪一个生效,就必须显式指明,否则都会生效,没有定义策略的情况下会走到默认策略。
(1)设置ingress默认策略
默认ingress策略为拒绝所有入站请求,egress不处理。
[[email protected] networkpolicy]# kubectl apply -f ingress-def.yaml -n dev
测试:
[[email protected] networkpolicy]# kubectl apply -f pod-demo.yaml -n dev[[email protected] networkpolicy]# kubectl apply -f pod-demo.yaml -n prod
此时dev名称空间访问不到,但prod可以,因为dev定义了ingress策略。
(2)设置策略为允许所有入站
测试:
[[email protected] networkpolicy]# kubectl apply -f ingress-def.yaml -n dev [[email protected] networkpolicy]# curl 10.244.2.2
(3)指定特定入站访问策略
允许特定网段访问标签为app=myapp的Pod的80,443端口。
[[email protected] networkpolicy]# kubectl label pods pod1 app=myapp -n dev
[[email protected] 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通信,解决办法,挨个重启。网络不熟还是不要乱折腾。
[[email protected] ~]# systemctl stop kubelet [[email protected] ~]# systemctl stop docker [[email protected] ~]# ifconfig cni0 down [[email protected] ~]# systemctl start kubelet [[email protected] ~]# systemctl start docker [[email protected] ~]# 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的通信没有问题,现象如下:
原因分析:出现此现象是在[[email protected] canal]# kubectl apply -f canal.yaml后,之前创建的Pod在同节点仍然可以通信,但新建的pod如果在同节点就不能通信。初步判断为应用canal.yaml时,改变了集群使用的cni组件(查看新建Pod的详细信息及pod所在主机的路由表可以确认),导致新建的pod使用的网络服务是calico,所以通信存在问题。与问题2类似。具体原因需了解apply具体做了哪些操作。
[[email protected] net.d]# cd /etc/cni/net.d/ [[email protected] 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