Docker --网络
Docker 网络模式
- bridge
- host
- none
- container自建网络
╭─root@du-z ~
╰─➤ docker network ls
NETWORK ID NAME DRIVER SCOPE
977b6e78e6b4 bridge bridge local
570c3afdc47e host host local
28739b66a1db none null local
bridge网络
简介:
- Docker 容器默认使用 bridge 模式的网络
- docker网络隔离基于网络命名空间(network namespaces),在物理机上创建docker容器时会为每一个docker容器分配网络命名空间,并且把容器IP桥接到物理机的虚拟网桥上
bridge网络拓扑图
拓展:运行容器Host宿主机,需要开启转发
# echo 1 > /proc/sys/net/ipv4/ip_forward
或者
# vim /etc/sysctl.conf
...
net.ipv4.ip_forward = 1
...
# sysctl -p
实验
第一步:查看
╭─root@du-z ~
╰─➤ ip a
...
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:21:ec:47:33 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:21ff:feec:4733/64 scope link
valid_lft forever preferred_lft forever
# 发现宿主机host上默认被创建了一个名为 docker0 的网桥,其 IP 为 172.17.0.1/16
╭─root@du-z ~
╰─➤ ip route
...
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1
...
# 这条路由信息表示所有目的 IP 为 172.17.0.0/16 的数据包都会从 docker0 网卡发出
第二步:创建一个容器并查看
╭─root@du-z ~
╰─➤ docker run -it busybox sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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
39: eth0@if40: <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
/ #
/ #
/ # ip route
default via 172.17.0.1 dev eth0 ##容器的默认网关正是宿主机的 docker0 网卡
172.17.0.0/16 dev eth0 scope link src 172.17.0.2
/ #
第三步:查看宿主机网卡信息
╭─root@du-z ~
╰─➤ ip a
...
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:21:ec:47:33 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:21ff:feec:4733/64 scope link
valid_lft forever preferred_lft forever
40: vethf2b2bd7@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP
link/ether 4a:10:f1:1f:e7:b7 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::4810:f1ff:fe1f:e7b7/64 scope link
valid_lft forever preferred_lft forever
# 查看docker0网桥信息
╭─root@du-z ~
╰─➤ brctl show docker0
bridge name bridge id STP enabled interfaces
docker0 8000.024221ec4733 no vethf2b2bd7
#发现Host宿主机产生的一个接口vethf2b2bd7 接在docker0网桥上
第四步:查看Host宿主机iptables规则
╭─root@du-z ~
╰─➤ iptables -L -t nat |grep 172
MASQUERADE all -- 172.17.0.0/16 anywhere
# Host 通过iptables为Container做伪装,
第五步:分析
- Host 上的接口vethf2b2bd7 与 容器上的eth0网卡形成一对veth pair,进行通信
- Host 通过iptables为Container做伪装,容器可以访问外网,但是外网不能访问容器
- Container容器的网络底层依靠iptables
- Docker0 的 IP 地址作为所连接的容器的默认网关地址
- 拓展:默认的bridge网络中的Container可以通过容器名通信(DNS通信)
none网络
简介:
- 此模式下创建容器是不会为容器配置任何网络参数的,如:容器网卡、IP、通信路由等,全部需要自己去配置
- none网络没有网络,只有lo即本地地址,没有任何的网卡
- none网络的应用场景主要是用于对于安全性要求比较高的场景
╭─root@du-z ~
╰─➤ docker run -it --network=none busybox sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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
/ #
# 登陆none网络 --network=none
host网络
简介:
- 此模式创建的容器没有自己独立的网络命名空间,是和物理机共享一个Network Namespace
- 连接到host的网络的容器共享主机的网络栈,容器的网络配置与宿主机完全一样
- 此模式网络安全性较差
╭─root@du-z ~
╰─➤ docker run -it --network=host busybox sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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:c5:89:84 brd ff:ff:ff:ff:ff:ff
inet 192.168.137.128/24 brd 192.168.137.255 scope global dynamic ens33
valid_lft 1598sec preferred_lft 1598sec
inet6 fe80::4602:8204:488f:7b36/64 scope link
valid_lft forever preferred_lft forever
3: ens37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 00:0c:29:c5:89:8e brd ff:ff:ff:ff:ff:ff
inet 192.168.137.3/24 brd 192.168.137.255 scope global ens37
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
link/ether 02:42:21:ec:47:33 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:21ff:feec:4733/64 scope link
valid_lft forever preferred_lft forever
/ #
container自建网络
实验拓扑图
第一步:自创建两个网络bridge1 bridge2
╭─root@du-z ~
╰─➤ docker network create bridge1
829b1800a2f2178a74f3b7a7a059d1513f45c9d16991804266f8813b83babed0
╭─root@du-z ~
╰─➤ docker network create bridge2
2677fa818ac12c81cf5e79d928f1320c4a8cf9595b594b68df2f6b77980b7841
╭─root@du-z ~
╰─➤ docker network ls
NETWORK ID NAME DRIVER SCOPE
977b6e78e6b4 bridge bridge local
829b1800a2f2 bridge1 bridge local
2677fa818ac1 bridge2 bridge local
570c3afdc47e host host local
28739b66a1db none null local
# 查看Host宿主机的网桥
╭─root@du-z ~
╰─➤ brctl show
bridge name bridge id STP enabled interfaces
br-2677fa818ac1 8000.024295cb711d no
br-829b1800a2f2 8000.024204b0933d no
docker0 8000.024221ec4733 no
#Host创建了两个网桥
第二步:在三个终端启动三个容器
# Container1
╭─root@du-z ~
╰─➤ docker run --name Container1 --network bridge1 -it busybox sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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
49: eth0@if50: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ #
# Container2
╭─root@du-z ~
╰─➤ docker run --name Container2 --network bridge2 -it busybox sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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
51: eth0@if52: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:13:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
valid_lft forever preferred_lft forever
# Container3
╭─root@du-z ~
╰─➤ docker run --name Container3 --network bridge2 -it busybox sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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
53: eth0@if54: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:13:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.3/16 brd 172.19.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ # ping 172.19.0.2
PING 172.19.0.2 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.511 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.162 ms
64 bytes from 172.19.0.2: seq=2 ttl=64 time=0.144 ms
/ #
/ # ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2): 56 data bytes
^C
--- 172.18.0.2 ping statistics ---
12 packets transmitted, 0 packets received, 100% packet loss
# Container2 与 Container3 在一个网络中可以通信
# Container1与 Container3 不在一个网络中不可以通信
第四步:将Container2 添加到bridge1 网络中
╭─root@du-z ~
╰─➤ docker network connect bridge1 Container2
第五步:查看Container2容器的网卡信息
/ #
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
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
51: eth0@if52: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:13:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
valid_lft forever preferred_lft forever
55: eth1@if56: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.3/16 brd 172.18.255.255 scope global eth1
valid_lft forever preferred_lft forever
/ #
# 实质:就是为Container2添加一块网卡;bridge1网络在Host宿主机中形成的网桥上添加一新接口,形成一对 veth pair
第六步:验证Container2的网络连通性
/ # ping Container1 #自创的网络不支持DNS通信,不做DNS转换
^C
/ # ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.803 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.160 ms
/ # ping Container3
^C
/ # ping 172.19.0.3
PING 172.19.0.3 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.663 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=1.208 ms
结论总结:
- 自创的网络不支持DNS通信,不做DNS转换
- 为容器添加新网络就是为Container2添加一块网卡与bridge1网络在Host宿主机中网桥上的接口形成一对 veth pair
拓展:
自创建的网络时可以自定义网段及网关
docker network create --subnet=10.0.0.0/16 --gateway=10.0.0.1 -d bridge bridge1
要想外网访问容器需要做端口映射
# docker run -P|-p
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步