Docker网络一-默认网络
本文介绍docker默认的几种网络模式,docker如何与主机通讯使其能访问外网和被外网访问。
一、docker 容器网络
在默认情况下,docker 会在 host 机器上新创建一个 docker0 的 bridge。他就相当于虚拟的交换机,容器默认连到这台交换机上。他的ip是docker自动分配的,例如 172.17.0.1/16
ocker有四种网络模式,可以在创建容器时通过--net=xxx
指定。
docker网络模式:
- host模式,使用–net=host指定。
- container模式,使用–net=container:NAME_or_ID指定。
- none模式,使用–net=none指定。
- bridge模式,使用–net=bridge指定,默认设置。
docker@default:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
3f23887bb1f1 bridge bridge local
ed0d1bb36689 host host local
282e264b5397 none null local
1.1 host模式
容器将不会虚拟出自己的网卡,配置自己的IP,而是使用宿主机的IP和端口,和宿主机共用一个Network Namespace。
在主机上执行ip addr
:
docker@default:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether fa:4f:21:84:56:5a brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:98:f5:92 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe98:f592/64 scope link
valid_lft forever preferred_lft forever
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:b0:03:fb brd ff:ff:ff:ff:ff:ff
inet 192.168.99.100/24 brd 192.168.99.255 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:feb0:3fb/64 scope link
valid_lft forever preferred_lft forever
6: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:c6:59:e8:1d brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:c6ff:fe59:e81d/64 scope link
valid_lft forever preferred_lft forever
以host网络起一个容器:
docker@default:~$ docker run --rm --net=host busybox ip addr
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: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop qlen 1000
link/ether fa:4f:21:84:56:5a brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 08:00:27:98:f5:92 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe98:f592/64 scope link
valid_lft forever preferred_lft forever
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 08:00:27:b0:03:fb brd ff:ff:ff:ff:ff:ff
inet 192.168.99.100/24 brd 192.168.99.255 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:feb0:3fb/64 scope link
valid_lft forever preferred_lft forever
6: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
link/ether 02:42:c6:59:e8:1d brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:c6ff:fe59:e81d/64 scope link
valid_lft forever preferred_lft forever
可以看到,容器的网络分配环境和主机一样。而其他的如进程和文件与主机隔离。所以这种模式不能在主机和容器同事启动监听80端口的nginx。
1.2 container模式
就是和已存在的容器公用一个网络。
1.3 none模式
none模式下,Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
1.4 bridge模式
Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP,并将一个主机上的Docker容器连接到一个虚拟网桥上。
二、网桥bridge
启动一个容器
docker run -d busybox top
991022faafc3af764e4f5bd2ba159722661f5b1599fb9d45b3d791b9e9cacf18
再使用网桥管理命令
$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242d986d02b no veth2b11e37
发现多了一个interfaces (veth2b11e37)。再看ip addr 查看主机上的网络,多了以下内容,这个interface链接到了docker0,并没有看到为容器分配的ip。
18: vethf1a68f5@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 3e:26:8a:c4:19:94 brd ff:ff:ff:ff:ff:ff
inet6 fe80::3c26:8aff:fec4:1994/64 scope link
valid_lft forever preferred_lft forever
进入容器查看:
docker@default:~$ docker exec -it f1525a68b2d6 sh
/ # ip addr
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
17: eth0@if18: <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 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever
/ #
可以看到eth0@if18上有一个ip:172.17.0.2/16,和前面看到的docker0在同一个网段。
所以,容器要访问外网,大概是这样的:eth0@if18–> veth2b11e37—>docker0—>主机eth0。
三、访问容器
外网无法直接访问容器提供服务,只能容器端口映射到主机,通过(主机:映射端口)访问容器内服务。