Calico是一个纯三层的虚拟网络方案,Calico为每个容器分配一个IP,每个host都是router,把不同host的容器连接起来。与vxlan不同的是:calico不对数据包进行封装,不需要NAT和端口映射,扩展性和性能都很好
与其他容器网络相比,calico还有一个优势:network policy。用户可以动态定义ACL规则,控制进出容器的数据包,实现业务需求
calico依赖etcd在不同主机间共享和交换信息,存储calico网络状态。calico网络中每个主机都要运行calico组件,提供容器interface管理,动态路由,动态ACL,报告状态等功能
部署calico
1.安装etcd
安装好后执行: etcd -listen-client-urls http://192.168.7.222:2379 -advertise-client-urls http://192.168.7.222:2379
2.修改docker1和docker2中的docker的配置文件:/etc/systecd/system/docker.service.d/10-machine.conf
重启docker服务
3。在docker1和docker2上部署calico
wget -O /usr/local/bin/calicoctl https://github.com/projectcalico/calicoctl/releases/download/v1.6.1/calicoctl 下载calico安装包
修改权限
启动calico服务:calicoctl node run
注:calico服务启动的时候主要是运行一个calico容器
1.启动calico服务的时候,首先设置主机网络,例如enable IP forwarding
2.下载并启动calico-node容器,calico会以容器的形式运行(与weave类似)
注:在启动服务的时候如果报错,注意以上两点:1. ETCD_ENDPOINTS=http://127.0.0.1:2379这里应该是连接我们的etcd的服务器,是我们之前在docker配置文件中设置的/etc/systemd/system/docker.service.d/,在本实验中应该是 ETCD_ENDPOINTS=http://192.168.7.222:2379
2.由于通过calicoctl node run启动服务时,会自动下载镜像 quay.io/calico/node:latest,tag是latest默认的,所以我们可以提前下载好相关的镜像,使用 docker pull quay.io/calico/node:v2.6.2
3.由于docker node run 服务是写好了的代码进行启动的,但是我们也可以自己去手动运行容器启动,自己手动启动的时候注意以上两点即可
docker run --net=host --privileged --name=calico-node -d --restart=always -e NODENAME=docker2 -e CALICO_NETWORKING_BACKEND=bird -e CALICO_LIBNETWORK_ENABLED=true -e ETCD_ENDPOINTS=http://192.168.7.222: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.2
这是官方文档的方式,在启动服务的时候指定镜像
启动calico服务一步搞定的办法是:ETCD_ENDPOINTS=http://172.17.8.101:2379 calicoctl node run --node-image=quay.io/calico/node:v2.6.2
指定自己的etcd的endpoints,指定镜像的tag
查看calico状态:
calicoctl node status
官网安装calico服务地址(centos)https://docs.projectcalico.org/v2.6/getting-started/docker/installation/vagrant-coreos/
2.创建calico网络
docker network create --driver calico --ipam-driver calico-ipam calico-net1
--driver calico:网络使用calico驱动
--ipam-driver calico-ipam:指定使用calico的IPAM驱动管理IP
calico是global网络,etcd会将calico-net1同步到所有主机
calico网络结构:
在docker2上运行容器:
docker run -itd --name calico1 --network=calico-net1 busybox
查看calico1的网络配置
calico0shi calico interface 分配的IP为192.168.100.64/32.calico0对应docker2上6的编号的interface
docker2将作为router负责转发目的的地址为calico1的数据包,所有发送到calico1的数据都会给 calie9fa9faf0fa,因为 calie9fa9faf0fa与cali0是一对veth pair,calico1能收到数据
docker2的网络结构如上盗图:
下面我们来看一下docker1上的网络结构
由于calico是global网络,所以我们不需要启动calico服务,也可以看到我们建立的calico网络:calico-net1
启动calico服务后,在docker1中运行容器:
使用与docker2上相同的网段calico-net1后获得的IP为192.168.72.129/32
在docker1上新建容器后可以看到docker1上新添加了2条路由:
1.目的地址为dockwe2上得容器,网关是:192.168.7.226
2.目的地址为 calico-node容器的路由
下面我们来看一下docker1与docker2的网络是否能够ping通
注:如果启动calico node run 服务时没有任何输出的结果,或者使用caloci网络运行的容器无法和其他host上的容器ping通,可能是由于host上的calicoctl的安装包没有下载好,建议重新下载或者是在其他host上重新拷贝一份
现在docker1与docker2上的容器之间的通信如上图:盗图
1.根据docker2上的calico1的容器的路由表,将数据包从cali0发出
2.数据经过veth pair到达docker2,查看路由表,数据根据ens160发给daoker1(192.168.7.235)上
3.docker2收到数据后,根据路由表发送给 cali5224fe3869b,通过veth pair cali0发送到calicao2中
接下来我们看不同calico网络之间的连通性
1.创建calico-net2
2.运行容器calico3使用calico-net2网络:docker run -itd --name calico3 --network calico-net2 busybox
3.
calico为calico3容器分配了192.168。72.130/32网络,验证相同的host上的容器之间是否能ping通
虽然calico2和calico3在同一个host上,但是由于他们使用的是不同的calico网络,也是不能通的
calico默认的policy规则是:容器只能与同一个calico网络中的容器通信
calico的每个网络都有一个同名的profile,profile中定义了该网络的policy,我们具体看一下calico-net1的profile:
首先我们要编辑一个文件:/etc/calico/calicoctl.cfg
1.创建目录mkdir /etc/calico
2.vim /etc/calico/calicoctl.cfg
apiVersion: v1
kind: calicoApiConfig
metadata:
spec:
datastoreType: "etcdv2"
etcdEndpoints: "http://etcd1:2379,http://etcd2:2379"
具体参考;https://docs.projectcalico.org/v2.6/reference/calicoctl/setup/etcdv2,
如果不编辑/etc/calico/calicoctl.cfg这个文件的话,会报一下错误:Failed to get resources: client: etcd cluster is unavailable or misconfigured; error #0: dial tcp 127.0.0.1:2379: getsockopt: connection refused
3.查看我们的calico-net1的profile
calico get profile calico-net1 -o yaml
1.命名为calico-net1
2.为profile添加一个tag calico-net1,这个tag默认和网络名一致,但是是可以任意设置,这个tag和上面的name没有一点关系,这个tag后面会用到
3.egress:对容器个发出的数据包进行限制,当前没有任何限制
4.ingress:对进入容器的数据包进行限制,当前是接收来自tag calico-net1的容器,其实就是接收本网段的数据包
calicoctl:管理资源,资源通过yaml和json格式来定义,通过calicoctl create或者apply方式来创建或应用,通过calicoctl get来查看
calicoctl支持的资源类型有:bgpPeer, hostEndpoint, policy, ipPool, profile, workloadEndpoint等
制定policy
calico能够让用户定义灵活的policy规则,精细化控制容器的流量
试验:创建一个新的calico网络calico-web并部署一个httpd容器
定义calico-web中的容器允许被calico-net2中的容器访问
web2容器的IP是192.168.72.131
现在还无法访问192.168.72.131的80端口
创建policy文件web.yml
创建好后,使用命令:calicoctl create -f web.yuml使用这个资源
创建calico的IP池
首先查看IP pool:calicoctl get ippool
创建ippoll首先创建一个资源文件
vim pool.yaml
运行命令进行创建:calicoctl create -f ippool.yaml
我们在进行查看:calicoctl get ippool
有我们自定义的10.20.0.0/24的网段
验证连通性:
创建一个subnet为10.20.0.0/24的网络,通过--subnet=10.20.0.0/24来指定subnet
运行容器个,查看他的IP
使用calico-sub运行的容器的IP是10.20.0.129,验证同一host上的容器是否能通
另一个容器的IP是192.168.72.139
不能ping通
不同host上的相同subnet的容器是可以ping通的