利用OpenVSwitch构建多主机Docker网络

简介: 本文讲的是利用OpenVSwitch构建多主机Docker网络,【编者的话】当你在一台主机上成功运行Docker容器后,信心满满地打算将其扩展到多台主机时,却发现前面的尝试只相当于写了个Hello World的入门程序,多主机的网络设置成了下一道门槛。
本文讲的是利用OpenVSwitch构建多主机Docker网络 【编者的话】当你在一台主机上成功运行Docker容器后,信心满满地打算将其扩展到多台主机时,却发现前面的尝试只相当于写了个Hello World的入门程序,多主机的网络设置成了下一道门槛。在你尝试各种方案时不妨先看看本文,或许就会豁然开朗,发现原来也不复杂。嗯,是的,本文用到了OpenVSwitch。

运行Docker已经不是什么新鲜事,网上有很多入门教程来帮助你在一台主机上运行容器。这台主机可以是Linux服务器,也可以是Mac(借助类似 boot2docker 的项目)。

在多台主机上运行却是另外一回事……

可选方案:
  • 分别在每台主机上运行Docker,在公网或内网网卡上暴露端口以便容器间相互通讯。这可能比较麻烦,而且会引发安全问题。
  • 运行类似Weave的中间层方案来完全地抽象网络。这个项目前景不错,不过还太年轻,尚未与compose(之前的fig)或maestro-ng这类编排工具整合。
  • 运行类似DeisFlynn的Docker多主机一站式方案。这可能不在你的考虑范围内。
  • 在主机间的网状网络中创建一个共享网桥,让Docker服务在那运行容器。这听起来有点复杂,不过……本文中我们将看到这可以非常容易地完成!

multi-host-docker1.jpg

概述

基本上,我们将执行以下步骤:
  • 在每台服务器上安装Docker;
  • 在每台服务器上安装OpenVSwitch;
  • 自定义网络设置用以自动在主机间创建网桥/隧道(在每台服务器的/etc/network/interfaces里);
  • 自定义每个Docker服务配置,只处理docker0 IP范围的一小部分,防止新容器的IP地址发生重叠。

就是这样。重启服务或重启服务器后,你将获得一个具备连接冗余(link redundancy)的全网状网络,Docker服务可以在专用的IP范围(不会重叠)上运行容器,并且不需要在公网或内网网卡上暴露所有端口就能互联。很棒,对么?

技术

简单列一下我们用到的技术:
  • Docker:嗯……这是篇关于Docker与网络的文章,所以……
  • OpenVSwitch:非常棒的虚拟网络交换机项目,伸缩性非常好,根据本指南,你可以运行“任意”规模的网络。

我们将假定服务器运行的是Ubuntu Server 14.04.02 LTS x64,对于其它系统,你可能需要修改下面提供的各项配置。

安装

Docker

无需多言,遵循 官网 提供的指南就行。稍后我们将深入其配置,以便运行于服务器上的不同Docker服务可相互协作。

OpenVSwitch

糟糕的是,默认仓库里OpenVSwitch安装包不可用(或过期了),我们需要自己构建 .deb 文件(一次),然后分发给不同主机。为了保持生产机的整洁,可另外找台小主机来安装开发包,并构建安装包。

OpenVSwitch GitHub 上有详细的构建手册。

执行下列命令来构建安装包(新版请按要求修改):
#获取最新存档
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

现在你有了新的 .deb 安装包,接下来将其推送并安装到所有主机上。
# 复制包到各主机并ssh登录
scp -r *deb user@remote_host:~/.
ssh user@remote_host

# 安装一些依赖(后面需要)并安装包
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

配置

网络

你可以使用OpenVSwitch提供的不同命令行工具来构建网状网络(比如 ovs-vsctl ),不过Ubuntu提供了一个辅助工具让你可以通过 /etc/network/interfaces 文件定义网络。

假定三台主机:1.1.1.1、2.2.2.2和3.3.3.3,可以通过上述IP相互ping通,它们是在公网或内网上并不重要。host1的 /etc/network/interfaces 大概如下。
...
# eth0、eth1和lo配置
...

# 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=2.2.2.2

allow-br0 gre2
iface gre2 inet manual
ovs_type OVSPort
ovs_bridge br0
ovs_extra set interface ${IFACE} type=gre options:remote_ip=3.3.3.3

