基于早已经掌握的知识后,辅助性的一些笔记
Docker网络
查看默认网络 docker network ls
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过 Container-IP 访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。
桥接模式(Bridge)
- 不能删除正在被容器使用的网络。
- 默认网络名
bridge
是 Docker 自带的,如果容器没有显式指定网络,Docker 会使用它。 - 删除默认桥接网络会导致新容器无法使用默认网络启动,除非指定其他网络。
删除默认的桥接网络: docker network rm bridge
- 可以创建自己的桥接网络:
docker network create \
--driver bridge \
my-bridge
然后启动容器时指定网络:
docker run --network my-bridge ...
进阶
1️⃣ 基本命令结构
docker network create \
--driver bridge \
--subnet <子网CIDR> \
--ip-range <容器可分配IP范围> \
--gateway <网关IP> \
<网络名称>
--driver bridge
:使用桥接网络--subnet
:整个网段,例如192.168.100.0/24
--ip-range
:容器可分配 IP 范围,例如192.168.100.10/28
--gateway
:网关 IP,Docker 默认会选择子网第一个可用 IP<网络名称>
:自定义网络名称
2️⃣ 排除特定 IP
Docker 不直接支持“排除 IP”,但是你可以通过 调整 --ip-range
来间接实现。例如:
- 子网:
192.168.100.0/24
- 想排除
192.168.100.1~192.168.100.9
- 那么可以把 IP 分配范围设为
192.168.100.10/28
或192.168.100.10/24
并保证容器不会使用排除的 IP
3️⃣ 示例
docker network create \
--driver bridge \
--subnet 192.168.100.0/24 \
--ip-range 192.168.100.20/28 \
--gateway 192.168.100.1 \
my_custom_bridge
解释:
- 子网:
192.168.100.0/24
→ 整个 192.168.100.0 ~ 192.168.100.255 - 容器可用 IP:
192.168.100.20 ~ 192.168.100.35
(/28 表示 16 个 IP) - 网关:
192.168.100.1
- 网络名称:
my_custom_bridge
注意:如需指定宿主系统内接口名称,则使用--opt com.docker.network.bridge.name=mybr0
MacVLAN模式(较高性能)
这是一个和桥接(bridge)完全不同的网络模式,适合你的容器需要直接在物理网络上拥有独立 IP的场景,比如你希望容器像一台真实的物理机一样,可以被局域网内其他设备访问。
1️⃣ macvlan 的基本概念
- 原理:macvlan 会给每个容器分配一个独立的 MAC 地址,并通过宿主机的物理网卡把容器直接暴露到局域网。
- 优点:
- 容器可以被局域网其他设备直接访问。
- 支持与宿主机不同的 IP 网段。
- 避免 NAT,性能更高。
- 缺点:
- 容器与宿主机默认无法直接通信(宿主机需要额外配置 macvlan 的子接口)。
- 需要宿主机网络配置配合,通常只在局域网内使用。
2️⃣ macvlan 的模式
Docker macvlan 有几种模式(mode):
模式 | 描述 |
---|---|
bridge | 容器通过物理网卡与局域网桥接,默认模式。 |
private | 容器之间隔离,不能相互通信。 |
vepa | VEPA 模式,需要交换机支持。 |
passthru | 物理网卡只绑定一个容器。 |
最常用的是 bridge
模式。
3️⃣ 创建 macvlan 网络命令
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
--ip-range=192.168.1.128/25 \
-o parent=eth0 \
my_macvlan_net
参数 | 说明 |
---|---|
-d macvlan | 网络驱动类型 |
--subnet | macvlan 网络子网 |
--gateway | 网关 IP |
--ip-range | 容器可分配 IP 范围 |
-o parent | 绑定的宿主机物理网卡(必须存在) |
my_macvlan_net | 自定义网络名 |
4️⃣ 排除 IP 和自定义 IP
- 容器默认会从
--ip-range
自动分配 IP。 - 可以指定容器 IP:
docker run --net my_macvlan_net --ip 192.168.1.150 ...
- 如果想排除某些 IP,只需调整
--ip-range
不包含这些 IP,或者手动分配。
5️⃣ 宿主机与 macvlan 容器通信 (重点!!!)
宿主机默认无法直接访问 macvlan 网络,需要创建 macvlan 子接口:
ip link add macvlan_host link eth0 type macvlan mode bridge
ip addr add 192.168.1.200/24 dev macvlan_host
ip link set macvlan_host up
192.168.1.200
:宿主机在 macvlan 子网中的 IP- 这样宿主机就可以和容器通信了。
- 这是临时方法,方便测试或临时通信!!!
6️⃣ 注意事项
- 必须指定物理网卡,虚拟网卡或 bond 可能需要额外处理。
- macvlan 容器和宿主机默认隔离,需要子接口才能通信。
- 不要把容器 IP 与 DHCP 分配冲突,最好使用静态 IP 或受控 IP 范围。
- MTU 可以通过
--opt com.docker.network.driver.mtu=xxxx
调整。
永久创建方法(CentOS/Ubuntu 示例)
CentOS 7/8 (使用 nmcli
)
nmcli connection add type macvlan \
con-name macvlan_host \
ifname macvlan_host \
dev eth0 \
mode bridge \
ip4 192.168.1.200/24 gw4 192.168.1.1
nmcli connection up macvlan_host
- 系统启动时会自动激活。
MacVLAN实战
在宿主机创建docker macvlan
docker network create \
-d macvlan \
--subnet 10.1.1.0/24 \
--gateway 10.1.1.1 \
--ip-range=10.1.1.0/25 \
-o parent=ens33 \
mvlan
在宿主机创建此macvlan的桥接口
nmcli con add type macvlan
con-name mvlan_sys
ifname mvlan_sys
dev ens33
mode bridge
ip4 10.1.1.1/24
nmcli con up mvlan_sys
宿主机开启ip转发
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
添加 iptables NAT 规则
iptables -t nat -A POSTROUTING -s 10.1.1.0/24 -o ens33 -j MASQUERADE
iptables -A FORWARD -s 10.1.1.0/24 -o ens33 -j ACCEPT
iptables -A FORWARD -d 10.1.1.0/24 -m state --state ESTABLISHED,RELATED -i ens33 -j ACCEPT
service iptables save
✅ 总结
- 容器 macvlan 网络:
10.1.1.0/24
,网关指向宿主机子接口10.1.1.1
- 宿主机创建 macvlan 子接口
mvlan_host
,IP10.1.1.1
- 宿主机开启 IP 转发,并对
10.1.1.0/24
做 MASQUERADE - 容器通过宿主机 NAT 上网,同时可以 ping 宿主机子接口