Docker / 命令文档

Docker 网络核心(面试向)

$ docker 7 个章节 Linux 命令详解

概述

本篇是「Docker 面试核心」系列第五篇,讲容器网络:四种网络模式的取舍、默认 bridge 与自定义网络的 DNS 差异、端口映射背后的 NAT 规则、容器间通信方案。网络题最考验「知其所以然」,本篇全部结论有实测输出支撑(Docker 26.1.4)。

四种网络模式

模式命令参数网络栈典型场景
bridge--network bridge(默认)独立 netns + docker0 网桥绝大多数应用
host--network host直接用宿主机对网络性能极致敏感
none--network none只有 loopback安全隔离/自定义网络
container--network container:X复用指定容器的 netns边车模式(如 k8s Pod)
$ docker network ls --format "table {{.Name}}\t{{.Driver}}"
NAME     DRIVER
bridge   bridge
host     host
none     null

面试要点:

  • 四种模式的本质差别是「网络命名空间给谁」:bridge 单独给、host 不给(直接用宿主机的)、none 只给 loopback、container 借别的容器的
  • k8s Pod 内多容器共享网络的实现就是 container 模式:业务容器与 pause 边车共用一个 netns
  • host 模式没有端口映射(-p 无效),性能最好但端口冲突需自己管、隔离最弱

默认 bridge 与自定义 network(DNS 差异,必考)

默认 bridge 只有 IP 互通、没有内置 DNS;自定义网络自带 DNS,可按容器名/网络别名直接互访。

# 默认 bridge:按 IP 通,按名字不通
$ docker run -d --name kb-b1 busybox:latest sleep 300
$ docker run --rm busybox:latest ping -c1 -W2 172.17.0.2 >/dev/null && echo 通
通
$ docker run --rm busybox:latest ping -c1 -W2 kb-b1 >/dev/null 2>&1 || echo 不通
不通

# 自定义网络:按容器名直接通
$ docker network create kbnet
$ docker run -d --name kb-a --network kbnet busybox:latest sleep 300
$ docker run --rm --network kbnet busybox:latest ping -c2 kb-a
PING kb-a (172.18.0.2): 56 data bytes
--- kb-a ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss

面试要点:

  • 「为什么自定义网络能解析容器名」:Docker 内置 DNS 服务器(127.0.0.11),注册容器名与 IP 的映射;默认 bridge 出于历史兼容不启用
  • 自定义网络还支持 --network-alias 一个名字多个容器(天然负载均衡雏形)
  • 同一自定义网络内全部互通,跨网络默认隔离 —— 用网络划分业务边界是容器安全的基本手段

端口映射与 NAT

-p 宿主:容器 通过 iptables 的 DNAT 规则把宿主机端口转进容器,实测:

# 容器内起 httpd,映射 8080 -> 80
$ docker run -d --name kb-http -p 8080:80 busybox:latest \
    sh -c 'mkdir -p /www && echo "hello from container" > /www/index.html && httpd -f -p 80 -h /www'

$ docker port kb-http
80/tcp -> 0.0.0.0:8080

$ curl -s -m 3 http://127.0.0.1:8080/
hello from container

# DNAT 规则(iptables -t nat -L DOCKER 可见)
DNAT dpt:80 -> to:172.17.0.3:80

面试要点:

  • 数据路径:宿主机收到目标端口 8080 → PREROUTING/DOCKER 链 DNAT 改写目的地址为容器 IP:80 → 经 docker0 转发进容器;回程由 MASQUERADE 处理
  • -p 127.0.0.1:8080:80 只绑回环(不对公网暴露),生产暴露服务务必指定绑定地址
  • host 模式与 macvlan 等方案绕过 NAT 获得原生性能;k8s 里由 kube-proxy/Service 接管这层规则

容器之间通信

同一网络:容器 IP 或 DNS 名直接互访(bridge 二层互通)。跨网络:默认隔离,需要显式连接或走宿主机端口。

# container 模式:与指定容器共享同一个网络命名空间(边车模式)
$ docker exec kb-b1 cat /proc/net/dev          # 容器 A 的网卡
$ docker run --rm --network container:kb-b1 busybox:latest cat /proc/net/dev
# 两者输出完全一致 —— 共享同一网络命名空间
网卡列表完全一致(共享同一网络命名空间)

# none 网络:只有 loopback,用于最大隔离或自建网络
$ docker run --rm --network none busybox:latest cat /proc/net/dev
lo

面试要点:

  • 同自定义网络内通信路径:容器 A → docker0/kbnet 网桥二层直达,无需 NAT;跨宿主机要 overlay(VXLAN)或 macvlan
  • 访问宿主机服务用 host.docker.internal(Docker Desktop)或宿主机 docker0 IP(Linux 默认 172.17.0.1)
  • 通信受限排查顺序:两容器是否同网络 → DNS 解析是否命中(ping 名字)→ iptables DOCKER-USER 链是否有拦截

host 与 none 模式实测补充

# host 模式:hostname 与宿主机一致(共享网络栈的直接证据)
$ hostname
VM-0-17-centos
$ docker run --rm --network host busybox:latest hostname
VM-0-17-centos

# container 模式:netns 完全复用,可视为「同一台网络主机上的两个进程」

面试要点:

  • host 模式容器与宿主机共享全部端口空间,netstat 看到的是同一张表 —— 排障方便、冲突也要自己负责
  • none + 自建网络栈(如给容器配 Veth/策略路由)是高级网络定制的基础
  • 安全基线:不必要的服务避免 host 模式;不信任的镜像用 none 或独立网络隔离

高频面试题速答

问题一句话答案
四种网络模式区别bridge 独立 netns 接网桥、host 复用宿主机栈、none 只有回环、container 借用别的容器的 netns
默认 bridge 为什么 ping 不通容器名默认 bridge 未启用内置 DNS,自定义网络才有 127.0.0.11 域名解析
-p 背后做了什么iptables nat 表 DOCKER 链写 DNAT 规则,把宿主机端口转发到容器 IP:端口
容器间怎么通信同网络走网桥二层直达 + 内置 DNS 按名访问;跨网络需显式连接或经宿主机端口
k8s Pod 里容器怎么共享网络container 模式思想:业务容器与 pause 容器共用一个网络命名空间
容器怎么访问宿主机服务Docker Desktop 用 host.docker.internal;Linux 用 docker0 网关 IP(默认 172.17.0.1)
host 模式的风险与宿主机共享端口空间和全部网络接口,无隔离、易冲突、-p 无效
跨主机容器通信方案overlay 网络(VXLAN 隧道)、macvlan/路由方案,或交给 k8s CNI 处理

同分类 · 其他命令文档