# auto:启动时创建
# 定义docker要使用的docker0,并(在可用时)连接到到OpenVSwitch创建的br0网桥上
# 每台主机需要使用不同的IP地址(不要相互冲突!)
auto docker0=docker0
iface docker0 inet static
address 172.17.42.1
network 172.17.0.0
netmask 255.255.0.0
bridge_ports br0
mtu 1462

在其它主机上要对这个配置上做些调整: remote_ip 的IP地址要相互配对。

multi-host-docker2.jpg


几点说明:
  • 生成树协议(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.42.1172.17.42.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)将需要更长的时间,并且无法提供任何除了多重额外链路冗余之外的有用价值。

如果现在重启服务器,你将拥有一个具备冗余的网状网络,你可以运行以下命令来测试:
  • 从host1上ping 172.17.42.2或其他IP;
  • 在主机上运行iperf,通过ifconfig查看使用中的链接;
  • 在ping第三台主机时停止“中间”那台,查看网络收敛(通过STP)时ping中断了几秒钟。

multi-host-docker3.jpg

Docker

我们现在有了一个完善的网络,每个Docker服务都可以将它们的容器挂接到 docker0 网桥上。让Docker自动完成这步不是很棒么?答案在于Docker有能力分配一个最小的IP地址池!

对于该示例,我们假定:
  • 每台主机(1.1.1.12.2.2.23.3.3.3)挂接到前面创建的docker0网桥上,其各自的IP地址是172.17.42.1172.17.42.2172.17.42.3
  • docker0网卡指定了一个/16的IP范围;
  • 给每台主机指定了一小块docker0的IP范围,以/18 fixed-cidr的形式保存在它们的docker服务配置中。分别是172.17.64.0/18172.17.128.0/18172.17.192.0/18

如果你的主机多于3台,你需要细分一个每个范围,或根据组织需要对整个网络拓扑结构进行重新考虑。

multi-host-docker4.jpg


host1的配置文件( /etc/default/docker )是这样的:
BRIDGE=docker0
CIDR=172.17.64.0/18

wait_ip() {
address=$(ip add show $BRIDGE | grep 'inet ' | awk '{print $2}')
[ -z "$address" ] && sleep $1 || :
}

wait_ip 5
wait_ip 15

DOCKER_OPTS="
-H unix:///var/run/docker.sock
-H tcp://0.0.0.0:2375
--fixed-cidr=$CIDR
--bridge $BRIDGE
--mtu 1462
"

你可以根据需要修改 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.42.2)!这样,你可以从任何一台主机访问到私有网状网络里的任何一个docker服务。

结语

重启一下(至少保证启动时所有东西都会自动上线)。

你可以试试以下命令看看一切是否正常。
# 访问host1
ssh user@host1

# 运行一个新容器
docker run -ti ubuntu bash

# 检查IP(在容器内运行)
ip add | grep eth0


#
# 在其他窗口中
#
# 访问另一台主机(host2或3)
ssh user@host2

# 运行一个新容器
docker run -ti ubuntu bash

# Ping其他的容器!
ping $IP

这不是一份指导如何在多主机上设置Docker的权威指南,欢迎大家提出批评(译者注:译稿也一样,请大家多多指正)。很多想法是在整体安装时产生的,本文尽可能详细地说明了为何选择这个或那个选项。

如果将分级网桥、VLAN等包括进来,事情将更复杂,不过那超出了本文的范围。;)

显然,更完整的网络是有需求的,而且看起来这个已经在开发中。

参考内容

如果你读完本文了,恭喜!

原文链接:MULTI-HOST DOCKER NETWORK(翻译:梁晓勇 校对:宋瑜)

