InfoQ Geekathon 大模型技术应用创新大赛 了解详情
写点什么

Docker 扁平化网络设计与实现

  • 2016-10-25
  • 本文字数:2892 字

    阅读完需:约 9 分钟

研发背景

众所周知,Docker 容器跨主机互访一直是一个问题,Docker 官方为了避免网络上带来的诸多麻烦,故将跨主机网络开了比较大的口子,而由用户自己去实现。目前 Docker 跨主机的网络实现方案也有很多种,主要包括端口映射、ovs、 fannel 等。

但是这些方案都无法满足我们的需求:端口映射服务内的内网 IP 会映射成外网的 IP,这样会给开发带来困惑,因为他们往往在跨网络交互时是不需要内网 IP 的;而 ovs 与 fannel 则是在基础网络协议上又包装了一层自定义协议,这样当网络流量大时,却又无端的增加了网络负载。最后我们采取了自主研发扁平化网络插件,也就是说让所有的容器统统在大二层上互通。

Docker 原生四种网络模式

目前,基于 Docker 的网络模式有很多种,接下来就简单的对 Bridge、Host、Container、None 模式进行介绍。

A. Bridge 模式该模式为 Docker 的默认网络模式,Docker daemon 会在宿主机上建立一个默认的网桥 docker0, 相信大家对 docker0 非常熟悉,但是在跨容器通信当中它却没有派上用场,因为默认的 docker0 的地址都是内网地址,而且启动后容器虽然也桥接在 docker0 上,但是容器的默认网关却依然无法设置,这就是 docker 原生默认网络的一个弊端。当然了,他却实现了在当先宿主机的网络隔离,拥有自己的 namespace, 网卡和 IP,具体的桥接原理我将在后面继续说明。

B. Host 模式

该模式其实就是和当前宿主机共享网络空间,而 Docker 本身并没有进行网络隔离,说的通俗点,也就是说容器其实都是和宿主机拥有相同的 IP, 而如何具体区分各个容器的呢?那就是通过端口映射,在启动 Docker 容器的时候来指定 -p 参数来进行设置端口映射。虽然这种方式在某种程度上也可以达到跨宿主机容器访问的目的,但是,却丧失了 Docker 网络隔离的意义,而且端口映射同样给微服务迁移带来一些麻烦,无法像非虚拟环境那样的平滑迁移,而是要考虑到很多端口转换的问题。

C. Container 模式

顾名思义,此模式会共享另一个容器的网络命名空间,但是会限制在一台宿主机上,依然无法实现容器间跨主机通信的功能。

D. None 模式

该模式是容器拥有自己的网络命名空间,自己的网路栈,自己的网卡,不和外界有任何瓜葛,容器网络完全独立,换句话说就是容器不需要网络功能,这种模式适用于容器包含写数据到磁盘卷的一些任务。这种模式依然无法实现我们的跨宿主机容器网络通信的功能。

自研 Docker Overlay 网络模式

目前 Overlay 网络模式主要是由隧道和路由两种方式实现,一种是对基础网络协议进行封包,另一种是配置更复杂的路由配置实现容器间跨主机的网络通信。其实,以上两种或多或少的都会给我们网络的实现带来了复杂性以及性能上的损耗,因为当我们拥有庞大的业务集群以后,这些复杂度和性能损耗都是不能忽视的。

插件原理如下:

1. 创建 Docker 自定义网络

复制代码
docker network create
--opt=com.docker.network.bridge.enable_icc=true
--opt=com.docker.network.bridge.enable_ip_masquerade=false
--opt=com.docker.network.bridge.host_binding_ipv4=0.0.0.0
--opt=com.docker.network.bridge.name=br0
--opt=com.docker.network.driver.mtu=1500
--ipam-driver=talkingdata

–subnet= 容器 IP 的子网范围, 例:172.18.0.0/17

–gateway=br0 网桥使用的 IP, 也就是宿主机的地址, 例:172.18.0.5

