centos7下安装docker(15.7容器跨主机网络---calico)

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通的

 

posted @ 2017-11-18 17:32 无踪无影 阅读(...) 评论(...) 编辑 收藏