Docker实现跨主机容器实例网络通信(2)——利用OpenVSwitch构建多主机Docker网络
题记
前面我们已经针对Docker容器进行了简单介绍,相信感兴趣的朋友已经能在相关帮助下部署一个docker环境感受了容器带给我们的另一种技术进步。
当然,如果你慢慢深入容器的技术研究,你会发现,尽管容器是虚拟机的未来趋势,但是容器还有很多需要进步,特别是关于网络方面,虚拟化技术可以支持非常丰富的网络需求,但是现在容器可能在这一块还需要继续进步和完善,最大的需求就是如果我们构建容器集群,我们可能只在一个宿主机上创建多个容器,可能需要N个宿主机,每个宿主机上又包含M个容器,我们需要N*M个容器组成一个大的容器集群网络,那么如何跨宿主机进行容器的网络连接是需要我们关注的,当然,现在也有非常多的方案供我们去选择:
--------------------------------------------------------------------------------------
Blog: http://blog.csdn.net/chinagissoft
QQ群:16403743
宗旨:专注于"GIS+"前沿技术的研究与交流,将云计算技术、大数据技术、容器技术、物联网与GIS进行深度融合,探讨"GIS+"技术和行业解决方案
转载说明:文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!
--------------------------------------------------------------------------------------
1、利用容器暴露端口方式
2、LinuxBriage方式
3、例如类似weave方式实现
4、也是本博客介绍的利用OpenvSwitch来实现
关于OpenvSwitch不多介绍,我OpenStack的早期版本(K版本之前),关于网络Neutron的实现都是通过OpenvSwitch。
实验环境
使用VMWare Workstation12
Ubuntu14.04
Docker 1.9.0
1、构建OpenvSwitch安装包
默认安装的版本不符合需求,也可以在一个新环境执行如下步骤
#获取最新存档
wget http://openvswitch.org/releases/openvswitch-2.3.1.tar.gz
tar xzvf openvswitch-2.3.1.tar.gz
cd openvswitch-2.3.1#安装依赖
sudo apt-get install -y build-essential fakeroot debhelper \autoconf automake bzip2 libssl-dev \openssl graphviz python-all procps \python-qt4 python-zopeinterface \python-twisted-conch libtool# 构建(不使用并行检查)
DEB_BUILD_OPTIONS='parallel=8 nocheck' fakeroot debian/rules binary# 得到最新deb文件并复制到某处
cd ..
ls -al *deb
执行完毕之后可以看到
openvswitch-2.3.1.tar.gz
openvswitch-common_2.3.1-1_amd64.deb
openvswitch-datapath-dkms_2.3.1-1_all.deb
openvswitch-datapath-source_2.3.1-1_all.deb
openvswitch-dbg_2.3.1-1_amd64.deb
openvswitch-ipsec_2.3.1-1_amd64.deb
openvswitch-pki_2.3.1-1_all.deb
openvswitch-switch_2.3.1-1_amd64.deb
openvswitch-test_2.3.1-1_all.deb
openvswitch-vtep_2.3.1-1_amd64.deb
python-openvswitch_2.3.1-1_all.deb
这也是我们需要的相关版本,然后安装即可(默认认为Docker环境以及安装好)
sudo apt-get install -y bridge-utils
sudo dpkg -i openvswitch-common_2.3.1-1_amd64.deb \openvswitch-switch_2.3.1-1_amd64.deb
2、配置网络
默认两台机器的IP可以互相ping通,然后,只需要设置网络即可
例如在192.168.12.107机器上设置为
# auto:为了有效地在主机启动时启动它
# br0=br0:防止在`ifquery --list`时被找到
auto br0=br0
allow-ovs br0
iface br0 inet manual
ovs_type OVSBridge
ovs_ports gre1 gre2
ovs_extra set bridge ${IFACE} stp_enable=true
mtu 1462# 没有auto,这是ovs的一个额外配置
# 两台主机的gre名字必须相符
allow-br0 gre1
iface gre1 inet manual
ovs_type OVSPort
ovs_bridge br0
ovs_extra set interface ${IFACE} type=gre options:remote_ip=192.168.12.117# auto:启动时创建
# 定义docker要使用的docker0,并(在可用时)连接到到OpenVSwitch创建的br0网桥上
# 每台主机需要使用不同的IP地址(不要相互冲突!)
auto docker0=docker0
iface docker0 inet static
address 172.17.1.1
network 172.17.0.0
netmask 255.255.0.0
bridge_ports br0
mtu 1462
在其他机器上,只需在配对的远程IP修改即可,如果需要更多的宿主机,可以添加更多的gre隧道即可,例如
allow-br0 gre2(新的gre)
iface gre2 inet manual
ovs_type OVSPort
ovs_bridge br0 (都在br0网桥)
ovs_extra set interface ${IFACE} type=gre options:remote_ip=192.168.12.199(新的IP)
说明
- 生成树协议(Spanning Tree Protocol):如果应用该配置,将在3台服务器中创建一个网络回路,这可不行。给
br0
网桥添加stp_enable=true
将确保一些gre
隧道被切断。同时确保网状网络的冗余,允许网络在其中一台主机下线时恢复。 - MTU:这是一项关键设定!没有这项,你可能获得一些意外“惊喜”:网络看起来工作正常(比如可以ping),但无法支持大数据包(比如BW测试中的iperf、大数据量请求或简单的文件复制)。注意,GRE隧道需要封装多种协议:
- 以太网:14字节——我们说的是网桥间的第2层;
- IPv4:20字节——容器/主机间通讯;
- GRE:4字节——因为,嗯,这是个GRE隧道;
- 也就是物理网卡MTU减去38字节,结果是1462(基于常规的1500 MTU网卡)。
- 在auto定义中使用“
=
”:对于具有固定IP的服务器这不是必需的,但有些云服务商(这里就不说是谁了……Digital Ocean(译者:软广再次乱入))使用了一个依靠ifquery --list --allow auto
的init服务(/etc/init/cloud-init-container.conf
)。不加上“=
”号将包含OpenVSwitch网卡,并延迟整个启动过程直到init脚本失败并超时。 - docker0网桥:每台服务器都需要自己的IP地址(比如
172.17.1.1
、172.17.1.2
)。由于docker0
网桥处在br0
网桥之上,它们将(也应该!)可以相互连接。想象一下,要解决IP冲突会有多乱……这也是为什么我们要在启动时定义它,而不依赖docker服务来为我们创建这个网桥。 - GRE隧道:你可以从gre0(而不是gre1)开始,它能完美工作。但由于某种原因,在输入
ifconfig
时你可以看到gre0
,却看不到其他隧道。这可能是gre0
作为虚拟网卡的一个副作用。从gre1
开始将让所有的gre
隧道对ifconfig
“隐身”(好过于只能看见一个)。别着急,你还是可以使用ovs-vsctl
命令显示隧道/网桥。 - 3台以上主机:你可以遵循相同的逻辑,并且:
- 添加额外的隧道(iface greX)来连接新主机。
- 在
br0
网桥定义中更新ovs_ports
以包含interfaces
文件中定义的所有gre
隧道。 - 聪明点……不要将每台服务器跟其他主机一一链接……STP收敛(convergence)将需要更长的时间,并且无法提供任何除了多重额外链路冗余之外的有用价值。
设置完毕之后,建议重启机器,然后可以在任意机器上都可以相互ping通管理IP(192.168.12.xxx)和docker0的IP(172.17.1.xxx)
3、容器添加
现在已经有网络了,需要将各个宿主机的容器都添加到docker0里面
- 每台主机(
192.168.12.107
、192.168.17.117
)挂接到前面创建的docker0
网桥上,其各自的IP地址是172.17.1.1
、172.17.1.2
; - 给
docker0
网卡指定了一个/16的IP范围; - 给每台主机指定了一小块
docker0
的IP范围,以/18fixed-cidr
的形式保存在它们的docker服务配置中。分别是172.17.64.0/18
、172.17.128.0/18
如果你的主机多于3台,你需要细分一个每个范围,或根据组织需要对整个网络拓扑结构进行重新考虑。
所需,需要为每一个宿主机的docker配置相关IP信息
例如docker1机器(/etc/default/docker)
BRIDGE=docker0
CIDR=172.17.64.0/18wait_ip() {
address=$(ip add show $BRIDGE | grep 'inet ' | awk '{print $2}')
[ -z "$address" ] && sleep $1 || :
}wait_ip 5
wait_ip 15DOCKER_OPTS="
-H unix:///var/run/docker.sock
-H tcp://0.0.0.0:2375
--fixed-cidr=$CIDR
--bridge $BRIDGE
--mtu 1462
"
其他机器的CIDR参考上述即可。
你可以根据需要修改DOCKER_OPTS
配置,添加镜像、不安全的registry、DNS等等。
说明:
- wait_ip:由于
docker0
网桥最后被创建,获取IP地址可能需要花点时间。使用wait_ip
“功能”,你可以在返回docker init脚本前安全地等待几秒钟。该配置文件是被真正的init脚本(/etc/init/docker.conf
)所引用。 - mtu:与前面相同原因,只是一个预防措施,用于确保每个网卡被创建时会被指定正确的MTU。
- -H tcp://……:如果你不想通过
0.0.0.0
将其“公开”(或绑定到服务器“真实”网卡之一),你也可以将它安全地绑定到……该主机的docker0
IP地址(比如172.17.1.2
)!这样,你可以从任何一台主机访问到私有网状网络里的任何一个docker服务。
测试
1、分别在docker1和docker2运行容器实例
我在docker1运行了两个ubuntu 14.04实例,相关IP分别是172.17.64.1和172.17.64.2
我在docker2运行了一个ubuntu 14.04实例,相关IP分别是172.17.128.1
首先测试是否可以ping通
然后,我针对docker1的64.2容器,与docker2的128.1进行测试,分别安装了ssh服务,然后为docker2容器创建ss用户,然后通过docker1的64.2容器,进行ssh远程连接。
参考文献
http://dockone.io/article/228
- https://goldmann.pl/blog/2014/ ... osts/
- http://networkstatic.net/open- ... tion/
- http://networkstatic.net/confi ... itch/
- http://fbevmware.blogspot.com. ... .html
- http://openvswitch.org/support ... .html
- https://access.redhat.com/docu ... .html
- https://communities.vmware.com ... ation
- http://www.microhowto.info/tro ... .html
- http://blog.scottlowe.org/2013 ... itch/
- http://blog.scottlowe.org/2013 ... itch/
- https://github.com/openvswitch ... an.md
- http://baturin.org/tools/encapcalc/
Docker实现跨主机容器实例网络通信(2)——利用OpenVSwitch构建多主机Docker网络相关推荐
- 利用OpenVSwitch构建多主机Docker网络
本文讲的是利用OpenVSwitch构建多主机Docker网络,[编者的话]当你在一台主机上成功运行Docker容器后,信心满满地打算将其扩展到多台主机时,却发现前面的尝试只相当于写了个Hello W ...
- 在宿主机连接docker内的mysql容器实例
一.要在宿主机内连接docker内的mysql实例,就必须有一个客户端工具 1.安装mysql客户端工具 #在mysql官网找到mysql客户端下载地址,使用yum在线安装 yum -y instal ...
- docker中下载mysql容器实例(详细)
简单版 第一步:查看mysql镜像 name 镜像名字 description 描述 stars ...
- docker常规操作——删除容器实例、删除镜像
本系列目录请看这里 https://blog.csdn.net/michel4liu/article/details/80819510 我们前几篇讲了编译镜像,如果有些旧镜像不想要了怎么删除呢,如果交 ...
- docker -v 覆盖了容器中的文件_10分钟让你理解 docker 容器中的 uid 和 gid
默认情况下,容器中的进程以 root 用户权限运行,并且这个 root 用户和宿主机中的 root 是同一个用户.听起来是不是很可怕,因为这就意味着一旦容器中的进程有了适当的机会,它就可以控制宿主机上 ...
- docker宿主机访问容器_干货来啦!带你初探Docker逃逸
Docker是当今使用范围最广的开源容器技术之一,具有高效易用的优点.然而如果使用Docker时采取不当安全策略,则可能导致系统面临安全威胁. 本期安仔课堂,ISEC实验室的张老师将为大家介绍不同环境 ...
- Docker容器间网络通信
自从Docker容器出现以来,容器网络通信就一直是被关注的焦点,也是生产环境的迫切需求.容器网络通信又分为两大方面:单主机容器上的相互通信,和跨主机的容器相互通信. 一.Docker单主机容器通信 基 ...
- 物联网架构成长之路(24)-Docker练习之Compose容器编排
0.前言 一开始学的之后,是想一步到位直接上Kubernetes(K8s)的,后面没想到,好像有点复杂,有些概念不是很懂.因此学习东西还是要循序渐进,慢慢来.先了解单机编排技术Docker Compo ...
- 群晖NAS教程(十七)、利用Docker安装网心云容器魔方
为了更好的浏览体验,欢迎光顾勤奋的凯尔森同学个人博客 群晖NAS教程(十七).利用Docker安装网心云容器魔方 个人博客 一.群晖docker套件中安装onething1/wxedge镜像. 二.w ...
最新文章
- Sql Server函数全解(二)数学函数
- C++初学基础知识——注释、变量、基本数据类型
- 目录和文件管理(一)
- .NetCore之下载文件
- golang mysql封装_使用Golang 封装一个Api 框架 ----- 数据库操作篇(gorm引入)
- JavaSE04、什么是类和对象,如何使用?
- 今天来谈谈内容溢出和文字溢出的问题
- 开源视频会议系统:OpenMeetings 安装方法
- idea中不重启服务器更改代码(使用jrebel)
- Wiley Online Library的LATEX模板说明
- php集成腾讯云im
- 基于btest.so的策略测试方案
- 为什么我们需要表明身份:EV证书的价值
- Web mfw Writeup
- 线性代数学习笔记11-2:总复习Part2(相似对角化、对称矩阵、奇异值分解SVD)
- Qt加载高德在线地图
- SiamFC代码配置复现 matlab版本
- Ubuntu笔记本折腾记(专治切换显卡死机)
- shareSDK 微信分享闪退问题
- html分级管理目录,卫生部抗菌药物临床应用分级管理目录(2018最新版)