–aux-address=DefaultGatewayIPv4= 容器使用的网关地址 mynet

我们首先需要创建一个 br0 自定义网桥,这个网桥并不是通过系统命令手动建立的原始 Linux 网桥,而是通过 Docker 的 create network 命令来建立的自定义网桥,这样避免了一个很重要的问题就是我们可以通过设置 DefaultGatewayIPv4 参数来设置容器的默认路由,这个解决了原始 Linux 自建网桥不能解决的问题. 用 Docker 创建网络时我们可以通过设置 subnet 参数来设置子网 IP 范围,默认我们可以把整个网段给这个子网,后面可以用 ipam driver(地址管理插件)来进行控制。还有一个参数 gateway 是用来设置 br0 自定义网桥地址的,其实也就是你这台宿主机的地址啦。

2.IPAM

这个驱动是专门管理 Docker 容器 IP 的, Docker 每次启停与删除容器都会调用这个驱动提供的 IP 管理接口,然后 IP 接口会对存储 IP 地址的 Etcd 有一个增删改查的操作。此插件运行时会起一个 Unix Socket, 然后会在 docker/run/plugins 目录下生成一个.sock 文件,Docker daemon 之后会和这个 sock 文件进行沟通去调用我们之前实现好的几个接口进行 IP 管理,以此来达到 IP 管理的目的,防止 IP 冲突。

3. 桥接

通过 Docker 命令去创建一个自定义的网络起名为“mynet”,同时会产生一个网桥 br0,之后通过更改网络配置文件(在 /etc/sysconfig/network-scripts/ 下 ifcfg-br0、ifcfg- 默认网络接口名)将默认网络接口桥接到 br0 上,重启网络后,桥接网络就会生效。Docker 默认在每次启动容器时都会将容器内的默认网卡桥接到 br0 上,而且宿主机的物理网卡也同样桥接到了 br0 上了。其实桥接的原理就好像是一台交换机,Docker 容器和宿主机物理网络接口都是服务器,通过 veth pair 这个网络设备像一根网线插到交换机上。至此,所有的容器网络已经在同一个网络上可以通信了,每一个 Docker 容器就好比是一台独立的虚拟机,拥有和宿主机同一网段的 IP,可以实现跨主机访问了。

4.etcd

我们可以设置 1,3,5,7 个节点为 Etcd 集群去集中管理 Docker 集群的 IP,而且我们也将宿主机的地址进行了统一的管理,这样做同样也是为了避免 IP 的使用冲突导致线上资源不可用。我们会通过自己开发的工具进行 IP 初始化,也就是说会传进来一个 IP 范围,然后工具会将所有的 IP 存进 etcd 中,每一个网络 ID 就是一个 etcd 目录,目录下就会分成已分配与未分配的 IP 地址池。etcd 本身会提供 Go 语言的 API 来访问 etcd, 目前 etcd 还是相当稳定的,没有出现过什么问题。

结语

我们的 Docker 集群是采用 Swarm 进行管理的,Swarm 相对 K8S 来说要简单的很多,但是在编排功能上也会有所欠缺,不过等 Docker 的新版本 1.12 发布以后,Swarm 会集成到 Docker 内部,而且会增加许多的功能,我想那时这个问题就会迎刃而解了。管理 Swarm 的是采用第三方的管理图形界面软件 shipyard,这款软件本身并不会兼容自定义网络,而且在设置每个容器使用的 CPU 核数时又会有 BUG,我们对此开源软件进行了二次开发,解决了这些问题。现如今我们已经成功的在上面运行了 YARN 集群,网络性能也是没有什么问题的。

参考

https://docs.docker.com/engine/extend/plugins

https://github.com/docker/libnetwork/blob/master/docs/ipam.md

https://github.com/docker/go-plugins-helpers

该 Docker 插件的开源地址:
https://github.com/TalkingData/Shrike

关于作者

