百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Docker 网络基础介绍

bigegpt 2024-09-14 00:13 44 浏览

【编者按】本文作者为 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 -Pnginx: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 官方技术博客。

相关推荐

当Frida来“敲”门(frida是什么)

0x1渗透测试瓶颈目前,碰到越来越多的大客户都会将核心资产业务集中在统一的APP上,或者对自己比较重要的APP,如自己的主业务,办公APP进行加壳,流量加密,投入了很多精力在移动端的防护上。而现在挖...

服务端性能测试实战3-性能测试脚本开发

前言在前面的两篇文章中,我们分别介绍了性能测试的理论知识以及性能测试计划制定,本篇文章将重点介绍性能测试脚本开发。脚本开发将分为两个阶段:阶段一:了解各个接口的入参、出参,使用Python代码模拟前端...

Springboot整合Apache Ftpserver拓展功能及业务讲解(三)

今日分享每天分享技术实战干货,技术在于积累和收藏,希望可以帮助到您,同时也希望获得您的支持和关注。架构开源地址:https://gitee.com/msxyspringboot整合Ftpserver参...

Linux和Windows下:Python Crypto模块安装方式区别

一、Linux环境下:fromCrypto.SignatureimportPKCS1_v1_5如果导包报错:ImportError:Nomodulenamed'Crypt...

Python 3 加密简介(python des加密解密)

Python3的标准库中是没多少用来解决加密的,不过却有用于处理哈希的库。在这里我们会对其进行一个简单的介绍,但重点会放在两个第三方的软件包:PyCrypto和cryptography上,我...

怎样从零开始编译一个魔兽世界开源服务端Windows

第二章:编译和安装我是艾西,上期我们讲述到编译一个魔兽世界开源服务端环境准备,那么今天跟大家聊聊怎么编译和安装我们直接进入正题(上一章没有看到的小伙伴可以点我主页查看)编译服务端:在D盘新建一个文件夹...

附1-Conda部署安装及基本使用(conda安装教程)

Windows环境安装安装介质下载下载地址:https://www.anaconda.com/products/individual安装Anaconda安装时,选择自定义安装,选择自定义安装路径:配置...

如何配置全世界最小的 MySQL 服务器

配置全世界最小的MySQL服务器——如何在一块IntelEdison为控制板上安装一个MySQL服务器。介绍在我最近的一篇博文中,物联网,消息以及MySQL,我展示了如果Partic...

如何使用Github Action来自动化编译PolarDB-PG数据库

随着PolarDB在国产数据库领域荣膺桂冠并持续获得广泛认可,越来越多的学生和技术爱好者开始关注并涉足这款由阿里巴巴集团倾力打造且性能卓越的关系型云原生数据库。有很多同学想要上手尝试,却卡在了编译数据...

面向NDK开发者的Android 7.0变更(ndk android.mk)

订阅Google官方微信公众号:谷歌开发者。与谷歌一起创造未来!受Android平台其他改进的影响,为了方便加载本机代码,AndroidM和N中的动态链接器对编写整洁且跨平台兼容的本机...

信创改造--人大金仓(Kingbase)数据库安装、备份恢复的问题纪要

问题一:在安装KingbaseES时,安装用户对于安装路径需有“读”、“写”、“执行”的权限。在Linux系统中,需要以非root用户执行安装程序,且该用户要有标准的home目录,您可...

OpenSSH 安全漏洞,修补操作一手掌握

1.漏洞概述近日,国家信息安全漏洞库(CNNVD)收到关于OpenSSH安全漏洞(CNNVD-202407-017、CVE-2024-6387)情况的报送。攻击者可以利用该漏洞在无需认证的情况下,通...

Linux:lsof命令详解(linux lsof命令详解)

介绍欢迎来到这篇博客。在这篇博客中,我们将学习Unix/Linux系统上的lsof命令行工具。命令行工具是您使用CLI(命令行界面)而不是GUI(图形用户界面)运行的程序或工具。lsoflsof代表&...

幻隐说固态第一期:固态硬盘接口类别

前排声明所有信息来源于网络收集,如有错误请评论区指出更正。废话不多说,目前固态硬盘接口按速度由慢到快分有这几类:SATA、mSATA、SATAExpress、PCI-E、m.2、u.2。下面我们来...

新品轰炸 影驰SSD多款产品登Computex

分享泡泡网SSD固态硬盘频道6月6日台北电脑展作为全球第二、亚洲最大的3C/IT产业链专业展,吸引了众多IT厂商和全球各地媒体的热烈关注,全球存储新势力—影驰,也积极参与其中,为广大玩家朋友带来了...