overlay实现容器跨主机通信
本节内容:
- Docker容器跨主机通信方案
- 环境信息
- 升级内核
- 安装docker
- 防火墙设置和开启内核转发
- 安装启动consul
- 启动Docker
- 创建overlay network
- 创建容器
- 测试容器跨主机通信
- 网络拓扑
- 抓包分析
一、Docker容器跨主机通信方案
实现跨主机的容器通信有很多种方案,需要看实际的网络状况,是云上环境,私有云环境,还是混合云环境;是否有SDN对网络做特殊控制等等。网络状况不一样,适用的方案也会不一样。比如有的环境可以使用路由的方案,有的却不能使用。不考虑网络模型的话,基本是两个派别:overlay和路由方案。
Docker 1.12中把swarmkit集成到了docker中,本篇博客使用的版本是docker 1.11版本,这是我以前做的一个方案,采用的是overlay方案,现整理出来。
二、环境信息
主机名 | 操作系统版本 | IP地址 | Docker版本 |
node1 | CentOS 7.0 | 172.16.7.151 | 1.11.0 |
node2 | CentOS 7.0 | 172.16.7.152 | 1.11.0 |
三、升级内核
默认内核:
[root@node1 ~]# uname -r
3.10.-.el7.x86_64
1.升级内核需要使用 elrepo 的yum 源
首先我们导入 elrepo 的key
[root@node1 ~]# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
2.安装 elrepo 源
[root@node1 ~]# rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
3.在yum的ELRepo源中,mainline 为最新版本的内核
安装 ml 的内核
[root@node1 ~]# yum --enablerepo=elrepo-kernel install kernel-ml-devel kernel-ml -y
4.修改内核启动顺序,默认启动的顺序应该为1,升级以后内核是往前面插入,为0
由于CentOS 7使用grub2作为引导程序 ,所以和CentOS 6有所不同,并不是修改/etc/grub.conf来修改启动项,需要如下操作:
[root@node1 ~]# cat /boot/grub2/grub.cfg |grep menuentry #查看有哪些内核选项
[root@node1 ~]# grub2-editenv list
[root@node1 ~]# grub2-set-default
5.重启系统
[root@node1 ~]# shutdown -r now
6.查看内核版本
[root@node1 ~]# uname -r
4.5.-.el7.elrepo.x86_64
四、安装docker
[root@node1 ~]# vim /etc/yum.repos.d/docker.repo
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=
gpgcheck=
gpgkey=https://yum.dockerproject.org/gpg [root@node1 ~]# yum install -y docker-engine
如果后面升级:
[root@node1 ~]# yum update docker-engine
卸载:
[root@node1 ~]# yum remove docker-engine
五、防火墙设置和开启内核转发
停止firewalld,安装iptables-services
[root@node1 ~]# systemctl stop firewalld.service
[root@node1 ~]# systemctl disable firewalld.service
[root@node1 ~]# yum install -y iptables-services
修改防火墙策略:
[root@node1 ~]# vim /etc/sysconfig/iptables
[root@node1 ~]# systemctl start iptables.service
[root@node1 ~]# systemctl enable iptables.service
开启内核转发,在/etc/sysctl.conf中添加一行配置:
[root@node1 ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward=
运行下面的命令使内核修改生效:
[root@node1 ~]# sysctl -p
六、安装启动consul
overlay一般需要一个全局的KV存储(sdn controller、etcd、consul)来存储各个主机节点在overlay网络中的配置信息。
# wget https://releases.hashicorp.com/consul/0.6.4/consul_0.6.4_linux_amd64.zip
# unzip -oq consul_0..4_linux_amd64.zip
# mv consul /usr/local/bin/
启动consul:
host-1 Start Consul as a server in bootstrap mode:
[root@node1 ~]# nohup consul agent -server -bootstrap -data-dir /tmp/consul -bind=172.16.7.151 &
host-2 Start the Consul agent:
[root@node2 ~]# nohup consul agent -data-dir /tmp/consul -bind=172.16.7.152 &
[root@node2 ~]# consul join 172.16.7.151
Successfully joined cluster by contacting nodes.
七、启动Docker
1. 修改docker daemon配置
# cp /usr/lib/systemd/system/docker.service /etc/systemd/system/
# vim /etc/systemd/system/docker.service
在ExecStart那行加上如下的选项,其中ens32是网卡名字:
--cluster-store=consul://localhost:8500 --cluster-advertise=ens32:2376
其中--cluster-store是指向key-value存储的地址,我这里就是consul的地址,consul里保存着整个overlay网络配置和节点信息。--cluster-advertise中是Host1和Host2互通的端口。
2. 启动Docker
执行systemctl daemon-reload使配置生效,然后执行systemctl start docker.service启动docker服务。
# systemctl daemon-reload
# systemctl start docker.service
加入开机自启动:
# systemctl enable docker.service
八、创建overlay network
1. vxlan简介
overlay network这种方式一般也是只需要三层可达,容器就能互通。overlay模式容器有独立IP,不同overlay方案之间的性能差别也是很大的。我这里采用的的vxlan技术。
vxlan(virtual Extensible LAN)虚拟可扩展局域网,是一种overlay的网络技术,使用MAC in UDP的方法进 行封装,共50字节的封装报文头。
用于对VXLAN报文进行封装/解封装,包括ARP请求报文和正常的VXLAN数据报文,在一段封装报文 后通过隧道向另一端VTEP发送封装报文,另一端VTEP接收到封装的报文解封装后根据封装的MAC地址进行转发。VTEP可由支持VXLAN的硬件设备或软件来实现。
从封装的结构上来看,VXLAN提供了将二层网络overlay在三层网络上的能力。
2. 创建overlay network
默认情况下,docker启动后初始化3种网络,这3种都是不能删除的。
# docker network ls
NETWORK ID NAME DRIVER
5944745e7d6d bridge bridge
ce5d1ba0be32 host host
244bb9a34016 none null
在node1主机上创建overlay network:
[root@node1 ~]# docker network create -d overlay --subnet=10.10.10.0/ net1
ca0c50dd3a49e028c3323024b9d6e8f837f4b76889b8d5848046ec0a5948ee2d
[root@node1 ~]# docker network ls
NETWORK ID NAME DRIVER
5944745e7d6d bridge bridge
ce5d1ba0be32 host host
ca0c50dd3a49 net1 overlay
244bb9a34016 none null
在其他主机上执行docker network ls,也会看到新建的这个名字叫net1的overlay网络。
九、创建容器
node1主机创建容器:
[root@node1 ~]# docker run -it --net=net1 --name=contain1 --hostname=test1 --ip=10.10.10.3 --add-host test2:10.10.10.4 centos:centos7
[root@test1 /]# yum install -y iproute net-tools
node2上创建容器:
[root@node2 ~]# docker run -it --net=net1 --name=contain2 --hostname=test2 --ip=10.10.10.4 --add-host test1:10.10.10.3 centos:centos7
[root@test2 /]# yum install -y iproute net-tools
十、测试容器跨主机通信
十一、网络拓扑
容器内部有两个网络接口eth0、eth1。实际上,eth1连接到docker_gwbridge,这可以从ip就能看出。eth0即为overlay network的接口。
十二、抓包分析
在node2主机上使用tcpdump抓包,然后在windows上用wireshark分析。
1. container1容器里ping container2的ip地址:
2. node2主机上抓包
[root@node2 ~]# tcpdump -i ens32 -s -X -nnn -vvv -w /tmp/package.pcap
3. 把package.pcap传下来放到wireshark上分析
以在container1中ping container2,分析数据包流向:
①container1(10.10.10.3)中ping container2(10.10.10.4),根据container1的路由表,数据包可通过直连网络到达container2。于是arp请求获取container2的MAC地址(在xvlan上的arp这里不详述),得到mac地址后,封包,从eth0发出;
②eth0桥接在net ns 1-ca0c50dd3a中的br0上,这个br0是个网桥(交换机)虚拟设备,需要将来自eth0的包转发出去,于是包转给了vxlan设备;这个可以通过arp -a看到一些端倪:
[root@node1 ~]# ip netns exec -ca0c50dd3a arp -a
③vxlan是个特殊设备,收到包后,由vxlan设备创建时注册的设备处理程序对包进行处理,即进行VXLAN封包(这期间会查询consul中存储的net1信息),将ICMP包整体作为UDP包的payload封装起来,并将UDP包通过宿主机的eth0发送出去。
④152宿主机收到UDP包后,发现是VXLAN包,根据VXLAN包中的相关信息(比如Vxlan Network Identifier,VNI=256)找到vxlan设备,并转给该vxlan设备处理。vxlan设备的处理程序进行解包,并将UDP中的payload取出,整体通过br0转给veth口,net1c2从eth0收到ICMP数据包,回复icmp reply。
从这个通信过程中来看,跨主机通信过程中的步骤如下:
- 容器的网络命名空间与overlay网络的网络命名空间通过一对veth pair连接起来,当容器对外通信时,veth pair起到网线的作用,将流量发送到overlay网络的网络命名空间中。
- 容器的veth pair对端eth2与vxlan设备通过br0这个Linux bridge桥接在一起,br0在同一宿主机上起到虚拟机交换机的作用,如果目标地址在同一宿主机上,则直接通信,如果不再则通过设置在vxlan1这个vxlan设备进行跨主机通信。
- vxlan1设备上会在创建时,由docker daemon为其分配vxlan隧道ID,起到网络隔离的作用。
- docker主机集群通过key/value存储共享数据,在7946端口上,相互之间通过gossip协议学习各个宿主机上运行了哪些容器。守护进程根据这些数据来在vxlan1设备上生成静态MAC转发表。
- 根据静态MAC转发表的设置,通过UDP端口4789,将流量转发到对端宿主机的网卡上。 根据流量包中的vxlan隧道ID,将流量转发到对端宿主机的overlay网络的网络命名空间中。
- 对端宿主机的overlay网络的网络命名空间中br0网桥,起到虚拟交换机的作用,将流量根据MAC地址转发到对应容器内部。
overlay实现容器跨主机通信的更多相关文章
- 第 8 章 容器网络 - 052 - overlay 如何实现跨主机通信?
overlay 如何实现跨主机通信? 在 host2 中运行容器 bbox2: docker run -itd --name bbox2 --network ov_net1 busybox bbox2 ...
- Docker 网络管理及容器跨主机通信
1.网络模式 docker支持四种网络模式,使用--net选项指定: host,--net=host,如果指定此模式,容器将不会获得一个独立的network namespace,而是和宿主机共用一个. ...
- overlay 如何实现跨主机通信?- 每天5分钟玩转 Docker 容器技术(52)
上一节我们在 host1 中运行了容器 bbox1,今天将详细讨论 overlay 网络跨主机通信的原理. 在 host2 中运行容器 bbox2: bbox2 IP 为 10.0.0.3,可以直接 ...
- Docker容器跨主机通信
默认情况下Docker容器需要跨主机通信两个主机节点都需要在同一个网段下,这时只要两个Docker容器的宿主机能相互通信并且该容器使用net网络模式,改实现方式为网桥模式通信: 除此之外我们还可以通过 ...
- 052、overlay如何实现跨主机通信?(2019-03-19 周二)
参考https://www.cnblogs.com/CloudMan6/p/7305989.html 今天开始学习 overlay 网络跨主机通信的原理 root@host01:~# ufw ...
- Docker-Docker容器跨主机通信
Docker默认的网络环境下,单台主机上的Docker容器可以通过docker0网桥直接通信,而不同主机上的Docker容器之间只能通过在主机上做端口映射进行通信.这种端口映射方式对很多集群应用来说极 ...
- Docker:macvlan实现容器跨主机通信 [十四]
一.什么是macvlan 1.macvlan 本身是 linux kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址, 2.即多个 interface,每个 interface ...
- Docker容器跨主机通信之:直接路由方式
一.Docker网络基本原理 直观上看,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)与外界相通,并可以收发数据包:此外,如果不同子网之间要进行通信,需要额外的路由机制. Docker ...
- Docker容器跨主机通信--overlay网络
一.Docker主机间容器通信的解决方案 Docker网络驱动 Overlay: 基于VXLAN封装实现Docker原生Overlay网络 Macvlan: Docker主机网卡接口逻辑上分为多个子接 ...
随机推荐
- Cloudstack 虚拟机实例(四)
虚拟机实例 默认的模板并没有被下载 修改全局设置 secstorage.allowed.internal.sites 设置 ,二级存储ISO镜像和模板可以下载,IP网段 重启服务/etc/init. ...
- P2243 电路维修
P2243 电路维修 题目背景 Elf 是来自Gliese 星球的少女,由于偶然的原因漂流到了地球上.在她无依无靠的时候,善良的运输队员Mark 和James 收留了她.Elf 很感谢Mark和Jam ...
- Java基础-IO流对象之随机访问文件(RandomAccessFile)
Java基础-IO流对象之随机访问文件(RandomAccessFile) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.RandomAccessFile简介 此类的实例支持对 ...
- C# 在程序中控制IIS服务或应用程序池关闭重启
//停止IIS服务 ServiceController sc = new ServiceController("iisadmin"); if(sc.Status=ServiceCo ...
- SFTP上传下载文件、文件夹常用操作
SFTP上传下载文件.文件夹常用操作 1.查看上传下载目录lpwd 2.改变上传和下载的目录(例如D盘):lcd d:/ 3.查看当前路径pwd 4.下载文件(例如我要将服务器上tomcat的日志文 ...
- UITableViewCell的separatorInset属性
separatorInset这个属性是IOS7后才有的属性,所以需要判断一下,才能修改 if (IOS7_OR_LATER) { cell.separatorInset = UIEdgeInsetsZ ...
- redis sentinel集群
ip分布情况: sentinel-1/redis 主 10.11.11.5 sentinel-2/redis 从 10.11.11.7 sentinel-3/redis 从 10.11.11.8 ha ...
- Linux装机利器Cobbler安装配置
Linux装机利器Cobbler安装配置 2011-05-27 15:31:05 分类: LINUX 一.安装环境 centos 5.4 关掉iptables 关掉 selinux selinux ...
- 关于mysql 5.7版本“报[Err] 1093 - You can't specify target table 'XXX' for update in FROM clause”错误的bug
不同于oracle和sqlserver,mysql并不支持在更新某个表的数据时又查询了它,而查询的数据又做了更新的条件,因此我们需要使用如下的语句绕过: , notice_code ) a) ; 本地 ...
- Elasticsearch技术解析与实战(四)shard&replica机制
序言 shard&replica机制 1.index包含多个shard 2.每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整的建立索引和处理请求的能力 3.增减节点时, ...