一、实验环境

机器 操作系统 安装服务
172.16.4.36 centos7

docker

etcd

flannel

172.16.4.37 centos7

docker

etcd

flanne

(以上环境中:docker已安装好)

二、Flannel网络原理

Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。
但在默认的Docker配置中,每个节点上的Docker服务会分别负责所在节点容器的IP分配。这样导致的一个问题是,不同节点上容器可能获得相同的内外IP地址。并使
这些容器之间能够之间通过IP地址相互找到,也就是相互ping通。 Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得"同属一个内网"且"不重复的"IP地址,并让属于不同节
点上的容器能够直接通过内网IP通信。 Flannel实质上是一种"覆盖网络(overlay network)",即表示运行在一个网上的网(应用层网络),并不依靠ip地址来传递消息,而是采用一种映射机制,把ip地址和
identifiers做映射来资源定位。也就是将TCP数据包装在另一种网络包里面进行路由转发和通信,目前已经支持UDP、VxLAN、AWS VPC和GCE路由等数据转发方式。 原理是每个主机配置一个ip段和子网个数。例如,可以配置一个覆盖网络使用 10.100.0.0/16段,每个主机/24个子网。比如主机a可以接受10.100.5./,主机B可以
接受10.100.18./24的包。flannel使用etcd来维护分配的子网到实际的ip地址之间的映射。对于数据路径,flannel 使用udp来封装ip数据报,转发到远程主机。选择
UDP作为转发协议是因为他能穿透防火墙。例如,AWS Classic无法转发IPoIP or GRE 网络包,是因为它的安全组仅仅支持TCP/UDP/ICMP。 flannel 使用etcd存储配置数据和子网分配信息。flannel 启动之后,后台进程首先检索配置和正在使用的子网列表,然后选择一个可用的子网,然后尝试去注册它。
etcd也存储这个每个主机对应的ip。flannel 使用etcd的watch机制监视/coreos.com/network/subnets下面所有元素的变化信息,并且根据它来维护一个路由表。为了
提高性能,flannel优化了Universal TAP/TUN设备,对TUN和UDP之间的ip分片做了代理。

默认的节点间数据通信方式是UDP转发.在Flannel的GitHub页面有如下的一张原理图:

  • 数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。
  • Flannel通过Etcd服务维护了一张节点间的路由表,详细记录了各节点子网网段 。
  • 源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一下的有docker0路由到达目标容器。
三、Flannel网络部署实验

1、安装etcd

1)下载并解压(在172.16.4.36和172.16.4.37上都执行以下命令)

wget https://github.com/etcd-io/etcd/releases/download/v3.3.10/etcd-v3.3.10-linux-amd64.tar.gz
tar -xf etcd-v3.3.10-linux-amd64.tar.gz
cd etcd-v3.3.10-linux-amd64
mv etcd* /usr/bin/

2)在172.16.4.36上新建:/usr/lib/systemd/system/etcd.service

[Unit]
Description=etcd
After=network.target [Service]
Environment=ETCD_NAME=etcd-1
Environment=ETCD_DATA_DIR=/var/lib/etcd
Environment=ETCD_LISTEN_CLIENT_URLS=http://172.16.4.36:2379,http://127.0.0.1:2379
Environment=ETCD_LISTEN_PEER_URLS=http://172.16.4.36:2380
Environment=ETCD_ADVERTISE_CLIENT_URLS=http://172.16.4.36:2379,http://127.0.0.1:2379
Environment=ETCD_INITIAL_ADVERTISE_PEER_URLS=http://172.16.4.36:2380
Environment=ETCD_INITIAL_CLUSTER_STATE=new
Environment=ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster-token
Environment=ETCD_INITIAL_CLUSTER=etcd-1=http://172.16.4.36:2380,etcd-2=http://172.16.4.37:2380
ExecStart=/usr/bin/etcd
[Install]
WantedBy=multi-user.target

3)在172.16.4.37上新建:/usr/lib/systemd/system/etcd.service

