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 容器独立和完整的网络功能。

相关推荐
FED_AF29 分钟前
Linux运维“邪修”功法之通配符
linux·运维
YOLO数据集集合1 小时前
风机叶片表面损伤检测数据集 | 风机叶片 表面损伤 污渍检测 无人机巡检 风电运维9119期
运维·人工智能·计算机视觉·目标跟踪·无人机·智慧城市·电力巡检
j7~1 小时前
【Linux网络编程】四十七.《Linux IO 模型详解:阻塞 IO、非阻塞 IO 与 IO 多路转接(select)》
linux·运维·网络·select·非阻塞io·阻塞io·i/o多路连接
分布式存储与RustFS2 小时前
用RustFS给Harbor当S3存储后端
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
泡海椒2 小时前
趋势分析报表:jquick-pdf折线图PDF生成实战
java·大数据·运维·服务器·前端·pdf
vipxieliang2 小时前
Docker vs Podman vs containerd:容器运行时全景
docker·容器
vipxieliang2 小时前
数据持久化方案:卷、挂载、权限与备份恢复
docker·容器
丸子君君2 小时前
【以麒麟服务器时间为准,定时请求时间同步】
运维·服务器·单片机
vipxieliang2 小时前
Compose 生产级配置:从 demo 到可上线
docker
vipxieliang2 小时前
容器原理揭秘:namespace、cgroup 与镜像分层
docker·容器