docker网络

Docker网络模式详解与容器通信

Docker 网络概述

Docker 安装时会自动在 Docker host 上创建三种网络,可以使用 docker network ls 命令查看:

bash 复制代码
# 查看 Docker 网络列表
[root@hrz3 ~]# docker network ls
NETWORK ID     NAME            DRIVER    SCOPE
805a6f455d21   bridge          bridge    local
07c01c3977b9   host            host      local
668ce77d8fd9   none            null      local

三种默认网络类型:

  • none 网络:无网络连接
  • host 网络:共享主机网络栈
  • bridge 网络:默认使用的桥接网络

None 网络

顾名思义,none 网络就是没有任何网络连接的封闭环境。

创建并使用 none 网络

bash 复制代码
# 拉取 busybox 镜像(小型 Linux 环境)
[root@hrz3 ~]# docker pull busybox

# 创建使用 none 网络的容器
[root@hrz3 ~]# docker run --name test1 -it --rm --network=none busybox:latest

# 在容器内查看网络接口
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever

特点说明:

  • 容器内只有 loopback 接口 (lo)
  • 完全网络隔离,无法通过网络访问
  • 适用于安全性要求高、不需要联网的应用场景

Host 网络

使用 host 网络的容器共享 Docker host 的网络栈。

创建并使用 host 网络

bash 复制代码
# 创建使用 host 网络的容器
[root@hrz3 ~]# docker run --name test2 -it --rm --network=host busybox:latest

# 查看容器网络配置(与宿主机相同)
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:0c:29:b0:df:de brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.30/24 brd 192.168.100.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::f794:4cdf:8dc2:f40/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

端口冲突示例