[Unit]
Description=etcd
After=network.target [Service]
Environment=ETCD_NAME=etcd-2
Environment=ETCD_DATA_DIR=/var/lib/etcd
Environment=ETCD_LISTEN_CLIENT_URLS=http://172.16.4.37:2379,http://127.0.0.1:2379
Environment=ETCD_LISTEN_PEER_URLS=http://172.16.4.37:2380
Environment=ETCD_ADVERTISE_CLIENT_URLS=http://172.16.4.37:2379,http://127.0.0.1:2379
Environment=ETCD_INITIAL_ADVERTISE_PEER_URLS=http://172.16.4.37:2380
Environment=ETCD_INITIAL_CLUSTER_STATE=new
Environment=ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster-token
Environment=ETCD_INITIAL_CLUSTER=etcd-1=http://172.16.4.36:2380,etcd-2=http://172.16.4.37:2380
ExecStart=/usr/bin/etcd
[Install]
WantedBy=multi-user.target
  • name:节点名称 data-dir 指定节点的数据存储目录
  • listen-peer-urls: 监听URL,用于与其他节点通讯
  • listen-client-urls: 对外提供服务的地址:比如 http://ip:2379,http://127.0.0.1:2379 ,客户端会连接到这里和 etcd 交互
  • initial-advertise-peer-urls: 该节点同伴监听地址,这个值会告诉集群中其他节点
  • initial-cluster 集群中所有节点的信息,格式为 node1=http://ip1:2380,node2=http://ip2:2380,… 。注意:这里的 node1 是节点的 --name 指定的名字;后面的 ip1:2380 是 --initial-advertise-peer-urls 指定的值
  • initial-cluster-state: 新建集群的时候,这个值为 new ;假如已经存在的集群,这个值为 existing
  • initial-cluster-token :创建集群的 token,这个值每个集群保持唯一。这样的话,如果你要重新创建集群,即使配置和之前一样,也会再次生成新的集群和节点 uuid;否则会导致多个集群之间的冲突,造成未知的错误
  • advertise-client-urls:对外公告的该节点客户端监听地址,这个值会告诉集群中其他节点

4)在172.16.4.36和172.16,4.37上新建:执行以下命令启动服务

systemctl enable etcd
systemctl start etcd

测试etcd集群是否正常:

先在172.16.4.36上执行

etcdctl mkdir /boshen

先在172.16.4.37上执行

[root@ ~]# etcdctl ls
/boshen

从上面可以看出,36上创建的数据37上也能看到,表示etcd集群正常工作了

2、安装flannel

1)下载并解压(在172.16.4.36和172.16.4.37上都执行以下命令)

wget https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz
tar -xf flannel-v0.10.0-linux-amd64.tar.gz
cp flanneld /usr/bin/

2)定义flannel网络ip池(只在一个节点上执行就行,比如在172.16.4.36上执行)

flannel-config.json 中,内容为:

{
"Network": "10.3.0.0/16",
"SubnetLen": ,
"Backend": {
"Type": "vxlan"
}
}
  1. Network 定义该网络的 IP 池为 10.3.0.0/16
  2. SubnetLen 指定每个主机分配到的 subnet 大小为 24 位,即10.3.X.0/24
  3. Backend 为 vxlan,即主机间通过 vxlan 通信。

然后执行以下命令:

etcdctl set /docker-flannel/network/config < flannel-config.json

3)新建启动文件: /usr/lib/systemd/system/flanneld.service(172.16.4.36和172.16.4.37)

[Unit]
Description=flannel
After=etcd.service network.target [Service]
ExecStart=/usr/bin/flanneld --etcd-endpoints=http://172.16.4.36:2379,http://172.16.4.37:2379 -etcd-prefix=/docker-flannel/network --iface=eth0
[Install]
WantedBy=multi-user.target
  • --etcd-endpoints 指定 etcd url。
  • --iface 指定主机间数据传输使用的 interface。
  • --etcd-prefix 指定 etcd 存放 flannel 网络配置信息的 key。只能指到目录级别,比如上面的key为:/docker-flannel/network/config ,只能指到/docker-flannel/network

