114.kubernetes之calico

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了114.kubernetes之calico相关的知识,希望对你有一定的参考价值。

参考技术A

calico包括如下重要组件:calico/node,Typha,Felix,etcd,BGP Client,BGP Route Reflector。

calico/node:把Felix,calico client, confd,Bird封装成统一的组件作为统一入口,同时负责给其他的组件做环境的初始化和条件准备。

Felix:主要负责路由配置以及ACLS规则的配置以及下发,它存在在每个node节点上。

etcd:存储各个节点分配的子网信息,可以与kubernetes共用;

BGPClient(BIRD), 主要负责把 Felix写入 kernel的路由信息分发到当前 Calico网络,确保 workload间的通信的有效性;

BGPRoute Reflector(BIRD), 大规模部署时使用,在各个节点之间不是mesh模式,通过一个或者多个 BGPRoute Reflector 来完成集中式的路由分发;当etcd中有新的规则加入时,Route Reflector 就会将新的记录同步。

Typha:在节点数比较多的情况下,Felix可通过Typha直接和Etcd进行数据交互,不通过kube-apiserver,既降低其压力。生产环境中实例数建议在3~20之间,随着节点数的增加,按照每个Typha对应200节点计算。

配置

相关操作

//由于我的环境是kube-router需要将以前的数据清理下,如果遇到问题需要清理也可以按照如下步骤

删除网卡

删除node已经分配的podCIDR

kube-manager

kubelet

[root@host229 ~]# etcdctl get / --prefix --keys-only |grep minions
/registry/minions/host214
/registry/minions/host227
/registry/minions/host228
/registry/minions/host229
[root@host229 ~]# etcdctl del /registry/minions/host214
[root@host229 ~]# etcdctl del /registry/minions/host227
[root@host229 ~]# etcdctl del /registry/minions/host228
[root@host229 ~]# etcdctl del /registry/minions/host229

文件模板地址
https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/

calico有两种模式iptable和ipvs,之一通过调整kube-proxy中的--proxy-mode=ipvs 来指定,相比iptables模式,ipvs模式性能更好,能够支持更大的集群规模。

Kubernetes之NetworkPolicy,Flannel和Calico

参考技术A

Pod是Kubernetes调度的最小单元。一个Pod可以包含一个或多个容器,因此它可以被看作是内部容器的逻辑宿主机。Pod的设计理念是为了支持多个容器在一个Pod中共享网络和文件系统。那么为什么Pod内的容器能够共享网络,IPC和PID命名空间?

原因:Kubernetes在每个Pod启动时,会自动创建一个镜像为gcr.io/google_containers/pause:version的容器,所有处于该Pod中的容器在启动时都会添加诸如--net=container:pause --ipc=contianer:pause --pid=container:pause的启动参数,因此Pod内所有容器共用pause容器的network,IPC和PID命名空间。所有容器共享pause容器的IP地址,也被称为Pod IP。因此处于同一个Pod内的容器,可以通过localhost进行相互访问。

在讲K8s Pod间通信前,我们先复习一下Docker容器间的网络通信。默认情况下,Docker使用一种名为bridge的网络模型。如下图所示:

Docker引擎在启动时,会在宿主机上创建一个名为docker0的虚拟网桥,这个虚拟网桥负责给所有容器分配不重复的ip地址以及容器间的网络通信。首先,Docker在创建一个容器时,会执行以下操作:

通过这个docker0网桥,同一宿主机上的容器可以互相通信。然而由于宿主机的IP地址与容器veth pair的 IP地址均不在同一个网段,故仅仅依靠veth pair和namespace的技术,还不足以使宿主机以外的网络主动发现容器的存在。为了使外界可以访问容器中的进程,docker采用了端口绑定的方式,也就是通过iptables的NAT,将宿主机上的端口端口流量转发到容器内的端口上。

K8s 默认不提供网络功能,所有Pod的网络功能,都依赖于宿主机上的Docker。因此,Pod IP即是依靠docker0网桥分配给pause容器的虚拟IP。

同一个Node内,不同的Pod都有一个docker0网桥分配的IP,可以直接通过这个IP进行通信。Pod IP和docker0在同一个网段。因此,当同节点上的Pod-A发包给Pod-B时,包传送路线如下:

