一图看懂Calico架构原理

一、Calico简介

1. 什么是Calico

Calico是一个用于容器、虚拟机和基于本地主机的工作负载的开源网络和网络安全解决方案。Calico支持广泛的平台,包括Kubernetes、OpenShift、Docker EE、OpenStack和bare metal服务。Calico将灵活的网络功能与随处运行的安全实施相结合,提供了一个具有本地Linux内核性能和真正的云本地可伸缩性的解决方案。
总之,calico是把Host当做Internet中的路由器,使用BGP同步路由,并使用iptables来做安全访问策略,设计出了Calico方案。

2. 为什么使用Calico

  1. 针对网络安全的最佳实践
    Calico丰富的网络策略模型使得锁定通信变得很容易,所以唯一的流量就是你想要的流量。您可以将Calico的安全增强看作是用它自己的个人防火墙来包装您的每个工作负载,当您部署新服务或将应用程序向上或向下扩展时,防火墙会实时动态地重新配置。

Calico的策略引擎可以在主机网络层(如果使用Istio & Envoy)和服务网格层(如果使用Istio & Envoy)执行相同的策略模型,保护您的基础设施不受工作负载影响。

  1. 性能
    Calico使用Linux内核内置的高度优化的转发和访问控制功能来提供本地Linux网络数据平面性能,通常不需要任何与第一代SDN网络相关的encap/decap开销。

  2. 扩容
    Calico的核心设计原则利用了最佳实践的云原生设计模式,并结合了全球最大的互联网运营商所信任的基于标准的网络协议。其结果是一个具有非凡可伸缩性的解决方案,多年来一直在生产中大规模运行。Calico的开发测试周期包括定期测试数千个节点集群。无论您运行的是10个节点集群、100个节点集群还是更多,您都可以获得最大Kubernetes集群所要求的性能和可伸缩性特性的改进。

  3. 互操作
    Calico支持Kubernetes工作负载和非Kubernetes或遗留工作负载无缝且安全地通信。Kubernetes pods是您网络上的一等公民,能够与网络上的任何其他工作负载进行通信。此外,Calico可以无缝地扩展,以保护与Kubernetes一起的现有基于主机的工作负载(无论是在公共云中,还是在VMs上的on-prem或裸机服务器上)。所有工作负载都受制于相同的网络策略模型,因此允许流的惟一流量就是您希望流的流量。

  4. 和linux有很多相似之处
    Calico使用现有系统管理员已经熟悉的Linux术语。输入您喜欢的Linux网络命令,您将得到您期望的结果。在绝大多数部署中,离开应用程序的包是通过网络传输的包,没有封装、隧道或覆盖。系统和网络管理员用来获得可见性和分析网络问题的所有现有工具都像现在一样工作。

  5. 针对Kubernetes网络策略的支持
    Calico的网络策略引擎在API的开发过程中形成了Kubernetes网络策略的原始参考实现。Calico的独特之处在于它实现了API定义的全部特性,为用户提供了API定义时所设想的所有功能和灵活性。对于需要更强大功能的用户,Calico支持一组扩展的网络策略功能,这些功能与Kubernetes API一起无缝地工作,为用户定义网络策略提供了更大的灵活性。

Calico在kubernetes集群中创建和管理一个三层的网络,该网络提供了Pod间的通信。 它为Pods提供了可路由的IP地址,从而使互操作性更加容易。Calico允许实施网络安全策略,提供对pod之间通信的细粒度控制。

二、Calico架构

1. Calico主要由下列组件组成:

  • calico/node: 该agent作为Calico守护进程的一部分运行。它管理接口,路由和接点的状态报告及强制性策略。

  • BIRD: 一个BGP的客户端,由Felix程序广播路由。

  • Etcd: 一个可选的分布式数据库存储。

  • Calico Controller: Calico策略控制器。

1.1 CALICO/NODE:

calico/node是一个由两个容器组成的Pod

  1. 一个calico/node容器运行两个守护进程。
    a. Felix
    b. the Bird BGP daemon (optional)

  2. A calico-CNI插件, 响应来自节点上的kubelet的CNI请求。

这个Felix组件是Calico网络的核心。它运行在集群中的每个节点上,它主要负责接口、路由的管理、状态报告及强制性策略。

1.1.1 接口和路由的管理

Felix守护进程负责编程接口并在内核路由表中创建路由,以便在创建pod时为它们提供可路由的IP地址。Felix创建虚拟的网络接口,并且针对每个pod从Calico IPAM中分配一个IP地址。 接口一般以cali前辍开头,除非明确指定

1.1.2 状态报告

Felix通过监视工具(如Prometheus)公开用于实例状态报告的度量。

1.1.3 强制性策略

Felix负责网络策略的实施。Felix监视Pod上的标签,并与定义的网络策略对象进行比较,以决定是否允许或拒绝Pod的流量。Felix将有关接口及其IP地址和主机网络状态的信息写入etcd。

image.png
1.2 BIRD