4)启动flanneld(172.16.4.36和172.16.4.37)

systemctl enable flanneld
systemctl start flanneld

查看状态

systemctl status flanneld

172.16.4.36上自动分配的子网为:10.3.39.0/24

172.16.4.36上新建了一个interface:  flannel.1

172.16.4.36上添加了一条路由:目的地址为 flannel 网络 10.3.59.0/24 的数据包都由 flannel.1 转发

172.16.4.37上自动分配的子网为:10.3.59.0/24

172.16.4.37上也新建了一个interface:  flannel.1

172.16.4.36上添加了一条路由:目的地址为 flannel 网络 10.3.39.0/24 的数据包都由 flannel.1 转发

3、Docker中使用flannel

上面只是安装了flannel网络,还需要指定docker中默认的网络为flannel,要不然容器仍然使用默认网络(bridge)

1)编辑docker的配置文件:/usr/lib/systemd/system/docker.service

增加紫框部分:其中这两个参数的值必须与 /run/flannel/subnet.env 中 FLANNEL_SUBNET 和FLANNEL_MTU 一致。

2)重启docker服务

systemctl daemon-reload
systemctl restart docker

在172.16.4.36上,会将10.3.39.1配置到 Linux bridge docker0上,并添加了到10.3.39.0/24的一条路由

在172.16.4.37上,会将10.3.59.1配置到 Linux bridge docker0上,并添加了到10.3.59.0/24的一条路由

3)测试flannel网络的连通性

在172.16.4.36上运行容器box1,容器内ip为10.3.39.2

docker run -itd --name=box1 busybox
docker exec box1 ip r

在172.16.4.37上运行容器box2,容器内ip为10.3.59.2

docker run -itd --name=box2 busybox
docker exec box2 ip r

在172.16.4.36上执行

可以发现,是可以ping通10.3.59.2,说明box1和box2是连通的,下面用traceroute分析下数据包流向:

  • box1容器的数据包首先发给自己主机的docker0,因为docker0是box1容器内的默认网关
  • 在172.16.4.36上,根据下面的路由表,发送给docker0的数据包会发到10.3.39.0/24也就是会发给flannel.1,flannel.1 将数据包封装成 VxLAN,通过 宿主机的eth0 发送给172.16.4.37

  • 在172.16.4.37上,收到box1发来的数据包,发现目的地址是10.3.59.2,根据宿主机的路由表,数据包发送给 flannel.1,并通过 docker0 到达 box2

4)flannel网络的隔离性

flannel 为每个主机分配了独立的 subnet,但 flannel.1 将这些 subnet 连接起来了,相互之间可以路由。本质上,flannel 将各主机上相互独立的 docker0 容器网络组成了一个互通的大网络,实现了容器跨主机通信。flannel 没有提供隔离。

