docker网络 docker安装后默认的三种网络为none、host、bridge。none :没有任何网路,没有任何网卡。安全性要求高并且不需要联网的应用可以使用 none 网络。host :连接到host网络的容器共享docker宿主机的网络,容器的网络配置、hostname与docker宿主机完全一致。bridge :桥接网络,使用最多,容器默认使用的网络。
1 2 3 4 5 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE a245b3871ac7 bridge bridge local 4b615d9327ee host host local 05e237730870 none null local
在启动容器的时候可以使用--network=none
来指定使用的网络
bridge网络 安装docker时会创建docker0的网桥,容器默认使用的都是这个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242b1443650 no #此时是没有容器使用docker0 ~]# docker run -it -d busybox ef8acee7abadee73a33c8ded047e7f57af8aaaf85a8bd6035fb271ee8ae99fb2 ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242b1443650 no veth6e01edd ~]# docker run -it -d --name=busybox2 busybox d96d5db03d981f4bcdf0f5374a5ca1a1dd741f40dacce82eab8e1a1bc0b68f0e ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242b1443650 no veth2783997 veth6e01edd
veth2783997、veth6e01edd为两个网络接口,对应着两个容器的网卡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 ~]# docker network inspect bridge [ { "Name": "bridge", "Id": "e56c41006af568144839868cca47fad31c1c0f7251848bffc71621e12bd7f2ee", "Created": "2022-10-20T01:03:46.451081072+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", #bridge的网络配置 "Gateway": "172.17.0.1" #bridge的网络配置,该网关就是docker0 } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { #使用bridge网络的容器网络配置 "d96d5db03d981f4bcdf0f5374a5ca1a1dd741f40dacce82eab8e1a1bc0b68f0e": { "Name": "busybox2", "EndpointID": "395664be54909dc79a763e74ca6a4aec83d342113ddbe4c287e2a2d70fcdb67d", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "ef8acee7abadee73a33c8ded047e7f57af8aaaf85a8bd6035fb271ee8ae99fb2": { "Name": "lucid_spence", "EndpointID": "7b780bdfdf91d7dad89978c6f0a007ec5be2d3bb283b0ce9db24078e24adfd47", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]
自定义网络 docker有三种网络驱动,bridge 、overlay 、macvlan。
自定义bridge网络 1 2 3 4 5 6 7 8 9 10 11 12 13 ~]# docker network create --driver bridge test_bridge b4a9474e46432b19582d3c7e24506aa79486aa12d938fe2f3929ba716ef3fe3e ~]# docker network ls NETWORK ID NAME DRIVER SCOPE e56c41006af5 bridge bridge local 4b615d9327ee host host local 05e237730870 none null local b4a9474e4643 test_bridge bridge local ~]# brctl show bridge name bridge id STP enabled interfaces br-b4a9474e4643 8000.02426345e115 no docker0 8000.0242b1443650 no veth2783997 veth6e01edd
创建一个新的bridge网络test_bridge,对应的会创建一个新的网桥,网桥的名后段就是test_bridge的短ID。 创建的新的test_bridge网络的网络配置docker自动分配的,在创建的时候可以指定IP网段。
1 2 3 4 5 6 7 8 9 ~]# docker network create --driver bridge --subnet 172.19.0.0/16 --gateway 172.19.0.1 test_bridge_2 e3eb0f55cb6356a97189a748a3a6a821a53cf9e1583d9a574cfada2557dcc370 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE e56c41006af5 bridge bridge local 4b615d9327ee host host local 05e237730870 none null local b4a9474e4643 test_bridge bridge local e3eb0f55cb63 test_bridge_2 bridge local
在创建容器的时候可以指定容器的IP,但是使用的网络必须是在创建时也指定- -subnet的。也就是使用test_bridge_2网络才可以指定容器IP,test_bridge则不行
1 2 3 4 5 ~]# docker run -it -d --network=test_bridge --ip 172.19.0.2 busybox c320bd7389697c8aaf149d0853166cc882b988c763c25f1cc053a5a6c7d8cfd1 docker: Error response from daemon: user specified IP address is supported only when connecting to networks with user configured subnets. ~]# docker run -it -d --network=test_bridge_2 --ip 172.19.0.2 busybox 09314af7bfdb84bc012aca1804d056e344db7609835040addfbd2b17f1aef8f4
不同网络容器之间通信 使用同一个bridge网络的容器之间是可以通信的,使用不同bridge网络的容器之间也可以实现通信。使用docker network connect 网络名 容器
连接到指定网络,docker network connect disconnect
断开指定的网络,具体的体现就是在对应的容器中多了一个对应网络的网卡。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ~]# docker run -it -d --network=test_bridge --name=busybox1 busybox 17f0e3f6fd1e729b21572e5d0eef9d280e50e5327edfe9fece15764fb22743b8 ~]# docker run -it -d --network=test_bridge --name=busybox2 busybox 79c883702435d5b00e6ee8ef8e4103d6025929296e9341ef5c3f98503cedb3e0 ~]# docker run -it -d --network=test_bridge_2 --name=busybox3 busybox fdd8fb26bbf26af839bae7312dd134cd7d5d94e697322d6ec61657eff4da28e9 ~]# docker exec -it busybox1 sh / # ping busybox2 #在同一个网络中可以使用容器名进行ping PING busybox2 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.224 ms 64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.085 ms 64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.098 ms ~]# docker network connect test_bridge busybox3 ~]# docker exec -it busybox3 sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 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 20: eth0@if21: <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 22: eth1@if23: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff inet 172.18.0.4/16 brd 172.18.255.255 scope global eth1 valid_lft forever preferred_lft forever / # ping busybox1 PING busybox1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.158 ms 64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.086 ms
容器之间的三种通信方式 容器之间可通过 IP,Docker DNS Server 或 joined 容器三种方式通信。
IP通信 属于同一个网络的容器之间是可以通信的。不同网络之间通过docker network connect 网络名 容器
实现通信。
Docker DNS Server docker内置了DNS服务,在IP通信的情况下可以使用DNS服务进行通信,busybox1与busybox2,以及将busybox3添加到test_bridge网络后,容器之间使用容器名就可以ping通。Docker DNS Server只能是在自定义网络中使用,默认的bridge网络无法使用DNS
joined容器 使多个容器共享一个网络栈,共享网卡和配置信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ~]# docker run -it -d --name=test_join busybox 578c4ad593d44212bf8180120ff6a5d41b64a8ec60b89ccd6be746baafc474a9 ~]# docker run -it -d --network=container:test_join --name=test_join_2 busybox 9b4f485357a3e04a41fd1b883ffcc1ef381fb42b6fc3b3d01018c0fa8c46d584 ~]# docker exec -it test_join sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 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 24: eth0@if25: <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 ~]# docker exec -it test_join_2 sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 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 24: eth0@if25: <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
可以发现test_join与test_join_2的网络配置是相同的。
容器与外界通信 容器访问外界 例如容器内ping 百度,以下是通信过程。
ping www.baidu.com,容器网卡发包
docker0收到包,交给NAT处理
NAT将源地址转换成宿主机网卡的IP
ping包从宿主机的网卡发出到达百度
外界访问容器 外部想要访问容器,容器需要将端口映射到宿主机的端口,通过docker run -p 宿主机端口:容器端口
实现。外部访问时访问宿主机的端口也就是访问了容器的端口 每一个映射的端口,host 都会启动一个 docker-proxy 进程来处理访问容器的流量。
docker-proxy 监听映射后宿主的端口
当外界访问宿主机端口时,docker-proxy转发给容器
容器响应请求并返回结果