BIRD是一个BGP守护进程,它将Felix编写的路由信息分发给集群节点上的其他BIRD代理。BIRD agent是和Calico守护进程的Pod一起安装的。这确保了流量是跨节点可路由的。默认情况下,Calico创建一个完整的网格拓扑。这意味着每个BIRD代理都需要连接到集群中的其他所有BIRD代理。

对于较大的部署,BIRD可以配置为路由反射器。路由反射器拓扑允许将BIRD设置为其他BIRD代理通信的集中点。它还减少了每个BGP代理打开连接的数量。

1.3 ETCD

Calico使用一个称为etcd的分布式数据存储,存储Calico资源配置和网络策略规则。Felix守护进程与etcd数据存储进行通信,用于发布每个节点的路由、节点和接口信息。

为了获得更高的可用性,应该为大型部署设置多节点etcd集群。在这个设置中,etcd确保在etcd集群中复制Calico配置,使它们始终处于最后已知的良好状态。

一个可选的部署模型是使用Kubernetes API服务器作为分布式数据存储,从而消除了构建和维护etcd数据存储的需要。

2. calico组件协同工作案例演示

在Kubernetes集群上部署三个nginx pod的示例演示了这些组件如何协同工作以提供网络。

  1. 当一个nginx pods调度到kubernetes节点上时,Felix创建一个以cali前辍的网络虚拟接口。并且分配给它一个/32的IP地址。
$ kubectl get pods -o wide
NAME                        READY   STATUS    RESTARTS   AGE     IP               NODE               NOMINATED NODE   READINESS GATES
my-nginx-5d998f947f-dgmrv   1/1     Running   0          102s    10.244.215.169   c720117.xiodi.cn              
my-nginx-5d998f947f-g8mgj   1/1     Running   2          2d15h   10.244.13.94     c720116.xiodi.cn              
my-nginx-5d998f947f-gn5hd   1/1     Running   0          102s    10.244.213.164   c720115.xiodi.cn              
my-nginx-5d998f947f-vb2jb   1/1     Running   0          102s    10.244.220.81    c720114.xiodi.cn              
  1. 请注意my-nginx-5d998f947f-vb2jbpod是调度到了c720114.xiodi.cn主机上面,且Pod的地址为10.244.220.81。在c720114.xiodi.cn主机上执行如下:
[root@c720114 ~]# ip route show
default via 192.168.20.1 dev eth0 proto static metric 100 
10.244.13.64/26 via 192.168.20.116 dev tunl0 proto bird onlink 
10.244.106.64/26 via 192.168.20.113 dev tunl0 proto bird onlink 
10.244.117.64/26 via 192.168.20.111 dev tunl0 proto bird onlink 
10.244.123.128/26 via 192.168.20.112 dev tunl0 proto bird onlink 
10.244.213.128/26 via 192.168.20.115 dev tunl0 proto bird onlink 
blackhole 10.244.220.64/26 proto bird 
10.244.220.76 dev cali791e7a948a6 scope link 
10.244.220.77 dev cali1577b57a2a2 scope link 
10.244.220.78 dev calib7e5b49a5fc scope link 
10.244.220.79 dev cali15c7619fccc scope link 
`10.244.220.81 dev cali9ee09c33a93 scope link `
  1. 查看关于cali9ee09c33a93接口的详细信息.
[root@c720114 ~]# ip a show dev cali9ee09c33a93
13: cali9ee09c33a93@if4:  mtu 1440 qdisc noqueue state UP group default 
    link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 4
    inet6 fe80::ecee:eeff:feee:eeee/64 scope link 
       valid_lft forever preferred_lft forever
  1. 进入它的容器,应该能看到它的Mac地址和第3步显示的一样。
[root@c720111 ~]# kubectl exec -it my-nginx-5d998f947f-vb2jb  -- /bin/sh

[info]以上证明了calico创建了网络接口,并分配给Pod一个ip地址。

  1. BIRD BGP守护进程意识到出现了一个新的网络接口,并通知其他节点。

我们在其它节点上进行查看如下所示:

ip route show
default via 192.168.20.1 dev eth0 proto static metric 100 
10.244.13.64/26 via 192.168.20.116 dev tunl0 proto bird onlink 
10.244.106.64/26 via 192.168.20.113 dev tunl0 proto bird onlink 
10.244.117.64/26 via 192.168.20.111 dev tunl0 proto bird onlink 
10.244.123.128/26 via 192.168.20.112 dev tunl0 proto bird onlink 
blackhole 10.244.213.128/26 proto bird 
10.244.213.156 dev cali8739340ad20 scope link 
10.244.213.157 dev cali1abad8afd57 scope link 
10.244.213.158 dev cali11239f98883 scope link 
10.244.213.159 dev cali19a12db9068 scope link 
10.244.213.160 dev cali0ff1fd6ec86 scope link 
10.244.213.161 dev calibf2f53a4925 scope link 
10.244.213.162 dev cali06d2d365420 scope link 
10.244.213.163 dev cali2bb02659332 scope link 
10.244.213.164 dev calidab80719a39 scope link 

`10.244.220.64/26 via 192.168.20.114 dev tunl0 proto bird onlink `

172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
192.168.20.0/24 dev eth0 proto kernel scope link src 192.168.20.115 metric 100 

