Docker 学习笔记:网络篇

发布时间:2026/7/16 10:28:33

Docker 学习笔记:网络篇 Docker 学习笔记网络篇本笔记承接容器资源限制部分深入讲解 Docker 的原生网络模型涵盖 none/host/bridge 三种网络、自定义网络、容器间通信IP/DNS/joined 容器以及容器与外部世界的双向访问。13. Docker 网络概览Docker 安装时会自动创建三个网络bash$ docker network ls NETWORK ID NAME DRIVER SCOPE a1b809382f0d bridge bridge local 6ad21ed9eaf1 host host local 4e31521b27c6 none null local14. none 和 host 网络14.1 none 网络none网络意味着容器只有lo回环接口完全封闭。bash$ docker run -it --networknone busybox / # ifconfig lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0适用场景对安全性要求极高且无需网络的应用例如只生成随机密码的离线程序。14.2 host 网络使用--networkhost时容器与宿主机共享同一个网络命名空间网络配置完全一致。bash$ docker run -it --networkhost busybox / # ip a # 能看到宿主机所有网卡 / # hostname docker # 宿主机的主机名优点性能最佳无网络地址转换开销。缺点端口冲突风险高灵活性下降。典型应用需要直接配置宿主机网络的网络插件如 Flannel或以容器形式运行的监控代理。15. bridge 网络默认15.1 原理Docker 在安装时创建一个名为docker0的 Linux bridge相当于软件交换机默认新建的容器都会连接到该网桥。bash$ brctl show bridge name bridge id STP enabled interfaces docker0 8000.02420be905a5 no创建容器后会自动生成一对veth pair虚拟网卡一端在容器内eth0另一端挂在docker0上如vethddb2744。bash$ docker run -itd --name busybox1 busybox $ brctl show bridge name bridge id STP enabled interfaces docker0 8000.02420be905a5 no vethddb2744容器内查看bash$ docker exec -it busybox1 sh / # ip a 24: eth0if25: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc noqueue inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0同时宿主机上会看到对应的另一端bash$ ip a | grep vethddb2744 25: vethddb2744if24: ...docker0网桥的 IP 为172.17.0.1/16容器自动从该子网获取 IP。15.2 查看 bridge 网络详情bash$ docker network inspect bridge Subnet: 172.17.0.0/16, Gateway: 172.17.0.116. 自定义网络用户定义 bridge与默认 bridge 相比自定义网络提供内置 DNS 解析支持容器名称直接通信。16.1 创建自定义 bridge 网络bash# 自动分配子网 $ docker network create --driver bridge my_net # 查看新建网桥 $ brctl show bridge name bridge id STP enabled interfaces br-89f7bc11b602 8000.0242194d039e no docker0 8000.02420be905a5 no vethddb274416.2 指定子网与网关bash$ docker network create --driver bridge \ --subnet 172.22.16.0/24 \ --gateway 172.22.16.1 \ my_net2宿主机上会生成同名网桥br-ID并配置网关 IPbash$ ip a | grep br-ec761bc51778 27: br-ec761bc51778: NO-CARRIER,... mtu 1500 ... inet 172.22.16.1/24 brd 172.22.16.255 scope global br-ec761bc5177816.3 使用自定义网络并指定静态 IPbash$ docker run -it --networkmy_net2 --ip 172.22.16.8 --name busybox3 busybox / # ip a 30: eth0if31: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 ... inet 172.22.16.8/24 ...注意只有创建网络时指定了--subnet才能使用--ip分配静态 IP。17. 理解容器间的连通性17.1 同一自定义网络内互通bash$ docker exec -it busybox2 sh / # ping -c3 172.22.16.8 # 同一 my_net2 中的另一个容器 64 bytes from 172.22.16.8: seq0 ttl64 time0.197 ms / # ping -c3 172.22.16.1 # 网关 64 bytes from 172.22.16.1: seq0 ttl64 time0.149 ms同一网络中的容器与网关之间均可通信。17.2 不同网络之间的隔离默认 bridge 网络与自定义 my_net2 网络属于不同的网桥Docker 通过 iptables 规则DOCKER-ISOLATION阻止了它们之间的双向流量。bash$ docker exec -it busybox2 sh / # ping -c3 172.17.0.2 # busybox1 的 IP --- 172.17.0.2 ping statistics --- 3 packets transmitted, 0 packets received, 100% packet loss17.3 将容器接入多个网络bash$ docker network connect my_net2 busybox1此时busybox1会多出一块eth1网卡获得my_net2的 IP从而可以与busybox2通信。18. 容器间通信的三种方式18.1 通过 IP 通信两个容器只要处于同一网络即可直接通过 IP 互通。18.2 通过 Docker DNS Server仅限用户自定义网络。容器可以用--name指定的名称直接相互访问。bash$ docker run -it --networkmy_net2 --name bbox1 busybox $ docker run -it --networkmy_net2 --name bbox2 busybox $ docker exec -it bbox2 sh / # ping -c3 bbox1 PING bbox1 (172.22.16.2): 56 data bytes 64 bytes from 172.22.16.2: seq0 ttl64 time0.177 ms默认 bridge 网络不支持DNS 名称解析。18.3 joined 容器共享网络栈通过--networkcontainer:目标容器名让新容器与目标容器共享同一个网络命名空间。bash$ docker run -d --name web1 httpd $ docker run -it --networkcontainer:web1 busybox / # ip a # 与 web1 的 IP 和 MAC 完全相同 / # wget 127.0.0.1 # 直接通过 localhost 访问 web1 的服务适用场景需要高效 loopback 通信或监控其他容器的网络流量。19. 容器访问外部世界19.1 默认行为容器无需额外配置即可访问外网如ping www.baidu.com这是通过NAT网络地址转换实现的。19.2 NAT 原理解析在宿主机 iptables 的 NAT 表中存在类似规则text-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE当容器向外发包时数据包经过docker0网桥匹配该规则后被 MASQUERADE即将源 IP 替换为宿主机外网接口的 IP从而能够访问外网并接收回复。可以用tcpdump抓包观察bash# 在宿主机两个窗口分别抓包 $ tcpdump -i docker0 -n icmp $ tcpdump -i ens160 -n icmp # 容器中 ping 外网 $ docker run -it busybox ping www.baidu.comdocker0上看到的源 IP 是容器 IP如172.17.0.2ens160上看到的源 IP 已经被替换为宿主机 IP如192.168.108.3020. 外部世界访问容器通过端口映射让外部流量到达容器内部服务。20.1 动态端口映射bash$ docker run -d -p 80 httpd $ docker port 容器ID 80/tcp - 0.0.0.0:32768访问http://宿主机IP:32768即可访问容器内的 HTTP 服务。20.2 指定固定端口bash$ docker run -d -p 8080:80 httpd $ curl http://192.168.108.30:8080 htmlbodyh1It works!/h1/body/html每个映射的端口宿主机都会启动一个docker-proxy进程负责将流量转发到容器。bash$ ps aux | grep docker-proxy原理流程以0.0.0.0:8080-80/tcp为例docker-proxy监听宿主机 8080 端口。外部请求到达宿主机 8080 端口。docker-proxy将请求转发到容器的 IP 和 80 端口。容器处理请求并原路返回。21. 知识点速查表21.1 Docker 原生网络模式对比网络模式配置方式网络隔离性能典型场景none--networknone完全无网络仅 lo不适用离线安全任务host--networkhost无共享宿主机网络栈最高高性能网络、网络插件bridge默认独立网络命名空间通过 NAT 访问外网较好一般容器应用自定义 bridge--networkmy_net同 bridge但内建 DNS好需要名称解析的多容器应用21.2 容器间通信方式速查方式适用网络关键命令/配置IP 直连任意同一网络ping 容器IP内置 DNS仅用户自定义网络--name 名称直接ping 容器名joined 容器所有网络--networkcontainer:目标容器共享网络栈21.3 容器与外部通信速查方向实现技术关键命令容器 → 外部NAT (MASQUERADE)无需配置自动生效外部 → 容器端口映射 docker-proxy-p 宿主机端口:容器端口21.4 常用网络管理命令命令功能docker network ls列出所有网络docker network inspect 网络名查看网络详细信息子网、网关、容器等docker network create --driver bridge 网络名创建自定义网络docker network connect 网络名 容器名将容器接入指定网络docker network disconnect 网络名 容器名将容器从网络断开docker port 容器名查看容器端口映射情况brctl show查看宿主机 Linux bridge 信息需安装 bridge-utils本笔记至此覆盖 Docker 网络的单机场景后续将进入存储卷与日志监控部分。

相关新闻