安装docker跨主机网络flannel的更多相关文章

  1. Docker跨主机网络——overlay

    前言 在Docker网络--单host网络一文中,我为大家总结了Docker的单机网络相关知识和操作,单机网络比较容易.本文我为大家总结Docker跨主机通信相关知识.同样本文大部分内容以CloudM ...

  2. Docker 跨主机网络 overlay(十六)

    目录 一.跨主机网络概述 二.准备 overlay 环境 1.环境描述 2.创建 consul 3.修改 docker 配置文件 4.准备就绪 三.创建 overlay 网络 1.在 host1 中创 ...

  3. Docker 跨主机网络

    Docker提供两种原生的跨主机网络: Overlay  和  Macvlan libnetwork & CNM libnetwork 是 docker 容器网络库,最核心的内容是其定义的 C ...

  4. Docker跨主机网络实践

    Docker使用中网络管理是最麻烦的,在项目初始化前期就需要进行合理的规划,如果在比较理想的单主机的网络通信是比较简单的,但如果涉及到跨主机的网络就需要使用docker自带的overlay netwo ...

  5. centos7下安装docker(15.4跨主机网络-flannel)

    flannel是CoreOS开发的容器网络解决方案,flannel为每一个host分配一个subnet,容器从这些subnet中分配IP,这些IP可以在host之间路由,容器无需NAT和port ma ...

  6. Docker跨主机网络解决方案

    前言:前面的部分一直都是单机跑docker,但实际生产环境不可能只用一台来跑.肯定会用到多台,因为他们都是内部私有ip,那么多台主机之间的容器如何通信?这个是个很头疼的问题!目前主流几种方法如下:1. ...

  7. docker 跨主机网络:overlay 简介

    简介 docker 在早前的时候没有考虑跨主机的容器通信,这个特性直到 docker 1.9 才出现.在此之前,如果希望位于不同主机的容器能够通信,一般有几种方法: 使用端口映射:直接把容器的服务端口 ...

  8. Docker 跨主机网络方案分析

    PS:文章首发公众号,欢迎大家关注我的公众号:aCloudDeveloper,专注技术分享,努力打造干货分享平台,二维码在文末可以扫,谢谢大家. 上篇文章介绍了容器网络的单主机网络,本文将进一步介绍多 ...

  9. Docker跨主机网络联通之etcd实现

    搭建ETCD集群 查看NODE1机器IP,并启动ETCD ubuntu@docker-node1:~$ ifconfig eth0 eth0: flags=4163<UP,BROADCAST,R ...

随机推荐

  1. 489. Robot Room Cleaner扫地机器人

    [抄题]: Given a robot cleaner in a room modeled as a grid. Each cell in the grid can be empty or block ...

  2. 解决input 有readonly属性 各个浏览器的光标兼容性问题

    <input type='text' readonly unselectable='on' onfocus='this.blur()'/> 目标:input 只能读,但是在ie.火狐浏览器 ...

  3. webstorm配置node.js

    1.确保电脑已经安装好了node.js

  4. python学习笔记Day3

    set有点:1.访问速度快 2.天生解决了重复问题 tuple与set区别: 元组可重复,set不可重复创捷集合1 >>> s1.add('alex')>>> pr ...

  5. 史上最全的MSSQL复习笔记

    1.什么是SQL语句 SQL语言,结构化的查询语言(Structured Query Language),是关系数据库管理系统的标准语言.它是一种解释语言,写一句执行一句,不需要整体编译执行. 语法特 ...

  6. 关于transform-style:preserve-3d的些许明了

    父元素要添加属性transform-style:preserve-3d;和transform:perspective(800px);还有相对定位 首先设置子元素 具有3D属性,然后再设置视角与3D元素 ...

  7. 软件开发中 SQL SERVER 任务的用法

    在软件开发中,经常性会用到定时任务.这个时候你可能会想到线程.但是事实中,线程方法比较麻烦.容易出错,资源竞争等问题,设计起来让你很头痛. 现在给大家提供一个新的思路,用SQL SERVER 的任务管 ...

  8. (转)Android学习路线总结,绝对干货

    一.前言 不知不觉自己已经做了几年开发了,由记得刚出来工作的时候感觉自己能牛逼,现在回想起来感觉好无知.懂的越多的时候你才会发现懂的越少. 如果你的知识是一个圆,当你的圆越大时,圆外面的世界也就越大. ...

  9. hdu 1254(两个BFS) 推箱子

    http://acm.hdu.edu.cn/showproblem.php?pid=1254 首先,要判断人是不是可以从4到达箱子的位置2,而且不止判断一次,因为推动箱子一步后,人的位置也会改变,所以 ...

  10. Android.DebugTools.Traceview & dmtracedump

    1. Android 调试工具之Traceview http://www.cnblogs.com/devinzhang/archive/2011/12/18/2291592.html TraceVie ...