1、Calico介绍
Calico不会有任何网桥!!!
它会为每一个容器创建一个Veth pair 设备,一端在容器内,一端设置到宿主机上
数据的转发,靠 Calico 维护的路由规则
它是基于三层的二层通信
三层指的是实际物理网络架构
二层通信指的是,需要维护「MAC 地址级别的信息」,即「虚拟IP」与「MAC 地址」的映射关系
Calico是一个纯三层的协议,为OpenStack虚机和Docker容器提供多主机间通信。
Calico不使用重叠网络比如flannel和libnetwork重叠网络驱动,它是一个纯三层的方法,使用虚拟路由代替虚拟交换,每一台虚拟路由通过BGP协议传播可达信息(路由)到剩余数据中心。
2、Calico 结构组成
Calico不使用重叠网络比如flannel和libnetwork重叠网络驱动,它是一个纯三层的方法,
使用虚拟路由代替虚拟交换,每一台虚拟路由通过BGP协议传播可达信息(路由)到剩余数据中心;
Calico在每一个计算节点利用Linux Kernel实现了一个高效的vRouter来负责数据转发,
而每个vRouter通过BGP协议负责把自己上运行的workload的路由信息像整个Calico网络内传播
小规模部署可以直接互联,大规模下可通过指定的BGP route reflector来完成。
Felix:calico agent,跑在每台需要运行workload的节点上,主要负责配置路由及
ACLs等信息来确保 endpoint 的连通状态;
etcd:分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性;
BGP Client(BIRD):主要负责把Felix 写入 kernel 的路由信息分发到当前Calico网络,
确保workload 间的通信的有效性;
BGP Route Reflector(BIRD):大规模部署时使用,摒弃所有节点互联的mesh模式,
通过一个或者多个BGP Route Reflector来完成集中式的路由分发;
通过将整个互联网的可扩展 IP 网络原则压缩到数据中心级别,Calico 在每一个计算节点利用
Linux kernel实现了一个高效的vRouter来负责数据转发而每个vRouter通过BGP协议负责把
自己上运行的workload的路由信息像整个Calico网络内传播一小规模部署可以直接互联,大规模
下可通过指定的BGP route reflector来完成.
这样保证最终所有的 workload 之间的数据流量都是通过 IP 包的方式完成互联的。
3、Calico网络方式(两种)
1)IPIP
从字面来理解,就是把一个IP数据包又套在一个IP包里,即把IP层封装到IP层的一个tunnel,
看起来似乎是浪费,实则不然。它的作用其实基本上就相当于一个基于IP层的网桥!一般来说,
普通的网桥是基于mac层的,根本不需IP,而这个ipip则是通过两端的路由做一个tunnel,
把两个本来不通的网络通过点对点连接起来。ipip的源代码在内核 net/ipv4/ipip.c中可以找到。
2)BGP
边界网关协议(Border Gateway Protocol,BGP)是互联网上一个核心的去中心化自治路由协议。
它通过维护IP路由表或"前缀,表来实现自治系统(AS)之间的可达性,属于矢量路由协议。
BGP不使用传统的内部网关协议(IGP)的指标,而使用基于路径、网络策略或规则集来决定路由。
因此,它更适合被称为矢量性协议,而不是路由协议。
BGP,通俗的讲就是讲接入到机房的多条线路(如电信、联通、移动等)融合为一体,
实现多线单IP,BGP机房的优点:服务器只需要设置一个IP地址,最佳访问路由是由网络上的骨干
路由器根据路由跳数与其它技术指标来确定的,不会占用服务器的任何系统。
备注:什么是vxlan
什么是VXLAN?
VXLAN,即Virtual Extensible LAN(虚拟可扩展局域网),是Linux本身支持的一网种网络虚拟化技术。VXLAN可以完全在内核态实现封装和解封装工作,从而通过“隧道”机制,构建出覆盖网络(Overlay Network)
VXLAN的设计思想是:
在现有的三层网络之上,“覆盖”一层虚拟的、由内核VXLAN模块负责维护的二层网络,使得连接在这个VXLAN二层网络上的“主机”(虚拟机或容器都可以),可以像在同一个局域网(LAN)里那样自由通信。
为了能够在二nfcu网络上打通“隧道”,VXLAN会在宿主机上设置一个特殊的网络设备作为“隧道”的两端,叫VTEP:VXLAN Tunnel End Point(虚拟隧道端点)
简而言之:
- 不需要关注 VTEP 与 VTEP 设备之间的通信(如何跨网段,如何进行三层网络的连通)
- 只需关注,将数据包传给当前 VTEP 设备后,如何获取目的 VTEP 的 MAC 地址,完成二层通信
4、Calico实验部署
Calico的原理理解起来,不是那么容易,
我们可以先进行搭建,再进行理解,下图是calico的跨主机通信
本次实验使用3台主机进行部署测试,菜单信息如下
系统 centos7.6
主机
51 lyc-80-25 安装dockder+etcd(集成) + Calicoctl
52 lyc-80-26 安装dockder+etcd(集成) + Calicoctl
53 lyc-80-27 安装dockder+etcd(集成) + Calicoctl
开启中继路由、转发
vim /etc/sysctl.conf
net.ipv4.conf.all.rp_filter=1
net.ipv4.ip_forward=1
先配置1台机器 后进行scp分发
防火墙设置
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
iptables -L -n
分发刚配置的文件到26、27机器
scp /etc/sysctl.conf root@192.168.80.26:/etc/
scp /etc/sysctl.conf root@192.168.80.27:/etc/
部署etcd集群
yum -y install etcd
# 备份etcd.conf + 置空etcd.conf
机器80.25-------------------------------------------
cp /etc/etcd/etcd.conf /etc/etcd/etcd.conf.bak
> /etc/etcd/etcd.conf
cat > /etc/etcd/etcd.conf << EOF
#[Member]
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_NAME="lyc-80-25"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.80.25:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.80.25:2379"
ETCD_INITIAL_CLUSTER="lyc-80-25=http://192.168.80.25:2380,lyc-80-26=http://192.168.80.26:2380,lyc-80-27=http://192.168.80.27:2380"
EOF
分发文件
需要提前对 /etc/hosts进行网络映射 然后rsa免密设置
scp /etc/etcd/etcd.conf root@192.168.80.26:/etc/etcd/etcd.conf
scp /etc/etcd/etcd.conf root@192.168.80.27:/etc/etcd/etcd.conf
修改80.26/80.27这2台分发的配置文件为各自的主机IP及主机名
vim /etc/etcd/etcd.conf
这三台机器就组成了etcd集群 ,注意hosts文件要添加上cat /etc/hosts,为后期映射准备
启动etcd
在三个节点同时启动
systemctl start etcd
systemctl enable etcd
systemctl status etcd
查看集群各节点信息
etcdctl member list
ps -ef | grep etcd
netstat -nultp | grep 2379
# 查看健康
etcdctl cluster-health
集成docker 和 etcd
在三台机器的docker.service中添加 --cluster-store=etcd://机器ip:2379
vim /usr/lib/systemd/system/docker.service
# 如下图所示,我的是
--cluster-store=etcd://192.168.80.25:2379
--cluster-store=etcd://192.168.80.26:2379
--cluster-store=etcd://192.168.80.27:2379
重启docker服务
systemctl daemon-reload
systemctl restart docker.service
systemctl status docker.service
如果出现上图报错,把原来【vim /usr/lib/systemd/system/docker.service】中除了我们添加的部分删除,即可重启成功
再次重启docker服务
systemctl daemon-reload
systemctl restart docker.service
systemctl status docker.service
ps -ef | grep docker
下载calicoctl
首先在三个节点机上下载calico的命令管理工具calicoctl
https://github.com/projectcalico/calicoctl/releases?page=17
推荐1.6.1版本
calicoctl上传主机后将mv到/usr/bin/目录
chmod +x calicoctl
mv calicoctl /usr/bin/
cd /usr/bin/
scp calicoctl root@192.168.80.26:/usr/bin/
scp calicoctl root@192.168.80.27:/usr/bin/
calicoctl version
calicoctl --help
启动calico服务
在Docker环境中Calico服务是做为容器来运行的,使用host的网络配置。
所有容器配置使用Calico服务,做为calico节点互相通信。
Calico在每个主机上通过一个自己的container与其他主机或者网络通讯
所以在三个节点上都要下载calico的node镜像
docker pull quay.io/calico/node:v2.6.10
拉取镜像的时候,慢的话,可以先清理下,再重新拉取
-----------------------------------------------
清理无效的镜像缓存
docker image prune
创建calico容器
25主机
docker run --net=host --privileged --name=calico-node -d --restart=always -e NODENAME=lyc-80-25 -e CALICO_NETWORKING_BACKEND=bird -e CALICO_LIBNETWORK_ENABLED=true -e IP=192.168.80.25 -e ETCD_ENDPOINTS=http://127.0.0.1:2379 -v /var/log/calico:/var/log/calico -v /var/run/calico:/var/run/calico -v /lib/modules:/lib/modules -v /run:/run -v /run/docker/plugins:/run/docker/plugins -v /var/run/docker.sock:/var/run/docker.sock quay.io/calico/node:v2.6.10
26主机
docker run --net=host --privileged --name=calico-node -d --restart=always -e NODENAME=lyc-80-26 -e CALICO_NETWORKING_BACKEND=bird -e CALICO_LIBNETWORK_ENABLED=true -e IP=192.168.80.26 -e ETCD_ENDPOINTS=http://127.0.0.1:2379 -v /var/log/calico:/var/log/calico -v /var/run/calico:/var/run/calico -v /lib/modules:/lib/modules -v /run:/run -v /run/docker/plugins:/run/docker/plugins -v /var/run/docker.sock:/var/run/docker.sock quay.io/calico/node:v2.6.10
27主机
docker run --net=host --privileged --name=calico-node -d --restart=always -e NODENAME=lyc-80-27 -e CALICO_NETWORKING_BACKEND=bird -e CALICO_LIBNETWORK_ENABLED=true -e IP=192.168.80.27 -e ETCD_ENDPOINTS=http://127.0.0.1:2379 -v /var/log/calico:/var/log/calico -v /var/run/calico:/var/run/calico -v /lib/modules:/lib/modules -v /run:/run -v /run/docker/plugins:/run/docker/plugins -v /var/run/docker.sock:/var/run/docker.sock quay.io/calico/node:v2.6.10
查看calico状态
docker exec -it calico-node env
calicoctl node status
calicoctl get node
以上测试说明calico集群网络正常
添加calico子网
yc-80-25:
vim ipPool.yaml
------------------
apiVersion: v1
kind: ipPool
metadata:
cidr: 192.168.10.0/24
spec:
ipip:
enabled: true
nat-outgoing: true
disabled: false
------------------------------
lyc-80-26:
vim ipPool.yaml
------------------
apiVersion: v1
kind: ipPool
metadata:
cidr: 192.168.20.0/24
spec:
ipip:
enabled: true
nat-outgoing: true
disabled: false
------------------------------
lyc-80-27:
vim ipPool.yaml
------------------
apiVersion: v1
kind: ipPool
metadata:
cidr: 192.168.30.0/24
spec:
ipip:
enabled: true
nat-outgoing: true
disabled: false
------------------------------
3台机器全部创建:
calicoctl get ipPool
calicoctl create-f ipPool.yaml
calicoctl get ipPool -o wide
创建IP池子
接着在上面创建的ip pool(192.168.10.0/24、192.168.20.0/24、192.168.30.0/24)里创建子网络。
可以从三个中选择一个或两个或全部去创建子网络。
如下创建了calico-net1,calico-net2和calico-net3三个不同的网络。
创建命令可以在任意一个节点上执行即可。
由于三个节点使用的是同一套etcd,所以子网络创建后,在其他两个节点上都可以通过
docker network 1s命令查看到生成的网络信息
在创建的ipPool中创建子网络
lyc-80-25
docker network create --driver calico --ipam-driver calico-ipam --subnet 192.168.10.0/24 calico-net1
------------------
lyc-80-26
docker network create --driver calico --ipam-driver calico-ipam --subnet 192.168.20.0/24 calico-net2
-----------------
lyc-80-27
docker network create --driver calico --ipam-driver calico-ipam --subnet 192.168.30.0/24 calico-net3
查看
docker network ls
--driver calico 网络使用calico驱动
--ipam-driver calico-ipam : 指定calico 的ipam 驱动管理ip
-subnet:指定calico-net1、calico-net2、calico-net3
这三个网段是global网段,etcd会将它们三个同步到所有的机器
开启ipv6转发,在各个节点上使用上面创建的三个子网去创建容器。
echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6
echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6
80-25
docker run -itd --net calico-net1 --name docker-test1 busybox
docker run -itd --net calico-net2 --name docker-test11 busybox
docker run -itd --net calico-net3 --name docker-test111 busybox
80-26
docker run -itd --net calico-net1 --name docker-test2 busybox
docker run -itd --net calico-net2 --name docker-test22 busybox
docker run -itd --net calico-net3 --name docker-test222 busybox
80-27
docker run -itd --net calico-net1 --name docker-test3 busybox
docker run -itd --net calico-net2 --name docker-test33 busybox
docker run -itd --net calico-net3 --name docker-test333 busybox
查看容器网络IP
docker exec -it docker-test1 ip a
docker exec -it docker-test11 ip a
docker exec -it docker-test111 ip a
查看各节点IP
80-25
docker exec -it docker-test1 ifconfig |grep inet
docker exec -it docker-test11 ifconfig |grep inet
docker exec -it docker-test111 ifconfig |grep inet
80-26
docker exec -it docker-test2 ifconfig |grep inet
docker exec -it docker-test22 ifconfig |grep inet
docker exec -it docker-test222 ifconfig |grep inet
80-27
docker exec -it docker-test3 ifconfig |grep inet
docker exec -it docker-test33 ifconfig |grep inet
docker exec -it docker-test333 ifconfig |grep inet
测试网络是否ping通
docker exec -it docker-test1 ping -c 2 docker-test2.calico-net1
docker exec -it docker-test1 ping -c 2 docker-test3.calico-net1
docker exec -it docker-test11 ping -c 2 docker-test22.calico-net2
docker exec -it docker-test11 ping -c 2 docker-test33.calico-net2
docker exec -it docker-test111 ping -c 2 docker-test222.calico-net3
docker exec -it docker-test111 ping -c 2 docker-test333.calico-net3
全部正常ping同,说明网络正常通信
route -n
5、总结
1、同一网段里面容器互相Ping的通(即使不在同一个节点上,只要创建容器时使用的是同一个子网段)
2、不在同一个子网段的容器是Ping不通的
3、宿主机能Ping通他自身的所有容器ip,但不能ping通其他节点上的容器IP
4、所有节点的容器都能Ping通其他节点的宿主机ip
即-在calico默认设置下,只允许位于同一网络中的容器之间通信,这样就实现了容器的跨主机互连,
也可以更好实现网络隔离效果,位于不通网络下的容器想要通信,就要依赖calico的policy策略来实现了。