原文发布时间为:2015-03-06
本文作者:sean 
本文来自云栖社区合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:利用OpenVSwitch构建多主机Docker网络
目录
相关文章
|
14天前
|
安全 网络安全 数据安全/隐私保护
网络堡垒的构建者:洞悉网络安全与信息安全的深层策略
【4月更文挑战第9天】在数字化时代,数据成为了新的价值核心。然而,随之而来的是日益复杂的网络安全威胁。从漏洞利用到信息泄露,从服务中断到身份盗用,攻击手段不断演变。本文深入剖析了网络安全的关键组成部分:识别和防范安全漏洞、加密技术的应用以及提升个体和企业的安全意识。通过探讨这些领域的最佳实践和最新动态,旨在为读者提供一套全面的策略工具箱,以强化他们在数字世界的防御能力。
|
2天前
|
运维 前端开发 Devops
云效产品使用报错问题之流水线打包docker镜像时报网络代理有问题如何解决
本合集将整理呈现用户在使用过程中遇到的报错及其对应的解决办法,包括但不限于账户权限设置错误、项目配置不正确、代码提交冲突、构建任务执行失败、测试环境异常、需求流转阻塞等问题。阿里云云效是一站式企业级研发协同和DevOps平台,为企业提供从需求规划、开发、测试、发布到运维、运营的全流程端到端服务和工具支撑,致力于提升企业的研发效能和创新能力。
|
4天前
|
存储 安全 网络安全
构建坚固的防线:云计算环境下的网络安全策略
【4月更文挑战第19天】 随着企业纷纷迁移至云平台,云计算已成为现代信息技术架构的核心。然而,数据存储与处理的云端化也带来了前所未有的安全挑战。本文深入探讨了在复杂多变的云环境中,如何实施有效的网络安全措施,确保信息安全和业务连续性。通过分析云服务模型、网络威胁以及加密技术,提出了一系列切实可行的安全策略,旨在帮助组织构建一个既灵活又强大的防御体系。
15 1
|
4天前
|
监控 安全 算法
数字堡垒的构建者:网络安全与信息保护的现代策略
【4月更文挑战第19天】在信息化快速发展的今天,网络安全和信息安全已成为维护社会稳定、保障个人隐私和企业商业秘密的关键。本文将深入探讨网络安全漏洞的成因、加密技术的进展以及提升安全意识的重要性,旨在为读者提供一套综合性的网络防护策略,以应对日益猖獗的网络威胁。
7 1
|
5天前
|
存储 运维 监控
构建高效稳定的Docker容器监控体系
【4月更文挑战第18天】 在现代微服务架构中,Docker容器已成为部署和运行应用的标准环境。随之而来的挑战是如何有效监控这些容器的性能与健康状况,确保系统的稳定性和可靠性。本文将探讨构建一个高效稳定的Docker容器监控体系的关键技术和方法,包括日志管理、性能指标收集以及异常检测机制,旨在为运维人员提供实用的指导和建议。
10 0
|
7天前
|
机器学习/深度学习 资源调度 数据可视化
使用Python和Keras进行主成分分析、神经网络构建图像重建
使用Python和Keras进行主成分分析、神经网络构建图像重建
10 1
|
8天前
|
数据采集 API 数据安全/隐私保护
畅游网络:构建C++网络爬虫的指南
本文介绍如何使用C++和cpprestsdk库构建高效网络爬虫,以抓取知乎热点信息。通过亿牛云爬虫代理服务解决IP限制问题,利用多线程提升数据采集速度。示例代码展示如何配置代理、发送HTTP请求及处理响应,实现多线程抓取。注意替换有效代理服务器参数,并处理异常。
畅游网络:构建C++网络爬虫的指南
|
16天前
|
机器学习/深度学习 人工智能 运维
构建未来:AI驱动的自适应网络安全防御系统
【4月更文挑战第7天】 在数字时代的浪潮中,网络安全已成为维系信息完整性、保障用户隐私和确保商业连续性的关键。传统的安全防御策略,受限于其静态性质和对新型威胁的响应迟缓,已难以满足日益增长的安全需求。本文将探讨如何利用人工智能(AI)技术打造一个自适应的网络安全防御系统,该系统能够实时分析网络流量,自动识别并响应未知威胁,从而提供更为强大和灵活的保护机制。通过深入剖析AI算法的核心原理及其在网络安全中的应用,我们将展望一个由AI赋能的、更加智能和安全的网络环境。
28 0
|
24天前
|
运维 Kubernetes 持续交付
构建高效自动化运维体系:基于Docker和Kubernetes的最佳实践
在现代云计算环境中,自动化运维成为保障系统稳定性与提升效率的关键。本文深入探讨了如何利用Docker容器化技术和Kubernetes容器编排工具构建一个高效、可靠的自动化运维体系。文中不仅介绍了相关的技术原理,还结合具体案例分析了实施过程中的常见问题及解决方案,为读者提供了一套行之有效的最佳实践指南。
|
26天前
|
运维 监控 云计算
构建高效稳定的Docker容器监控体系
随着微服务架构的普及,Docker容器作为其核心承载单元,在系统运维中扮演着日益重要的角色。本文旨在探讨如何构建一个高效且稳定的Docker容器监控体系,以确保容器运行的可靠性和系统的高可用性。文章首先分析了容器监控的必要性,接着详细介绍了监控体系的设计理念和组件选择,最后提供了实施过程中的关键步骤与最佳实践。通过本文,读者将掌握构建和维护Docker容器监控体系的有效方法。