三、Calico网络和策略的安装

参考链接: https://docs.projectcalico.org/v3.11/getting-started/kubernetes/installation/calico

0. 如果安装了flannel,执行如下

# 删除flannel
$ kubectl delete -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

# 在node节点清理flannel网络留下的文件
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/
rm -f /etc/cni/net.d/*
注:执行上面的操作,重启kubelet

# 第三步,应用calico相关的yaml文件

1. 安装的先决条件

  • kube-proxy: 配置为不运行 --masquerade-all选项,因为这与Calico冲突。

  • kubelet: 针对网络必须配置使用CNI插件。--network-plugin=cni

  • kube-proxy: 必须运行iptables的代理模式,这是默认选项。

2. 执行安装

Calico是作为kubernetes集群的daemonset进行部署的。因此它确保了集群中的每个节点都会安装。

  1. 针对50个节点或小于50个节点的安装方法如下:
  • 下载calico.yaml文件
curl https://docs.projectcalico.org/v3.11/manifests/calico.yaml -O
  • 假如使用192.168.0.0/16段的网络,直接跳过本步骤。假如使用别的网络,请取代下面的192.168.0.0/16
POD_CIDR="" \
sed -i -e "s?192.168.0.0/16?$POD_CIDR?g" calico.yaml
  • 使用下面命令应用manifest
kubectl apply -f calico.yaml
  1. 针对超过50个节点的安装方法如下:
  • 下载calico.yaml文件
curl https://docs.projectcalico.org/v3.11/manifests/calico-typha.yaml -o calico.yaml
    • 假如使用10.244.0.0/16段的网络,直接跳过本步骤。假如使用别的网络,请取代下面的10.244.0.0/16
POD_CIDR="" \
sed -i -e "s?10.244.0.0/16?$POD_CIDR?g" calico-typha.yaml
  • 在Deployment中修改replica的数量。
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: calico-typha
  ...
spec:
  ...
  replicas: 

[warning]我们建议每200个节点至少有一个副本,不超过20个副本。在生产中,我们建议至少使用三个副本来减少滚动升级和故障的影响。副本的数量应该总是小于节点的数量,否则滚动升级将会停止。此外,只有当Typha实例少于节点时,Typha才有助于扩大规模

  • 应用清单文件
kubectl apply -f calico.yaml
  1. 使用带有etcd数据存储的方式(就是使用外部的etcd存储,需要指定外部etcd存储的地址等信息)
  • 下载calico.yaml文件
curl https://docs.projectcalico.org/v3.11/manifests/calico-etcd.yaml -o calico.yaml
  • 假如使用10.244.0.0/16段的网络,直接跳过本步骤。假如使用别的网络,请取代下面的10.244.0.0/16
POD_CIDR="" \
sed -i -e "s?10.244.0.0/16?$POD_CIDR?g" calico-etcd.yaml
  • 在名为calico-config的ConfigMap中,将etcd_endpoint的值设置为etcd服务器的IP地址和端口。

  • 应用清单文件

kubectl apply -f calico.yaml

四、Calico的部署

Calico提供一个名为calicoctl的命令行实用程序,用于管理Calico配置。运行calicoctl实用程序的主机需要连接到Calico etcd数据存储。另外,可以将calicoctl配置为连接到Kubernetes API数据存储。

您可以在任何可以通过网络访问Calico数据存储的主机上以二进制或容器的形式运行calicoctl。其中有三种的安装方式:

  • 在单一的主机上作为二进制进行安装

  • 在单一的主机上作为容器进行安装

  • 作为kubernetes pod进行安装

1. 在单一的主机上作为二进制安装calicoctl

  1. 下载calicoctl 二进制文件
$ curl -O -L  https://github.com/projectcalico/calicoctl/releases/download/v3.11.1/calicoctl
  1. 设置文件为可执行
$ chmod +x calicoctl
  1. 把calicoctl移动到可搜索的路径
$ mv calicoctl /usr/local/bin
  1. 配置calicoctl的配置文件
$ cat /etc/calico/calicoctl.cfg
apiVersion: projectcalico.org/v3
kind: CalicoAPIConfig
metadata:
spec:
  datastoreType: "kubernetes"
  kubeconfig: "/root/.kube/config"

2. 在单一的主机上作为容器安装calicoctl

$ docker pull calico/ctl:v3.11.1

3. 安装calicoctl作为Kubernetes pod

使用与数据存储类型匹配的YAML将calicoctl容器部署到节点。

  • etcd
$ kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calicoctl-etcd.yaml

  • Kubernetes API存储
$ kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calicoctl.yaml
  • 可以使用kubectl命令显示如下:
$ kubectl exec -ti -n kube-system calicoctl -- /calicoctl get profiles -o wide

NAME                 TAGS
kns.default          kns.default
kns.kube-system      kns.kube-system
  • 建议设置个别名
$ alias calicoctl="kubectl exec -i -n kube-system calicoctl /calicoctl -- "

[warning]为了能使用calicoctl别名,重定向文件到输入

calicoctl create -f - < my_manifest.yaml

你可能感兴趣的:(一图看懂Calico架构原理)