一篇文章讲明白 Docker 网络原理
一篇文章讲明白 Docker 网络原理
作者:蛮荆 2023-04-06 08:37:24网络 网络管理 Docker 原生网络是基于 Linux 的 网络命名空间(net namespace) 和 虚拟网络设备(veth pair)实现的。当 Docker 进程启动时,会在宿主机上创建一个名称为 docker0 的 虚拟网桥,在该宿主机上启动的 Docker 容器会连接到这个虚拟网桥上。概述
Docker原生网络是基于 Linux 的网络命名空间(net namespace) 和虚拟网络设备(veth pair)实现的。当Docker进程启动时,会在宿主机上创建一个名称为docker0的虚拟网桥,在该宿主机上启动的Docker容器会连接到这个虚拟网桥上。
$ ifconfig# 输出如下docker0: ... mtu 1500inet 172.17.0.1netmask 255.255.0.0broadcast 172.17.255.255...虚拟网桥的工作方式和物理交换机类似,宿主机上所有的容器通过虚拟网桥连接在一个二层网络中。
从docker0子网中分配一个 IP 给容器使用,并设置docker0的 IP 地址为容器的默认网关。在宿主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡), 另一端放在宿主机中,以vethxxx类似的名字命名, 并将这个网络设备连接到docker0网桥中。
Docker 会自动配置 iptables 规则和配置 NAT,便于连通宿主机上的docker0网桥,完成这些操作之后,容器就可以使用它的eth0虚拟网卡,来连接其他容器和访问外部网络。
Docker中的网络接口默认都是虚拟的接口,Linux 在内核中通过数据复制实现接口之间的数据传输,可以充分发挥数据在不同Docker容器或容器与宿主机之间的转发效率, 发送接口发送缓存中的数据包,将直接复制到接收接口的缓存中,无需通过物理网络设备进行交换。
# 查询主机上 veth 设备$ ifconfig | grep veth*veth06f40aa: ...vethfdfd27a:图片来源: https://www.suse.com/c/rancher_blog/introduction-to-container-networking/
虚拟网桥docker0通过 iptables 配置与宿主机器上的网卡相连,符合条件的请求都会通过 iptables 转发到docker0, 然后分发给对应的容器。
# 查看 docker 的 iptables 配置$ iptables -t nat -L# 输出如下Chain PREROUTING (policy ACCEPT)target prot opt source destinationDOCKER all--anywhere anywhere ADDRTYPE match dst-type LOCALChain DOCKER (2 references)target prot opt source destinationRETURN all--anywhere anywhere网络驱动
Docker的网络子系统支持插拔式的驱动程序,默认存在多个驱动程序,并提供核心网络功能。
名称
描述
bridge
默认的网络设备,当应用程序所在的容器需要通信时使用
host
移除容器与宿主机之间的网络隔离,直接使用宿主机的网络
overlay
将多个容器连接,并使集群服务能够相互通信
ipvlan
使用户可以完全控制 IPv4 和 IPv6 寻址
macvlan
可以为容器分配 MAC 地址
none
禁用所有网络
Network plugins
通过 Docker 安装和使用第三方网络插件
图片来源: Docker——容器与容器云
Docker daemon 通过调用 libnetwork 提供的 API 完成网络的创建和管理等功能。libnetwork 中使用了 CNM 来完成网络功能, CNM 中主要有沙盒(sandbox)、端点(endpoint)和网络(network)3 种组件。
•沙盒:一个沙盒包含了一个容器网络栈的信息。一个沙盒可以有多个端点和多个网络,沙盒可以对容器的接口、路由和 DNS 设置等进行管理,沙盒的实现可以是 Linux network namespace、FreeBSD Jail或者类似的机制
•端点:一个端点可以加入一个沙盒和一个网络。一个端点只属于一个网络和一个沙盒,端点的实现可以是 veth pair、Open vSwitch 内部端口或者相似的设备
•网络:一个网络是一组可以直接互相联通的端点。一个网络可以包含多个端点,网络的实现可以是Linux bridge、VLAN 等
bridge 模式
bridge是默认的网络模式,为容器创建独立的网络命名空间,容器具有独立的网卡等所有的网络栈。使用该模式的所有容器都是连接到docker0 这个网桥, 作为虚拟交换机使容器可以相互通信,但是由于宿主机的 IP 地址与容器 veth pair 的 IP 地址不在同一个网段,所以为了和宿主机以外的网络通信, Docker 采用了端口绑定的方式,也就是通过 iptables 的 NAT,将宿主机上的端口流量转发到容器。
bridge模式已经可以满足 Docker 容器最基本的使用需求了,但是其与外界通信时使用 NAT,增加了通信的复杂性,在复杂场景下使用会有限制。
$ docker network inspect bridge# 输出如下 (节选部分信息)[{"Name": "bridge","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": null,"Config": [{"Subnet": "172.17.0.0/16","Gateway": "172.17.0.1"}]},"Containers": {# 使用 bridge 网络的容器列表},}]通过上面的输出可以看到,虚拟网桥 的 IP 地址就是bridge网络类型的网关地址。
我们可以从输出的Containers容器列表中找一个容器,查看其网络类型和配置:
$ docker inspect 容器ID# 输出如下 (节选部分信息)[..."NetworkSettings": {"Bridge": "","Gateway": "172.17.0.1","IPAddress": "172.17.0.4","Networks": {"bridge": {"Gateway": "172.17.0.1","IPAddress": "172.17.0.4",}}...]通过上面的输出可以看到,虚拟网桥 的 IP 地址就是bridge网络类型的容器的网关地址。
实现机制
在 iptables 做了 DNAT 规则,实现端口转发功能:
# iptables 配置查看$ iptables -t nat -vnL# 输出如下Chain PREROUTING (policy ACCEPT 37M packets, 2210M bytes)...0 0 DNAT tcp--!docker0 * 0.0.0.0/00.0.0.0/0tcp dpt:8080 to:172.17.0.4:80当容器需要将端口映射到宿主机时,Docker会自动为该容器分配一个 IP 地址,同时新增一个 iptables 规则。
host 模式
容器不会获得一个独立的网络命名空间,而是和宿主机共用一个。容器不会虚拟出自己的网卡,配置自己的IP等,而是直接使用宿宿主机的。但是容器的其他方面,如文件系统、进程列表等还是和宿宿主机隔离的,容器对外界是完全开放的,能够访问到宿主机,就能访问到容器。
host模式降低了容器与容器之间、容器与宿主机之间网络层面的隔离性,虽然有性能上的优势,但是引发了网络资源的竞争与冲突,因此适用于容器集群规模较小的场景。
启动一个网络类型为host的Nginx容器:
$ docker run -d --net host nginxUnable to find image 'nginx:latest' locallylatest: Pulling from library/nginx...f202870092fc40bc08a607dddbb2770df9bb4534475b066f45ea35252d6e76e2查看网络类型为host的容器列表:
$ docker network inspect host# 输出如下 (节选部分信息)[{"Name": "host","Scope": "local","Driver": "host","Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"Containers": { # 使用 host 网络的容器列表 "f202870092fc40bc08a607dddbb2770df9bb4534475b066f45ea35252d6e76e2": {"Name": "frosty_napier","EndpointID": "7306a8e4103faf4edd081182f015fa9aa985baf3560f4a49b9045c00dc603190","MacAddress": "","IPv4Address": "","IPv6Address": ""}},}]查看Nginx容器网络类型和配置:
$ docker inspect f202870092fc4# 输出如下 (节选部分信息)[..."NetworkSettings": {"Bridge": "","Gateway": "","IPAddress": "","Networks": {"host": {"Gateway": "","IPAddress": "",}}...]通过上面的输出可以看到,Nginx容器使用的网络类型是host,没有独立的 IP。
查看Nginx容器 IP 地址:
# 进入容器内部 shell$ docker exec -it f202870092fc4 /bin/bash# 安装 ip 命令$ apt update && apt install -y iproute2# 查看 IP 地址$ ip a# 输出如下1: lo:通过上面的输出可以看到,Nginx容器内部并没有独立的 IP,而是使用了宿主机的 IP。
查看宿主机的端口监听状态:
$ sudo netstat -ntpl# 输出如下Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program nametcp00 0.0.0.0:800.0.0.0:* LISTEN1378/nginx: mastertcp6 00 :::80 :::*LISTEN1378/nginx: master通过上面的输出可以看到,监听80端口的进程为nginx, 而不是docker-proxy。
none 模式
容器拥有自己的 Network Namespace,但是并不进行任何网络配置。也就意味着该容器没有网卡、IP、路由等信息,需要手动为容器添加网卡、配置 IP 等,none模式下的容器会完全隔离,容器中只有 lo 这个 loopback(回环网络)网卡用于进程通信。
none模式为容器做了最少的网络设置,在没有网络配置的情况下,通过自定义配置容器的网络,提供了最高的灵活性。
启动一个网络类型为host的Nginx容器:
$ docker run -d --net none nginxUnable to find image 'nginx:latest' locallylatest: Pulling from library/nginx...d2d0606b7d2429c224e61e06c348019b74cd47f0b8c85347a7cdb8f1e30dcf86
查看网络类型为none的容器列表:
$ docker network inspect none# 输出如下 (节选部分信息)[{"Name": "none","Scope": "local","Driver": "null","Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"Containers": { # 使用 none 网络的容器列表 "d2d0606b7d2429c224e61e06c348019b74cd47f0b8c85347a7cdb8f1e30dcf86": {"Name": "hardcore_chebyshev","EndpointID": "b8ff645671518e608f403818a31b1db34d7fce66af60373346ea3ab673a4c6b2","MacAddress": "","IPv4Address": "","IPv6Address": ""}},}]查看Nginx容器网络类型和配置:
$ docker inspect d2d0606b7d242# 输出如下 (节选部分信息)[..."NetworkSettings": {"Bridge": "","Gateway": "","IPAddress": "","Networks": {"none": {"Gateway": "","IPAddress": "",}}...]通过上面的输出可以看到,Nginx容器使用的网络类型是none,没有独立的 IP。
查看Nginx容器 IP 地址:
# 进入容器内部 shell$ docker exec -it d2d0606b7d242 /bin/bash# 访问公网链接$ curl -I "https://www.docker.com"curl: (6) Could not resolve host: www.docker.com# 为什么会报错呢? 这是因为当前容器没有网卡、IP、路由等信息,是完全独立的运行环境,所以没有办法访问公网链接。# 查看 IP 地址$ hostname -I# 没有任何输出,该容器没有 IP 地址查看宿主机的端口监听状态:
$ docker port d2d0606b7d242或者$ sudo netstat -ntpl | grep :80# 没有任何输出,Nginx 进程运行在容器中,端口没有映射到宿主机container 模式
与host模式类似,容器与指定的容器共享网络命名空间。这两个容器之间不存在网络隔离,但它们与宿主机以及其他的容器存在网络隔离。该模式下的容器可以通过 localhost 来访问同一网络命名空间下的其他容器,传输效率较高,且节约了一定的网络资源。在一些特殊的场景中非常有用,例如 k8s 的 Pod。
其他模式
出于篇幅考虑,这里不再赘述其他网络模式,感兴趣的读者可以根据文章末尾的引用连接自行阅读。
网络驱动概述
•当需要多个容器在同一台宿主机上进行通信时,使用bridge•当网络栈不应该与宿主机隔离,但是希望容器的其他方面被隔离时,使用host•当需要在不同宿主机上运行的容器进行通信时,使用overlay•当从虚拟机迁移或需要使容器看起来像物理宿主机时,使用Macvlan, 每个容器都有一个唯一的 MAC 地址•当需要将 Docker 与专门的网络栈集成,使用Third-partyDocker 和 iptables
如果在公网可以访问的服务器运行Docker,需要对应的iptables规则来限制访问主机上的容器或其他服务。
在 Docker 规则之前添加 iptables 规则
Docker 安装了两个名为DOCKER-USER和DOCKER的自定义iptables链,确保传入的数据包始终先由这两个链进行检查。
# 可以通过该命令查看$ iptables -L -n -v | grep -i dockerDocker的所有iptables规则都被添加到Docker链中,不要手动修改此链 (可能会引发问题)。如果需要添加在一些在Docker之前加载的规则,将它们添加到DOCKER-USER链中,这些规则应用于Docker自动创建的所有规则之前。
添加到FORWARD链中的规则在这些链之后进行检测,这意味着如果通过Docker公开一个端口,那么无论防火墙配置了什么规则,该端口都会被公开。如果想让这些规则在通过Docker暴露端口时仍然适用,必须将这些规则添加到DOCKER-USER链中。
限制到 Docker 主机的连接
默认情况下,允许所有外部 IP连接Docker主机,为了只允许特定的 IP 或网络访问容器,在DOCKER-USER过滤器链的顶部插入一个规则。
例如,只允许 192.168.1.1 访问:
# 假设输入接口为 eth0$ iptables -I DOCKER-USER -i eth0 ! -s 192.168.1.1 -j DROP也可以允许来自源子网的连接,例如,允许 192.168.1.0/24 子网的用户访问:
# 假设输入接口为 eth0$ iptables -I DOCKER-USER -i eth0 ! -s 192.168.1.0/24 -j DROP阻止 Docker 操作 iptables
在Docker引擎的配置文件/etc/docker/daemon.json设置iptables的值为false,但是最好不要修改,因为这很可能破坏Docker引擎的容器网络。
为容器设置默认绑定地址
默认情况下,Docker守护进程将公开0.0.0.0地址上的端口,即主机上的任何地址。如果希望将该行为更改为仅公开内部 IP 地址上的端口,则可以使用--ip 选项指定不同的IP地址。
集成到防火墙
如果运行的是Docker 20.10.0或更高版本,在系统上启用了iptables,Docker会自动创建一个名为docker的防火墙区域, 并将它创建的所有网络接口 (例如 docker0 ) 加入到docker区域,以允许无缝组网。
运行命令将docker接口从防火墙区域中移除:
firewall-cmd --znotallow=trusted --remove-interface=docker0 --permanentfirewall-cmd --reloadReference
•Networking overview[1]
•Networking tutorials[2]
•Docker and iptables[3]
•容器Docker详解[4]
•Introduction to Container Networking[5]
•docker 容器网络方案:calico 网络模型[6]
•Docker——容器与容器云[7]
引用链接
[1]Networking overview:https://docs.docker.com/network/[2]Networking tutorials:https://docs.docker.com/network/network-tutorial-standalone/[3]Docker and iptables:https://docs.docker.com/network/iptables/
[4]容器Docker详解:https://juejin.cn/post/6844903766601236487
[5]Introduction to Container Networking:https://www.suse.com/c/rancher_blog/introduction-to-container-networking/
[6]docker 容器网络方案:calico 网络模型:https://cizixs.com/2017/10/19/docker-calico-network/
[7]Docker——容器与容器云:https://book.douban.com/subject/26894736/
责任编辑:武晓燕 来源:洋芋编程 Docker网络命名空间推荐系统
微软Win11原版22H2下载_Win11GHOST 免 激活密钥 22H2正式版64位免费下载
语言:中文版系统大小:5.13GB系统类型:Win11微软Win11原版22H2下载_Win11GHOST 免 激活密钥 22H2正式版64位免费下载系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。Win11 64位 Office办公版(免费)优化 1、保留 Edge浏览器。 2、隐藏“操作中心”托盘图标。 3、保留常用组件(微软商店,计算器,图片查看器等)。 5、关闭天气资讯。
Win11 21H2 官方正式版下载_Win11 21H2最新系统免激活下载
语言:中文版系统大小:4.75GB系统类型:Win11Ghost Win11 21H2是微软在系统方面技术积累雄厚深耕多年,Ghost Win11 21H2系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。Ghost Win11 21H2是微软最新发布的KB5019961补丁升级而来的最新版的21H2系统,以Windows 11 21H2 22000 1219 专业版为基础进行优化,保持原汁原味,系统流畅稳定,保留常用组件
windows11中文版镜像 微软win11正式版简体中文GHOST ISO镜像64位系统下载
语言:中文版系统大小:5.31GB系统类型:Win11windows11中文版镜像 微软win11正式版简体中文GHOST ISO镜像64位系统下载,微软win11发布快大半年了,其中做了很多次补丁和修复一些BUG,比之前的版本有一些功能上的调整,目前已经升级到最新版本的镜像系统,并且优化了自动激活,永久使用。windows11中文版镜像国内镜像下载地址微软windows11正式版镜像 介绍:1、对函数算法进行了一定程度的简化和优化
微软windows11正式版GHOST ISO镜像 win11下载 国内最新版渠道下载
语言:中文版系统大小:5.31GB系统类型:Win11微软windows11正式版GHOST ISO镜像 win11下载 国内最新版渠道下载,微软2022年正式推出了win11系统,很多人迫不及待的要体验,本站提供了最新版的微软Windows11正式版系统下载,微软windows11正式版镜像 是一款功能超级强大的装机系统,是微软方面全新推出的装机系统,这款系统可以通过pe直接的完成安装,对此系统感兴趣,想要使用的用户们就快来下载
微软windows11系统下载 微软原版 Ghost win11 X64 正式版ISO镜像文件
语言:中文版系统大小:0MB系统类型:Win11微软Ghost win11 正式版镜像文件是一款由微软方面推出的优秀全新装机系统,这款系统的新功能非常多,用户们能够在这里体验到最富有人性化的设计等,且全新的柔软界面,看起来非常的舒服~微软Ghost win11 正式版镜像文件介绍:1、与各种硬件设备兼容。 更好地完成用户安装并有效地使用。2、稳定使用蓝屏,系统不再兼容,更能享受无缝的系统服务。3、为
雨林木风Windows11专业版 Ghost Win11官方正式版 (22H2) 系统下载
语言:中文版系统大小:4.75GB系统类型:雨林木风Windows11专业版 Ghost Win11官方正式版 (22H2) 系统下载在系统方面技术积累雄厚深耕多年,打造了国内重装系统行业的雨林木风品牌,其系统口碑得到许多人认可,积累了广大的用户群体,雨林木风是一款稳定流畅的系统,一直以来都以用户为中心,是由雨林木风团队推出的Windows11国内镜像版,基于国内用户的习惯,做了系统性能的优化,采用了新的系统
雨林木风win7旗舰版系统下载 win7 32位旗舰版 GHOST 免激活镜像ISO
语言:中文版系统大小:5.91GB系统类型:Win7雨林木风win7旗舰版系统下载 win7 32位旗舰版 GHOST 免激活镜像ISO在系统方面技术积累雄厚深耕多年,加固了系统安全策略,雨林木风win7旗舰版系统在家用办公上跑分表现都是非常优秀,完美的兼容各种硬件和软件,运行环境安全可靠稳定。win7 32位旗舰装机版 v2019 05能够帮助用户们进行系统的一键安装、快速装机等,系统中的内容全面,能够为广大用户
番茄花园Ghost Win7 x64 SP1稳定装机版2022年7月(64位) 高速下载
语言:中文版系统大小:3.91GB系统类型:Win7欢迎使用 番茄花园 Ghost Win7 x64 SP1 2022.07 极速装机版 专业装机版具有更安全、更稳定、更人性化等特点。集成最常用的装机软件,集成最全面的硬件驱动,精心挑选的系统维护工具,加上独有人性化的设计。是电脑城、个人、公司快速装机之首选!拥有此系统
相关文章
- CentOS 7.3.1611 系统安装配置图文教程
- None
- 开启win7的隐藏功能 虚拟WiFi和SoftAP(即虚拟无线AP)
- Win7下C盘大量文件占着内存哪些文件是可以删除
- Linux 系统内核的调试详解
- win10系统安装photoshop cs6教程
- 在Windows上制作CentOS自动安装的光盘的教程
- Ubuntu 15.10系统10月22日发布 采用Linux Kernel 4.2内核
- Win7开机出错没有动画变成绿色的滚动条怎么办?
- 在Linux服务器上安装配置socks5代理的教程
- Win10右键菜单怎么添加删除复制路径选项?
- 右击新建文件夹时出现win7资源管理器已经停止工作问题
- Win10一周年更新正式版14393已开放下载(含下载地址)
- MOM.exe是什么进程?是MOM.exe病毒吗?为什么运行?
- CentOS7 如何设置截图的快捷键?
- Win8.1系统中的任务管理器怎么打开 3种打开Win8.1任务管理器方法图解
- HP TPN-C116笔记本安装win7系统的方法分享
- Win8电话激活英语对话详解
热门系统
- 1华硕笔记本&台式机专用系统 GhostWin7 32位正式旗舰版2018年8月(32位)ISO镜像下载
- 2深度技术 Windows 10 x86 企业版 电脑城装机版2018年10月(32位) ISO镜像免费下载
- 3电脑公司 装机专用系统Windows10 x86喜迎国庆 企业版2020年10月(32位) ISO镜像快速下载
- 4雨林木风 Ghost Win7 SP1 装机版 2020年4月(32位) 提供下载
- 5深度技术 Windows 10 x86 企业版 六一节 电脑城装机版 版本1903 2022年6月(32位) ISO镜像免费下载
- 6深度技术 Windows 10 x64 企业版 电脑城装机版2021年1月(64位) 高速下载
- 7新萝卜家园电脑城专用系统 Windows10 x64 企业版2019年10月(64位) ISO镜像免费下载
- 8新萝卜家园 GhostWin7 SP1 最新电脑城极速装机版2018年8月(32位)ISO镜像下载
- 9电脑公司Ghost Win8.1 x32 精选纯净版2022年5月(免激活) ISO镜像高速下载
- 10新萝卜家园Ghost Win8.1 X32 最新纯净版2018年05(自动激活) ISO镜像免费下载
热门文章
常用系统
- 1深度旋风 Ghost XP SP3 快速装机版 2011.05 下载
- 2电脑公司Ghost Win10 鼠年纯净版X64位 v2023年01最新下载
- 3GHOST WIN8 X64 免激活专业版 V2017.01(64位) 下载
- 4萝卜家园 GHOST XP SP3 完美装机版 V2018.09 下载
- 5雨林木风 Ghost XP SP3 快速装机版 YN2012.6 [NTFS] 下载
- 6萝卜家园 GHOST WIN7 SP1 X86 欢度元旦版 V2018.01 (32位) 下载
- 7新萝卜家园 Ghost XP SP3系统 电脑城极速纯净版 2019年10月 ISO镜像高速下载
- 8萝卜家园 ghost win11 64位 特选高速版 v2023.01系统最新下载
- 9雨林木风Ghost Win10 快速纯净版X64 v2023.01下载
- 10电脑公司Ghost Win10 好用专业版x64位 v2023.02最新免费下载