马超,TalkingData 运维部研发工程师,精通 Golang 和 Python,五年技术工作经历,曾从事手机游戏服务端研发, 技术运营研发工程师。关注 平台稳定性(监控,问题发现及响应)和资源充分利用(虚拟化,容器)。


感谢木环对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

活动推荐:

2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。

2016-10-25 19:003467

评论

发布
暂无评论
发现更多内容

企业在线产品宣传册应该如何设计?

小炮

产品宣传手册

2022年最热门的招聘技术技能是什么,您绝对想不到

禅道项目管理

项目管理 开发技能

内存之旅——如何提升CMA利用率?

OpenHarmony开发者

内存 OpenHarmony

译文《Java并发编程之volatile》

潘大壮

并发编程 volatile 后端 Java EE

安全Linux 内核提权漏洞分析

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 漏洞挖掘

洞见科技成为华东江苏大数据交易中心会员单位,创始人姚明获颁「年度数字经济卓越领袖奖」

洞见科技

数据中心 隐私计算 数据交易

Docker Build时的安全问题

火线安全

Docker 云原生 云安全 docker build

以太坊的扩容革命:ETH2.0

不登山的小鲁

以太坊 扩容 Ethereum eth eth2.0

OpenHarmony 3.1 Beta版本关键特性解析——探秘隐式查询

OpenHarmony开发者

OpenHarmony 隐式查询

DevOps落地思考

火线安全

DevOps 云原生 云安全 DevOps认证

融云直播 SDK 升级,让直播「PK」起来

融云 RongCloud

直播 IM 场景化

墨天轮访谈 | Pika数据库陈磊:云时代下,键值数据库是否会被替代?

墨天轮

数据库 KV存储引擎 国产数据库

天翼云成为首个加入openGauss社区的运营商云

天翼云开发者社区

跑马灯带你深入浅出TextView的源码世界

vivo互联网技术

android 源码分析 TextView

长连接网关技术专题(七):小米小爱单机120万长连接接入层的架构演进

JackJiang

网络编程 websocket 即时通讯 网关 长连接

OceanBase 社区 Webinar 首播官宣|社区版 RoadMap 和性能调优!周四见

OceanBase 数据库

OceanBase 社区版

跨境电商数据融合实践|OceanBase 助力致欧家居打造分布式跨境电商

OceanBase 数据库

oceanbase 致欧家居

Gartner发布中国IaaS PaaS市场服务报告,天翼云强势入选

天翼云开发者社区

VuePress 博客之 SEO 优化(六)站长工具

冴羽

Vue 前端 vuepress SEO 博客搭建

QoS 设计:车联网平台消息传输质量保障|车联网平台搭建从入门到精通 04

EMQ映云科技

物联网 IoT mqtt coap emq

融云互联网通信安全揭秘之链路安全

融云 RongCloud

网络安全

恒源云(GpuShare)_这个春天,GpuShare与你同行

恒源云

抗疫

MASA Blazor入门这一篇就够了

MASA技术团队

C# .net 组件 组件库

Rust 用于移动开发的几种方式

非凸科技

Java c++ Python rust 量化

信通院推出数字化赋能者新标准天翼云获评数字化转型赋能服务集体

天翼云开发者社区

公有云市场百舸争流!天翼云稳居第一梯队,进入领导者象限

天翼云开发者社区

一文来了解关于分布式锁的那些事儿

Linux服务器开发

redis 分布式 分布式锁 Linux服务器开发 Linux后台开发

中台和多云管理是伪问题?运维要集体下岗了吗?

火线安全

DevOps 云原生 云安全

雄安新区设立四周年,看天翼云以数字底座托起未来之城

天翼云开发者社区

Linux云计算之linux grep命令详解

学神来啦

云计算 Linux 运维 grep

龙蜥社区一周动态 | 3.14-3.18

OpenAnolis小助手

开源 操作系统 龙蜥社区 一周动态

  • 扫码添加小助手
    领取最新资料包
Docker扁平化网络设计与实现_语言 & 开发_马超_InfoQ精选文章