Docker 网络

Docker 容器在创建时,虽然会通过 Linux 的命名空间完成与宿主机进程的网络隔离,但是却有没有办法通过宿主机的网络与整个互联网相连,这会对 Docker 的应用产生限制。为此,每一个使用 docker run 启动的容器都会为其分配单独的网络命名空间。Docker 提供了四种不同的网络模式,分别是 Host、Container、None 和 Bridge 模式。

Docker0是安装Docker时自动创建的虚拟网桥,所有容器的网络都通过Docker0与主机网络接口通讯。 容器之间通讯使用的是TCP协议,而不是socket,每个容器有自己的IP地址

1.Host

在 Host 模式下,容器直接使用宿主机的网络栈,不进行网络隔离。这意味着容器的网络配置与宿主机完全相同,容器内的应用程序可以直接使用宿主机的 IP 地址和端口。

如果在宿主机上访问 http://127.0.0.1:80,实际上访问的是容器内的 Nginx 服务。

Host 模式适用场景:需要容器与宿主机共享网络栈,适用于对网络性能要求较高的场景,此时不

需要端口映射,容器直接可以使用宿主机的端口。

2.Container

在 Container 模式下,新创建的容器会共享另一个容器的网络命名空间。这意味着两个容器的网络

配置完全相同,它们可以通过 localhost 直接通信。

通过 --network container:nginx 参数,Alpine 容器就可共享 nginx 容器的网络命名空间,通过

localhost 就可直接访问 nginx 容器的网络服务。

Container 模式适用场景:需要多个容器共享同一个网络栈,适用于需要紧密协作的容器组。例如,

一个容器运行应用程序,另一个容器运行日志收集器,两者就可以通过 localhost 直接通信。

3.None

在 None 模式下,容器不会配置任何网络栈,即容器内没有网络接口,无法与外界通信。

使用 --network none 参数启动一个 Alpine 容器,在容器内执行 ip addr 命令,可以看到容器内

没有任何网络接口。

容器无法与外界通信,也无法被外界访问。

None 模式适用场景:适用于不需要网络通信的场景,例如只进行本地数据处理或测试;安全性要

求较高的场景,确保容器与外界完全隔离。

4.Bridge

Bridge 模式是 Docker 的默认网络模式。在这种模式下,Docker 会为每个容器创建一个虚拟网络 接口,并将其连接到 Docker 的虚拟网桥(通常是 docker0)。容器通过这个网桥与宿主机和其他容器进行通信。

使用 -p 8080:80 参数启动一个 Nginx 容器,将容器的 80 端口映射到宿主机的 8080 端口。Docker 会自动创建一个虚拟网络接口,并将其连接到 docker0 网桥。通过 curl http://localhost:8080 就能 访问容器内的 Nginx 服务。

Bridge 模式适用于大多数需要容器与宿主机或其他容器通信的场景。通过端口映射,容器内的服 务可以被外部网络访问。

主机到网桥转接到转发到这里面,这个页面就打开了

在 Bridge 模式下,Docker 除了分配隔离的网络命名空间之外,还会为所有的容器设置 IP 地址。

当 Docker 服务器在主机上启动之后会创建新的虚拟网桥 docker0,随后在该主机上启动的全部服务在默认情况下都会与该网桥相连。

启动三个容器

可以看出,docker0 为每一个容器分配一个新的 IP 地址并将 docker0 的 IP 地址设置为默认的网关, 其拓扑关系如下图所示:

比如,mysql 容器的 ip 是 172.17.0.4,Docker 网桥规则会将从任意源发送到当前机器 3306 端口的 TCP 包都转发到 172.17.0.4:3306 所在的地址上,如果在当前机器上直接 ping 这个 IP 地址就会发现它是可以访问到:

从上述操作我们可以知道 Docker 是如何将容器的内部的端口暴露出来并对数据包进行转发的,当 有 Docker 容器需要将服务暴露给宿主机器时,docker0 就为容器分配一个 ip 地址,同时向 iptables追加一条新的转发规则,Docker 网络转发规则如下图所示:

使用 mysqladmin 客户机在宿主机器的命令行中访问 127.0.0.1:3306 地址时,会经过 iptables 的 预路由(NAT PREROUTING)将该 ip 定向到了 mysql 容器的 ip 地址 172.17.0.4,重定向过的数据包此时就可以通过 iptables 中的过滤转发(FILTER FORWARD)配置,最终在后路由(NAT POSTROUTING)阶段将容器 ip 地址伪装成主机的 127.0.0.1,到这里,虽然从外面看起来请求的 是 127.0.0.1:3306,但实际上请求的已经是 Docker 容器暴露出的端口了。
在/sys/class/net 目录可以查看到以上的所有网络设备:

Docker 通过 Linux 的命名空间实现了网络的隔离,进而又通过 iptables 进行了数据包的转发,从而实现了 Docker 容器独立和完整的网络功能。

相关推荐
Harm灬小海1 小时前
【云计算学习之路】学习Centos7系统:服务搭建(NFS)
linux·运维·服务器·学习·云计算
Harm灬小海1 小时前
【云计算学习之路】学习Centos7系统-权限管理
linux·运维·服务器·学习·云计算
木雷坞1 小时前
vLLM 服务启动慢排查:NAS 模型目录、Docker 镜像和 GPU Runtime
docker·容器·vllm
xhbh6661 小时前
MC端口映射完全教程:路由器虚拟服务器配置+防火墙放行+内网穿透备用方案
运维·服务器·网络·网络协议·tcp/ip·智能路由器·流量端口转发
weixin_426150701 小时前
AI辅助Oracle容量规划:告别拍脑袋扩容
运维·数据库·人工智能·oracle
艾莉丝努力练剑1 小时前
【Linux网络】Linux 网络编程:HTTP(四)从手写服务器到生产级 Nginx 与 cpp-httplib 实战
linux·运维·服务器·网络·c++·nginx·http
@insist1231 小时前
信息安全工程师-安全实施:等保 2.0 框架、核心机制与运维体系
运维·安全·软考·信息安全工程师·软件水平考试
Harm灬小海2 小时前
【云计算学习之路】学习Centos7系统:Linux磁盘管理
linux·运维·服务器·学习·云计算
艾莉丝努力练剑2 小时前
【Linux网络】Linux 网络编程:HTTP(三)HTTP 协议原理
linux·运维·服务器·网络·c++·http