Docker 网络基础介绍
【编者按】本文作者为 Mesosphere 开发大使 Michael Hausenblas,主要介绍配置 Docker 单主机网络的基本知识。文章系国内 ITOM 管理平台 OneAPM 编译呈现。
想要了解有关 Docker 网络的更多信息,包括多主机网络介绍,请查看本文作者 Michael Hausenblas
撰写的报告——《Docker 网络与服务探索》,点此下载该报告。
当你开始扩大 Docker 的应用范围时,忽然发现,你需要了解很多关于网络的知识。作为 Docker 网络的入门介绍,本文将从小处着手,首先你要考虑如何管理容器之间的连接。Docker 容器需要有个主机才能运行,该主机既可以是实体机器(例如:企业数据中心的裸机服务器),也可以是 on-prem 或云中的虚拟机。如图一所示,主机上会运行 Docker 后台程序与 Docker 客户端。一方面,你可以与 Docker 注册表交互(pull 或 push Docker 图片);另一方面,也可以启动、停止或监视容器。
图片1. 简化版 Docker 架构(单主机)
主机与容器之间的关系为 1:N
。也就是说,一个主机上通常会运行着多个容器。例如,Facebook 报告称,取决于机器的规模,每个主机上平均运行着10到40个容器。此外,Mesosphere 对裸机进行的多项负载测试结果显示,在每个主机上运行250以内的容器是可能的。
不过,无论是单主机部署模式,还是采用了机器集群,你都不可避免地需要面对网络:
- 对大多数单主机部署而言,问题可以归结为通过共享卷组(shared volume)进行数据交换还是通过网络(基于 HTTP
或其他协议)进行数据交换。尽管 Docker
数据卷组简单易用,但也会导致紧密耦合,这意味着更难将单主机部署转变为多主机部署。通常,共享卷组的优势在于数据处理速度。 - 在多主机部署中,你需要考虑两个方面:单个主机内的容器如何相互交流?不同主机之间的容器又如何交流?性能考虑与安全要素都将影响你的设计决定。当单主机的容量无法满足需求(请参考前文关于单主机承载的平均容器数及最大容器数的讨论),或打算使用诸如
Apache Spark, HDFS 或 Cassandra 之类的分布式系统时,多主机部署就变得必不可少了。
分布式系统与数据局部性
使用分布式系统(进行计算或存储)的主要好处通常来自并发处理,后者常常伴随数据局部性。此处,数据局部性是指将代码发布至数据所处位置的原则,而不是传统的那样倒过来。试思考以下情况:如果你的数据集大小以
TB 计,而代码量以 MB 计,在集群中移动代码其实比将多个 TB
的数据移至中央处理区更加高效。除了获得并发处理的优势,分布式系统还具备更好的容错性,因为系统的一些部分仍或多或少保留了独立运转的能力。
简而言之,Docker 网络是 Docker 提供的原生容器 SDN 解决方法。概括来说,Docker 网络提供了四种可选模式:桥接模式、主机模式、容器模式以及无网络模式。本文将逐一讨论这四种模式与单主机配置相关的内容,并在文末总结时提及诸如安全之类的一般话题。
桥接模式网络
在此模式下(参考图片2),Docker 后台程序会创建 docker0
,一个虚拟的以太网桥,用于自动转发与之连接的任意网络接口间的数据包。默认情况下,该后台进程会创建一对对等接口(peer interface),分派其一为容器的 eth0 接口,另一个则分派在主机的命名空间下,同时从私有 IP 地址范围中为该桥接分配一个 IP 地址或子网络,由此,同一主机上的所有容器都连接到此内网中。
示例1. 运行中的 Docker 桥接模式网络
$ docker run -d -P --net=bridge nginx:1.9.1$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES17d447b7425d nginx:1.9.1 nginx -g 19 seconds ago
Up 18 seconds 0.0.0.0:49153->443/tcp, 0.0.0.0:49154->80/tcp trusting_feynman
注意
由于桥接模式是 Docker 默认的连接模式,在示例1中,你也可以使用
docker run -d -P nginx:1.9.1
。如果你没有使用-P
参数(用于发布容器的所有公开端口),也没有使用-p host_port:container_port
(用于发布特定的端口),IP 数据包在主机之外就无法路由至容器。
图片2. 桥接模式网络设置
主机模式网络
该模式能有效禁止 Docker 容器的网络隔离。因为容器共享了主机的网络命名空间,它会直接暴露于公网。因此,你需要通过端口映射(port mapping)开展协调工作。
实例2. 运行中的 Docker 主机模式网络
$ docker run -d --net=host ubuntu:14.04 tail -f /dev/null$ ip addr | grep -A 2 eth0:2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000 link/ether 06:58:2b:07:d5:f3 brd ff:ff:ff:ff:ff:ff
inet **10.0.7.197**/22 brd 10.0.7.255 scope global dynamic eth0
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
b44d7d5d3903 ubuntu:14.04 tail -f 2 seconds ago
Up 2 seconds jovial_blackwell
$ docker exec -it b44d7d5d3903 ip addr2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000 link/ether 06:58:2b:07:d5:f3 brd ff:ff:ff:ff:ff:ff
inet **10.0.7.197**/22 brd 10.0.7.255 scope global dynamic eth0
正如示例2所示,容器与主机的 IP 地址是一致的,同为 10.0.7.197
。
在图片3中,在使用主机模式时,容器直接继承了其所在主机的 IP 地址。该模式相比桥接模式运转更迅速(因为不存在路由的开销),但是它直接将容器暴露于公网中,而后者包含了诸多安全隐患。
图片3. Docker 主机模式网络设置
容器模式网络
在此模式下,Docker 会重用其他容器的网络命名空间。通常,如果你想提供客制化的网络堆栈,该模式最为有用。该模式也为 Kubernetes 网络所采用。
示例3. 运行中的 Docker 容器模式网络
$ docker run -d -P --net=bridge nginx:1.9.1$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
eb19088be8a0 nginx:1.9.1 nginx -g 3 minutes ago Up 3 minutes0.0.0.0:32769->80/tcp,0.0.0.0:32768->443/tcp admiring_engelbart
$ docker exec -it admiring_engelbart ip addr8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
inet **172.17.0.3**/16 scope global eth0
$ docker run -it --net=container:admiring_engelbart ubuntu:14.04 ip addr...8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
inet **172.17.0.3**/16 scope global eth0
结果(如实例3所示)正如我们所想:通过 --net=container
启动的第二个容器与第一个容器拥有相同的 IP 地址,即自动分配的 admiring_engelbart
,也即 172.17.0.3
。
无网络模式
该模式将容器置于其网络堆栈之内,但并不进行配置。由此,断绝了网络连接,主要适用于以下两种情况:不需要网络的容器(例如:向磁盘卷组进行写入的批量作业),以及当你想配置自定义网络时。
示例4. 运行中的 Docker 无网模式
$ docker run -d -P --net=none nginx:1.9.1$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
d8c26d68037c nginx:1.9.1 nginx -g 2 minutes ago
Up 2 minutes grave_perlman
$ docker inspect d8c26d68037c | grep IPAddress "IPAddress": "", "SecondaryIPAddresses": null,
正如示例4所见,并未配置网络连接——这正是我们所期望的。
你可以在此 Docker 文档中了解有关网络以及配置选项的更多知识。
注意 本文提及的所有 Docker 指令都在 CoreOS 环境中实践过,Docker 客户度与主机端的版本号均为 1.7.1。
总结
除了上文提及的四种 Docker 单主机网络模式,你还应了解以下几个方面的内容(这些内容也都与多主机部署密切相关)。
分配 IP 地址
当容器数量变化频繁且涉及的数量较多时,手动分配 IP 地址是不可行的。桥接模式在一定程度上能解决该问题。为了避免本地网络中的 ARP (Address Resolution Protocol,地址解析协议)冲突,Docker 后台进程会根据分配的 IP 地址随机生成 MAC 地址。
分配端口
你会发现自己不是处于固定端口分配阵营,就是动态端口分配阵营。这可以是随服务或应用而变的策略,也可以是全局策略,但是,你必须下定决心。记住,在桥接模式下,Docker 能自动分配可路由的(UDP 或 TCP)端口。
网络安全
默认情况下,Docker 启用了容器间通讯(这意味着默认设置为 --icc=true
),也就是说,同一主机上的容器可以毫无限制地相互交流,这有可能导致拒绝服务(DOS)攻击。此外,Docker 通过 --ip_forward
与 --iptables
标记控制容器与外部世界的交流。你应该学习这些标记的默认值,并让公司安全团队也有所了解,同时在 Docker 后台进程的设置中体现你的认知。对了,由 StackEngine 的 Boyd Hemphill 完成的 Docker 安全分析也是很好的学习材料。
另一个需要考虑的网络安全问题是在线加密。然而,在撰写本文时,针对这一问题的解决方案非常有限。只有两个系统提供了开箱即用的解决方案:使用 NaCl 的 Weave 以及包含基于 TLS 设置的 OpenVPN。据笔者从 Docker 安全主管 Diogo Mónica 处得到的消息,在线加密可能从 1.9版本后开始提供。
最后,建议阅读 Adrian Mouat 撰写的《Docker 使用入门》,该文档详细介绍了有关网络安全的方方面面。
小贴士 自动 Docker 安全检查 若要在生产环境中自动检查部署 Docker 容器的常见安全问题,笔者强烈推荐使用 The
Docker Bench for Security。
OneAPM Cloud Insight 产品集监控、管理、计算、协作、可视化于一身,帮助所有 IT 公司,减少在系统监控上的人力和时间成本投入,让运维工作更加高效、简单。想阅读更多技术文章,请访问 OneAPM 官方技术博客。
本文转自 OneAPM 官方博客
原文地址:https://www.oreilly.com/learning/what-is-docker-networking
Docker 网络基础介绍的更多相关文章
- Docker网络基础:快速指南
Docker网络基础:快速指南 原文连接:http://blogxinxiucan.sh1.newtouch.com/2017/07/30/Docker网络基础:快速指南/ 了解有关扩展网络功能的默认 ...
- Docker网络模式介绍
一.概述 docker的网络驱动有很多种方式,按照docker官网给出的网络解决方案就有6种,分别是:bridge.host.overlay.macvlan.none.Network plugins, ...
- Docker: 基础介绍 [一]
一.Docker介绍 Docker是Docker.lnc公司开源的一个基于LXC技术之上构建的Container容器引擎,源代码托管在Github上,基于Go语言并遵从Apache2.0协议开源 Do ...
- docker网络基础配置
常用两种方式: 1)映射容器端口到宿主机 2)容器互联机制 --------------------------------------------- 端口映射实现访问容器的用法: docker ru ...
- Docker网络基础
大量的互联网应用服务包括多个服务组件,这往往需要多个容器之间通过网络通信进行相互配合. Docker目前提供了映射容器端口到宿主主机和容器互联机制来为容器提供网络服务. 端口映射实现访问容器: 在启动 ...
- Linux虚拟网络:Docker网络知识之基础篇
我们在工作中应用了docker容器化技术,服务的部署.维护和扩展都方便了很多.然而,近期在私有化部署过程中,由于不同服务器环境的复杂多变,常常遇到网络方面的问题,现象为容器服务运行正常,但宿主机.容器 ...
- docker网络配置
Docker网络配置 Docker网络模式介绍 Docker在创建容器时有四种网络模式:bridge/host/container/none,bridge为默认不需要用--net去指定,其他三种模式需 ...
- Docker网络配置、Docker部署分布式项目
目标 1.Docker网络配置 2.Docker部署SpringCloud项目 Docker网络配置 Docker网络模式介绍 Docker在创建容器时有四种网络模式:bridge/host/cont ...
- 基于Docker的MindSpore安装与使用基础介绍
技术背景 MindSpore是一款新一代AI开源计算框架,其特色在于:创新编程范式,AI科学家和工程师更易使用,便于开放式创新:该计算框架可满足终端.边缘计算.云全场景需求,能更好保护数据隐私:可开源 ...
随机推荐
- django第二课 网页继承
第一步 创建项目(有问题可以看我的第一个博客) C:\Python36\Scripts\django-admin.py startproject *** (我的写法,仅供参考) 第二步 创建文件夹,同 ...
- 【C#小知识】C#中一些易混淆概念总结(六)---------解析里氏替换原则,虚方法 分类: C# 2014-02-08 01:53 1826人阅读 评论(0) 收藏
目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...
- Okhttp3上传多张图片同时传递参数
之前上传图片都是直接将图片转化为io流传给服务器,没有用框架传图片. 最近做项目,打算换个方法上传图片. Android发展到现在,Okhttp显得越来越重要,所以,这次我选择用Okhttp上传图片. ...
- android listview实现点击某个item后使其显示在屏幕顶端
在该listview的点击事件中加入一下代码即可 listView.setSelectionFromTop(position, 0);
- go语言的unsafe包(转)
The unsafe Package in Golang Golang的unsafe包是一个很特殊的包. 为什么这样说呢? 本文将详细解释. 来自go语言官方文档的警告 unsafe包的文档是这么说的 ...
- android学习-ndk-build(androidstudio编译cocos2d-x库的cpp为so文件的解释)
本文不作为ndk初学使用,只是对cpp等c++文件编译成so文件的过程中,参数含义,及ndk配置的解释.使用的技术比较旧. androidStudio使用gradle调用ndk-build工具编译c+ ...
- 数据库学习---SQL基础(一)
数据库学习---SQL基础(一) 数据库学习---SQL基础(二) 数据库学习---SQL基础(三) SQL(struct query language)结构化查询语言:一种专门与数据库通信的语言, ...
- 生成类似于MongoDB产生的ObjectId
package com.jt.boot.utils; import com.google.common.base.Objects; import java.net.NetworkInterface; ...
- 文件触发式实时同步 Rsync+Sersync Rsync+Inotify-tools
一.概述 1.Rsync+Sersync 是什么? 1)Sersync使用c++编写基于inotify开发的触发机制: 2)Sersync可以监控所监听的目录发生的变化(包括新建.修改.删除),具体到 ...
- 搭建jenkins
使用Jenkins配置Git+Maven的自动化构建 实现背景:Jenkins通过给定的代码地址URL,将代码拉取到其“宿主服务器”(就是Jenkins的安装位置),进行编译.打包和发布到容器中.在J ...