不同的Node之间,Node的IP相当于外网IP,可以直接访问,而Node内的docker0和Pod的IP则是内网IP,无法直接跨Node访问。因此,不同Node上的Pod间需要通信,需要满足以下两个条件:

因此,为了实现以上两个需求,K8s提供了CNI(Container Network Interface)供第三方实现从而进行网络管理。由此出现了一系列开源的Kubernetes中的网络插件与方案,包括:flannel,calico,cilium等等。这些网络插件集中解决了以下需求:

CNI的介绍请参考这篇文章: https://jimmysong.io/kubernetes-handbook/concepts/cni.html

在默认的Docker配置中,每个节点上的Docker服务会分别负责所在节点容器的IP分配。这样导致的一个问题是,不同节点上容器可能获得相同的内外IP地址。

Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。

Flannel实质上是一种“覆盖网络(overlay network)”,也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持UDP、VxLAN、AWS VPC和GCE路由等数据转发方式,默认的节点间数据通信方式是UDP转发。下图展示了数据包在flannel中的流转:

Flannel是一种典型的Overlay网络,它将已有的物理网络(Underlay网络)作为基础,在其上建立叠加的逻辑网络,实现网络资源的虚拟化。Overlay网络有一定额外的封包和解包等网络开销,对网络通信的性能有一定损耗。

Calico是纯三层的SDN 实现,它基于BPG 协议和Linux自身的路由转发机制,不依赖特殊硬件,容器通信也不依赖iptables NAT或Tunnel 等技术。能够方便的部署在物理服务器、虚拟机(如 OpenStack)或者容器环境下。同时calico自带的基于iptables的ACL管理组件非常灵活,能够满足比较复杂的安全隔离需求。

Calico 还基于 iptables 还提供了丰富而灵活的网络 policy, 保证通过各个节点上的 ACLs 来提供 workload 的多租户隔离、安全组以及其他可达性限制等功能。

核心问题是,nodeA怎样得知下一跳的地址?答案是node之间通过BGP协议交换路由信息。

每个node上运行一个软路由软件bird,并且被设置成BGP Speaker,与其它node通过BGP协议交换路由信息。

可以简单理解为,每一个node都会向其它node通知这样的信息:

我是X.X.X.X,某个IP或者网段在我这里,它们的下一跳地址是我。

通过这种方式每个node知晓了每个workload-endpoint的下一跳地址。

K8s NetworkPoclicy 用于实现Pod间的网络隔离。在使用Network Policy前,必须先安装支持K8s NetworkPoclicy的网络插件,包括:Calico,Romana,Weave Net,Trireme,OpenContrail等。

在未使用NetworkPolicy前,K8s中所有的Pod并不存在网络隔离,他们能够接收任何网络流量。一旦使用NetworkPolicy选中某个namespace下的某些Pod,那么这些Pod只能接收特定来源的流量(由Ingress属性定义),并且只能向特定出口发送网络请求(由Egress属性定义)。其他未被这个NetworkPolicy选中的Pod,依然不具备网络隔离。

下面是一个NetworkPolicy的例子:

下面的例子表示默认禁止所有Pod间的Ingress流量:

默认拒绝所有 Pod 之间 Egress 通信的策略为:

而默认允许所有 Pod 之间 Ingress 通信的策略为:

默认允许所有 Pod 之间 Egress 通信的策略为:

以 calico 为例看一下 Network Policy 的具体用法。首先配置 kubelet 使用 CNI 网络插件:

安装 calio 网络插件:

首先部署一个 nginx 服务,此时,通过其他 Pod 是可以访问 nginx 服务的:

开启 default namespace 的 DefaultDeny Network Policy 后,其他 Pod(包括 namespace 外部)不能访问 nginx 了:

最后再创建一个运行带有 access=true label的 Pod 访问的网络策略:

以上是关于114.kubernetes之calico的主要内容,如果未能解决你的问题,请参考以下文章

入门设计模式之汇总篇

计算机领域之父

JavaWeb之Ajax&JSON

JavaWeb之redis&Jedis

圣杯之战第12集Saber第一次使用契约胜利之剑打败Rider骑英之缰绳!

开发语言之---Python