点击学习开源企业 Docker 镜像仓库 Harbor 软件 教程。
下面将通过具体的示例来分析 Dokcer 中的 bridge、host 和 none 网络模式。
Docker 运行容器时默认使用 bridge 模式。下面将分析 Docker 的 bridge 模式:
(1)使用 ifconfig 命令查看宿主机的网络接口信息,如下:
root@hxvm:~# ifconfig docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:c7:7b:2a:35 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.27.114.197 netmask 255.255.240.0 broadcast 172.27.127.255 inet6 fe80::3c5f:557c:2b76:dca8 prefixlen 64 scopeid 0x20<link> ether 00:15:5d:ff:0a:00 txqueuelen 1000 (Ethernet) RX packets 411 bytes 82130 (82.1 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 464 bytes 75215 (75.2 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 184 bytes 18181 (18.1 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 184 bytes 18181 (18.1 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
上述输出信息中,有三个网络接口信息,其中 docker0 网络接口是成功安装 Docker 服务后自动安装的网络桥接口。
(2)使用命令启动一个名为 centos 的容器,并在容器内部使用 ip link show 命令查看网络接口信息,如下:
root@hxvm:~# docker run -it --name centos centos /bin/bash // 容器的网络接口信息 [root@185467f8550c /]# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
上述输出信息中,多了一个 eth0@if9 网络接口。
(3)再次返回宿主机,宿主机执行命令查看宿主机网络接口信息,如下:
hx@hxvm:~$ ifconfig docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:c7ff:fe7b:2a35 prefixlen 64 scopeid 0x20<link> ether 02:42:c7:7b:2a:35 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 34 bytes 4677 (4.6 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.27.114.197 netmask 255.255.240.0 broadcast 172.27.127.255 inet6 fe80::3c5f:557c:2b76:dca8 prefixlen 64 scopeid 0x20<link> ether 00:15:5d:ff:0a:00 txqueuelen 1000 (Ethernet) RX packets 64435 bytes 88621497 (88.6 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 34189 bytes 3144873 (3.1 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 272 bytes 29064 (29.0 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 272 bytes 29064 (29.0 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vethd42395d: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::445c:25ff:feab:12e2 prefixlen 64 scopeid 0x20<link> ether 46:5c:25:ab:12:e2 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 25 bytes 3032 (3.0 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
上述输出信息中,多了一个名为 vethd42395d 的网络接口信息。
到这里为止,我们找到了三个网络接口,分别如下:
docker0 是一个网桥(bridge)设备。它创建了一个虚拟的网络环境,用于连接 Docker 容器。当 Docker 容器启动时,它们可以连接到这个 docker0 网桥,从而在这个虚拟网络中实现相互通信。
eth0@if9 是容器内部的一个虚拟网络设备,只是将名称改为了 eth0。注意:eth0@if9 名称表示eth0 接口与另一个接口(编号为 if9)存在某种关联。在 Linux 网络设备命名中,这种形式可能出现在虚拟网络设备或者网络设备的特殊连接关系中。
vethd42395d 当使用 docker run 运行容器时,由 Docker 自动创建的虚拟网络接口。
继续在宿主机上执行命令,查看宿主机网络接口列表信息,如下:
hx@hxvm:~$ ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 00:15:5d:ff:0a:00 brd ff:ff:ff:ff:ff:ff 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 02:42:c7:7b:2a:35 brd ff:ff:ff:ff:ff:ff 9: vethd42395d@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default link/ether 46:5c:25:ab:12:e2 brd ff:ff:ff:ff:ff:ff link-netnsid 0
上述输出信息中,最左边的序号(1、2、3、9)是网络接口索引编号,这个编号是 Linux 系统内核分配给每个网络接口的一个唯一标识符,用于在系统内部识别和管理网络接口。
根据上面的信息,加上 eth0@if9 接口名称,是不是可以猜测 eth0@if9 和 vethd42395d@if8 是一对虚拟网络设备,如下图:
到这里,我们已经知道 Docker 如何使用 bridge 网络模式,以及相关的网络接口。
下面还有一些命令,可以进一步查看网络信息:
(1)使用命令查看指定容器的网络信息,例如,查看名为 centos 容器的详细信息:
root@hxvm:~# docker inspect centos [ { "Id": "185467f8550c40ed59757228414d26475725e99f48597a448663406d2ca2efe2", "Created": "2024-09-12T05:49:37.579501352Z", "Path": "/bin/bash", "Args": [], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 3053, "ExitCode": 0, "Error": "", "StartedAt": "2024-09-12T05:49:37.767389387Z", "FinishedAt": "0001-01-01T00:00:00Z" }, //... "Name": "/centos", // 容器名称 //...容器网络设置信息 "NetworkSettings": { "Bridge": "", "SandboxID": "36019ba05665ad501c902e0e78359485ef67ee82d1c17d3f85bbb0788afc5f17", "SandboxKey": "/var/run/docker/netns/36019ba05665", "Ports": {}, "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "17b055fda792997461f1521b388bc81775a21f111dfb9c10268ea19174b87a2e", "Gateway": "172.17.0.1", // 网关地址 "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.2", // IP地址 "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:02", // MAC地址 "Networks": { // 桥接模式 "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null, "NetworkID": "1da6aa9ec785d8cdfb1e4288168f9dec039adb2809203a757fe25e4ef10e5f94", "EndpointID": "17b055fda792997461f1521b388bc81775a21f111dfb9c10268ea19174b87a2e", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "DNSNames": null } } } } ]
(2)使用 命令查看 Docker 中名为 bridge 的网络模式的详细信息:
// 查看 docker 网络模式列表 root@hxvm:~# docker network ls NETWORK ID NAME DRIVER SCOPE 1da6aa9ec785 bridge bridge local 23f832eeba6e host host local f83cddfed9c2 none null local // 查看指定网络模式的详细信息 root@hxvm:~# docker network inspect bridge [ { "Name": "bridge", "Id": "1da6aa9ec785d8cdfb1e4288168f9dec039adb2809203a757fe25e4ef10e5f94", "Created": "2024-09-12T13:32:56.8984669+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, // 该网络模式下面的容器信息,当前仅挂载了名为centos容器 "Containers": { "185467f8550c40ed59757228414d26475725e99f48597a448663406d2ca2efe2": { "Name": "centos", "EndpointID": "17b055fda792997461f1521b388bc81775a21f111dfb9c10268ea19174b87a2e", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", // 这个 bridge 的名称,是不是很熟悉,docker0 "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]
(3)使用 brctl show 命令查看 Linux 系统中查的网桥(bridge)信息,系统默认没有安装 brctl 命令,需要手动安装:
a、使用 apt install bridge-utils 安装 brctl 命令
root@hxvm:~# apt install bridge-utils Reading package lists... Done Building dependency tree... Done ... Unpacking bridge-utils (1.7-1ubuntu3) ... Setting up bridge-utils (1.7-1ubuntu3) ... Processing triggers for man-db (2.10.2-1) ...
b、查看网桥信息
root@hxvm:~# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242c77b2a35 no vethd42395d
其中:
bridge name - 网桥在系统中的名称,如上述示例中的 docker0。用户可以根据需求自定义网桥名称,它用于在网络配置和管理中标识特定的网桥设备。
bridge id - 网桥标识,一个唯一的标识符,用于在网络中区分不同的网桥。它由两部分组成,前面的8000 是一个固定的十六进制数,表示这是一个以太网网桥;后面的 0242c77b2a35 是网桥的 MAC 地址或者是基于 MAC 地址计算得到的值。这个标识在网络的链路层通信和一些网络管理操作(如生成树协议相关操作,如果启用了 STP)中可能会被用到。
STP enabled - 是否启用了生成树协议(Spanning Tree Protocol,STP)。STP 用于防止网络中的环路,确保网络的稳定性。如果显示为 yes,表示网桥启用了 STP;如果为 no,则表示未启用。
interfaces - 连接的接口,列出了连接到该网桥的网络接口。上面示例中,vethd42395d 连接到了 docker0 网桥。
(4)使用命令显示 Linux 网桥(bridge)的转发数据库(Forwarding Database,FDB)中的条目信息。网桥的转发数据库主要存储了 MAC 地址与网桥端口(连接到网桥的网络接口)之间的映射关系。例如:
root@hxvm:~# bridge fdb show ... 02:42:c7:7b:2a:35 dev docker0 vlan 1 master docker0 permanent 02:42:c7:7b:2a:35 dev docker0 master docker0 permanent 46:5c:25:ab:12:e2 dev vethd42395d vlan 1 master docker0 permanent 46:5c:25:ab:12:e2 dev vethd42395d master docker0 permanent ...
分析“02:42:c7:7b:2a:35 dev docker0 master docker0 permanent”:
02:42:c7:7b:2a:35 是一个 MAC 地址。
dev docker0 表明这个 MAC 地址所属的设备是 docker0。
master docker0 表示这个 MAC 地址对应的设备(即docker0本身)是 docker0 的主设备。这看起来有点像一种自引用的关系,实际上这可能表示这个 MAC 地址是docker0设备在自身的网络管理和数据转发逻辑中的一个重要标识。例如,在docker0进行数据转发时,它可能会根据这个 MAC 地址以及其他相关信息来处理发往自身或者从自身发出的数据帧。
permanent 表示这种关联是永久性的。这意味着在正常的网络运行过程中,这个 MAC 地址与docker0设备的这种关系是相对固定的,不会轻易被修改或删除。这种永久性有助于网络的稳定运行,并且在网络管理和故障排查时,可以依据这种固定的关系来确定网络设备的状态和功能。
使用 docker run 命令启动 centos 容器,并且通过 --network 选项指定网络模式为 host,如下:
(1)启动一个容器:
root@hxvm:~# docker run -it --name my_centos --network host centos /bin/bash
(2)进入容器内部,在容器内部使用 ip link show 命令查看网络接口信息:
[root@hxvm /]# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 00:15:5d:ff:0a:00 brd ff:ff:ff:ff:ff:ff 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:c7:7b:2a:35 brd ff:ff:ff:ff:ff:ff
(3)最后,返回宿主机执行 ip link show 命令查看宿主机的网络接口信息:
root@hxvm:~# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 00:15:5d:ff:0a:00 brd ff:ff:ff:ff:ff:ff 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:c7:7b:2a:35 brd ff:ff:ff:ff:ff:ff
从上述输出的信息可知,在容器内部和宿主机执行 ip link show 命令的输出信息一致,这可以证明二者采用了同一个网络栈。
使用 docker run 命令启动 centos 容器,并且通过 --network 选项指定网络模式为 none,如下:
root@hxvm:~# docker run -it --name my_centos --network none centos /bin/bash [root@cf2394999ad2 /]# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
上面命令中,在容器内部使用 ip link show 命令查看 Linux 系统中的网络接口信息。这些信息包括网络接口的名称、状态、MAC 地址、最大传输单元(MTU)等。
从输出可知,仅有一个名为 lo 的回路接口,也就意味着当前容器没有网卡,不能访问任何网络。
紧接着,我们在宿主机上运行 ip link show 命令查看网络接口信息,如下:
root@hxvm:~# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 00:15:5d:ff:0a:00 brd ff:ff:ff:ff:ff:ff 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:c7:7b:2a:35 brd ff:ff:ff:ff:ff:ff
从输出可知,宿主机中没有创建新的网络接口(其中,lo 是回路网络接口,eth0 是物理以太网卡,docker0 是 Docker 创建的网桥)。
点击学习开源企业 Docker 镜像仓库 Harbor 软件 教程。