bash 复制代码
# 检查宿主机 80 端口占用情况
[root@hrz3 ~]# systemctl restart httpd.service 
[root@hrz3 ~]# ss -tpln | grep 80
LISTEN    0     128      :::80          :::*          users:(("httpd",pid=110359,fd=4)...

# 尝试启动使用 host 网络的 nginx 容器(会因端口冲突失败)
[root@hrz3 ~]# docker run --name nginx -itd --network=host nginx:latest       
6c1b69b0b927627a77651a58adcd0faab18a6c218cc5d781573723321991e4ec

# 检查容器状态(启动失败)
[root@hrz3 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

特点说明:

  • 容器直接使用宿主机的网络接口
  • 端口绑定直接映射到宿主机
  • 可能产生端口冲突问题

Bridge 网络

Docker 安装时会创建名为 docker0 的 Linux 网桥,默认容器都连接到该网桥。

查看网桥信息

bash 复制代码
# 安装网桥管理工具
[root@hrz3 ~]# yum install bridge-utils -y

# 查看网桥信息
[root@hrz3 ~]# brctl show 
bridge name     bridge id               STP enabled     interfaces
br-98ee29092a6b         8000.02423e67826f       no
docker0         8000.0242c68c95ae       no
virbr0          8000.52540021eff1       yes             virbr0-nic

创建容器并观察网络变化

终端一:创建容器

bash 复制代码
# 创建新容器(默认使用 bridge 网络)
[root@hrz3 ~]# docker run --name test3 -it --rm busybox 

# 在容器内查看网络配置
/ # ip a
...
47: eth0@if48: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

终端二:观察宿主机网络变化

bash 复制代码
# 查看宿主机网络接口
[root@hrz3 ~]# ip a
...
48: veth7bc4c9b@if47: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 02:af:73:43:25:da brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::af:73ff:fe43:25da/64 scope link 
       valid_lft forever preferred_lft forever

# 再次查看网桥,可以看到新接口已连接
[root@hrz3 ~]# brctl show                 
bridge name     bridge id               STP enabled     interfaces
br-98ee29092a6b         8000.02423e67826f       no
docker0         8000.0242c68c95ae       no              veth7bc4c9b
virbr0          8000.52540021eff1       yes             virbr0-nic

查看默认 bridge 网络配置

bash 复制代码
# 查看默认 bridge 网络的详细配置
[root@hrz3 ~]# docker network inspect bridge
......
        "Options": null,
        "Config": [
            {
                "Subnet": "172.17.0.0/16",
                "Gateway": "172.17.0.1"
            }
        ]
......

网络配置说明:

  • 子网:172.17.0.0/16
  • 网关:172.17.0.1
  • Docker 自动从该子网为容器分配 IP

自定义 Bridge 网络

创建自定义 bridge 网络

bash 复制代码
# 创建自定义 bridge 网络
[root@hrz3 ~]# docker network create --driver bridge --subnet 172.16.1.0/24 --gateway 172.16.1.1 testnetwork
abb2b722e12d17885bbd8756b89c3bc0ec6670bf31e51350dde232e825fd3507

# 查看网络列表
[root@hrz3 ~]# docker network ls
NETWORK ID     NAME            DRIVER    SCOPE
abb2b722e12d   testnetwork     bridge    local

# 查看新创建的网络接口
[root@hrz3 ~]# ip a
......
49: br-abb2b722e12d: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:77:91:d1:70 brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.1/24 brd 172.16.1.255 scope global br-abb2b722e12d
       valid_lft forever preferred_lft forever

使用自定义网络创建容器

bash 复制代码
# 创建容器并指定使用自定义网络和静态 IP
[root@hrz3 ~]# docker run --name test -it --rm --network=testnetwork --ip 172.16.1.2 busybox 

# 查看容器网络配置
/ # ip a
...
50: eth0@if51: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:10:01:02 brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.2/24 brd 172.16.1.255 scope global eth0
       valid_lft forever preferred_lft forever

多网络容器通信

不同网络容器通信问题

bash 复制代码
# 终端一:创建使用默认 bridge 网络的容器 a1
[root@hrz3 ~]# docker run --name a1 -it --rm busybox
/ # ip a
54: eth0@if55: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
bash 复制代码
# 终端二:创建使用自定义网络的容器 a2,并连接多个网络
[root@hrz3 ~]# docker run --name a2 -itd --network=testnetwork --ip 172.16.1.5 busybox

# 为容器 a2 添加默认 bridge 网络连接
[root@hrz3 ~]# docker network connect bridge a2

# 进入容器 a2 查看网络配置
[root@hrz3 ~]# docker exec -it a2 sh
/ # ip a
56: eth0@if57: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:10:01:05 brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.5/24 brd 172.16.1.255 scope global eth0
       valid_lft forever preferred_lft forever
58: eth1@if59: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth1
       valid_lft forever preferred_lft forever

网络连通性测试

bash 复制代码
# 在容器 a2 中 ping 容器 a1
/ # ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.057 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.061 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.062 ms

容器访问方式

基于 IP 地址访问

bash 复制代码
# 创建容器 a1(自定义网络)
[root@hrz3 ~]# docker run --name a1 -it --rm --network=testnetwork busybox
/ # ip a
60: eth0@if61: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:10:01:02 brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.2/24 brd 172.16.1.255 scope global eth0
       valid_lft forever preferred_lft forever

# 创建容器 a2(同一网络),通过 IP 访问 a1
[root@hrz3 ~]# docker run --name a2 -it --rm --network=testnetwork busybox
/ # ping 172.16.1.2
PING 172.16.1.2 (172.16.1.2): 56 data bytes
64 bytes from 172.16.1.2: seq=0 ttl=64 time=0.170 ms
64 bytes from 172.16.1.2: seq=1 ttl=64 time=0.088 ms

基于容器名访问(DNS 解析)

bash 复制代码
# 在同一网络中使用容器名进行访问
/ # ping a2
PING a2 (172.16.1.3): 56 data bytes
64 bytes from 172.16.1.3: seq=0 ttl=64 time=0.025 ms
64 bytes from 172.16.1.3: seq=1 ttl=64 time=0.063 ms

DNS 特性说明:

  • Docker 1.10+ 版本内置 DNS 服务器
  • 自动将容器名解析为 IP 地址
  • 仅在使用自定义 bridge 网络时可用

Joined 容器

Joined 容器共享同一个网络栈,可以通过 127.0.0.1 直接通信。

bash 复制代码
# 创建基础容器 a3
[root@hrz3 ~]# docker run --name a3 -itd --network testnetwork  busybox 

# 创建 joined 容器 a4,共享 a3 的网络栈
[root@hrz3 ~]# docker run --name a4 -it --rm --network container:a3 busybox

# 在 a4 中访问 a3
/ # ping a3
PING a3 (172.16.1.2): 56 data bytes
64 bytes from 172.16.1.2: seq=0 ttl=64 time=0.028 ms
64 bytes from 172.16.1.2: seq=1 ttl=64 time=0.059 ms

容器与外部网络通信

容器访问外部网络

bash 复制代码
# 在容器中访问外部网络
[root@hrz3 ~]# docker run --name a4 -it --rm --network container:a3 busybox 
/ # ping www.baidu.com
PING www.baidu.com (103.235.46.102): 56 data bytes
64 bytes from 103.235.46.102: seq=0 ttl=127 time=227.597 ms
64 bytes from 103.235.46.102: seq=2 ttl=127 time=201.077 ms

网络地址转换(NAT)过程:

  1. 容器发送 Ping 包:172.17.0.3 → www.baidu.com
  2. docker0 收到包,发现目标为外网,交给 NAT 处理
  3. NAT 将源地址换成主机 IP:192.168.100.30 → www.baidu.com
  4. Ping 包从主机网卡发送到目标地址

外部访问容器

方法一:使用 host 网络
bash 复制代码
# 使用 host 网络,容器服务直接绑定到宿主机网络
方法二:端口映射(推荐)
bash 复制代码
# 启动容器并将容器端口映射到宿主机端口
[root@hrz3 ~]# docker run --name web1 -itd -p 80:80 httpd 
d85baf83b1da6381446f88a4db5b17d962b209259f9c481db4921748a35e51a4

# 通过宿主机 IP 访问容器服务
[root@hrz3 ~]# curl 192.168.100.30:80
<html><body><h1>It works!</h1></body></html>

总结

  1. none 网络:封闭网络,容器无法在网络层被访问,适用于高安全性需求
  2. host 网络:容器共享宿主机网络栈,网络配置与宿主机完全一致
  3. 默认 bridge 网络:无法使用容器名进行互访
  4. 自定义 bridge 网络:支持容器名解析和互访
  5. 网络连通性:只有在同一网络中的容器才能互相通信
  6. 外部访问:可通过 host 网络或端口映射实现外部访问容器服务

关键点:

  • 使用自定义 bridge 网络可实现容器名解析
  • 多网络容器可通过网络连接实现跨网络通信
  • 端口映射是最常用的外部访问容器方式
相关推荐
独行soc3 小时前
2025年渗透测试面试题总结-105(题目+回答)
网络·python·安全·web安全·adb·渗透测试·安全狮
卓码软件测评4 小时前
【第三方网站代码登记测试_HTTP头语法代码详解】
网络·网络协议·http·架构·web
奇树谦4 小时前
Fast DDS 默认传输机制详解:共享内存与 UDP 的智能选择
网络·网络协议·udp·fastdds
缘华工业智维10 小时前
工业设备预测性维护:能源成本降低的“隐藏钥匙”?
大数据·网络·人工智能
安当加密10 小时前
达梦数据库TDE透明加密解决方案:构建高安全数据存储体系
网络·数据库·安全
wuxuanok12 小时前
WebSocket —— 在线聊天室
网络·websocket·网络协议
安当加密12 小时前
构建高安全堡垒机登录体系:RADIUS + 动态口令实践
网络·安全
风清再凯13 小时前
06_k8s数据持久化
云原生·容器·kubernetes
做运维的阿瑞13 小时前
Docker 从入门到精通:完整通关笔记
笔记·docker·容器