docker 網路分為單機和多機,我們來瞭解一下docker的單機網路 docker單機網路分為以下幾種: 1)bridge NetWork,使用--net=bridge指定,預設設置。2)Host NetWork ,使用--net=host指定。3)None NetWork,使用--net=non ...
docker 網路分為單機和多機,我們來瞭解一下docker的單機網路
docker單機網路分為以下幾種:
1)bridge NetWork,使用--net=bridge指定,預設設置。
2)Host NetWork ,使用--net=host指定。
3)None NetWork,使用--net=none指定。
4)Container NetWork,使用--net=container:NAME_or_ID指定。
5)自定義 NetWork,使用docker network create my_net,使用--net=my_net指定。
1、首先,我們來看看一個比較重要的概念,關於namespace,看看network的namespace到底是怎麼回事。
通過實踐演示network-namespace。
創建容器:創建兩個busybox容器
[root@docker01 ~]# docker run -itd --name test1 busybox
f862152b6631cf28cf041b454ab85f5d190b03029c088a331a64b164900ef331
[root@docker01 ~]# docker run -itd --name test2 busybox
f78690e1e0b820c4fea8af6e4d062f4f6460f68697274e70b0189b5c2ff3386d
啟動了2個容器,test1與test2,進入這2個容器查看各自的ip地址
[root@docker01 ~]# docker exec -it test1 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 30: eth0@if31: <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 / # exit [root@docker01 ~]# docker exec -it test2 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 32: eth0@if33: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
可以看出test1的ip為172.17.0.2,test2的ip為172.17.0.3。其實這塊就是網路命名空間!
在test2上ping可以ping通test1的namespace。
[root@docker01 ~]# docker exec -it test2 sh / # ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=18.389 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.084 ms
可以發現命名空間是獨立的,容器內的網路命名空間和容器外不同,容器和容器之前的網路命名空間也是相對獨立的。
2、那麼docker網路究竟是如何配置的?
1. bridge網路模式
我們進入容器內,ping baidu發現可以ping通。這是什麼原理呢,肯定是通過可以轉接的方式,如:容器--->虛擬機---->宿主機-->baidu。
/ # ping www.baidu.com PING www.baidu.com (115.239.210.27): 56 data bytes 64 bytes from 115.239.210.27: seq=0 ttl=127 time=15.410 ms 64 bytes from 115.239.210.27: seq=1 ttl=127 time=7.586 ms
查看docker網路:
[root@docker01 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 99c36d692cac bridge bridge local ec237fbb8837 host host local 94e84f3d8354 none null local
這裡我們可以看到橋接模式。
對於test1與test2 來講,他是通過bridge的方式
我們可以看一下其內部網路信息:
[root@docker01 ~]# docker inspect test1 ...... "NetworkSettings": { "Bridge": "", "SandboxID": "6f8f2f996e4d5bfeddd179832cc5ffb3cd3f9ee830ce6acfff16fd249e9e0130", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/6f8f2f996e4d", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "d0a01da2cd1b487c6829518c7bdc01215b66a11b1e79e80862ab81c49e5cb0f7", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:02", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "99c36d692cac8d6be351681e590e0048f6a746fd9e1c88b2e3b7769dfd57fccb", "EndpointID": "d0a01da2cd1b487c6829518c7bdc01215b66a11b1e79e80862ab81c49e5cb0f7", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } }
......
查看宿主機ip信息:
[root@docker01 ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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 inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:cf:3d:4b brd ff:ff:ff:ff:ff:ff inet 10.0.0.99/24 brd 10.0.0.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fecf:3d4b/64 scope link valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:1f:f4:29:1a 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:1fff:fef4:291a/64 scope link valid_lft forever preferred_lft forever 4: veth3b111e2@if32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default link/ether 62:a9:c9:0b:be:d6 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::60a9:c9ff:fe0b:bed6/64 scope link valid_lft forever preferred_lft forever 5: vethdc6d1fa@if30: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether a2:17:9c:af:d1:d9 brd ff:ff:ff:ff:ff:ff link-netnsid 2 inet6 fe80::a017:9cff:feaf:d1d9/64 scope link valid_lft forever preferred_lft forever
這個機器有5個網路,除了lo,ens33,docker0,veth3b111e2@if32,vethdc6d1fa@if30,veth其實是連接了2個networknamespace,vethdbcb3a6@if11與vethdc6d1fa@if30負責連接docker0上邊的,容器test1與test2裡面也應該有個和veth連接的。
[root@docker01 ~]# docker exec test1 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 30: eth0@if31: <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
eth0@if31和外邊的veth3b111e2@if32 其實是一對。test2同理。
可以通過命令查看他們的關係: yum install -y bridge-utils
#安裝後可以運行brctl這個命令了
[root@docker01 ~]# brctl show docker0 8000.02421ff4291a no veth3b111e2 vethdc6d1fa
因為目前兩個容器test1與test2的橋接,所以就顯示兩個。
test1 和test2 之前通過docker0,docker0 類似test1和test2之前的路由器,docker0 在通過nat的eth0連接互聯網。
為了形象理解docker bridge network可以參考下圖:
2. host 網路模式
host模式下容器不會獲得一個獨立的network namespace,而是與宿主機共用一個。這就意味著容器不會有自己的網卡信息,而是使用宿主機的。容器除了網路,其他都是隔離的。
[root@docker01 ~]# docker run -itd --name test3 --network host busybox 2268c2f8eb8ff74b72e521148dc1fe82a9a822857f251abab2368b24924453d6 [root@docker01 ~]# docker exec -it test3 /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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 inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:cf:3d:4b brd ff:ff:ff:ff:ff:ff inet 10.0.0.99/24 brd 10.0.0.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fecf:3d4b/64 scope link valid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:1f:f4:29:1a 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:1fff:fef4:291a/64 scope link valid_lft forever preferred_lft forever 4: veth3b111e2@if32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker_gwbridge state UP group default link/ether 62:a9:c9:0b:be:d6 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::60a9:c9ff:fe0b:bed6/64 scope link valid_lft forever preferred_lft forever 5: vethdc6d1fa@if30: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether a2:17:9c:af:d1:d9 brd ff:ff:ff:ff:ff:ff link-netnsid 2 inet6 fe80::a017:9cff:feaf:d1d9/64 scope link valid_lft forever preferred_lft forever
此容器沒有自己的介面,與宿主機ip完全一樣,起容器只能起單個,比如nginx。
3. none網路模式:
獲取獨立的network namespace,但不為容器進行任何網路配置,需要我們手動配置。
[root@docker01 ~]# docker run -itd --name test4 --network none busybox 7222ec17cd70c1094af5710445bec25bd2a7bd09c86f97348857ad5f70ed21b3 [root@docker01 ~]# docker exec -it test4 /bin/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
此容器沒有介面ip,與外界無溝通,用於安全性比較高的業務,可自己手動添加網路。
4. container 網路模式:
與指定的容器使用同一個network namespace,具有同樣的網路配置信息,兩個容器除了網路,其他都還是隔離的。新創建的容器不會創建自己的網卡,配置自己的IP,而是和一個指定的容器共用IP、埠範圍等。同樣,兩個容器除了網路方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過lo網卡設備通信。
[root@docker01 ~]# docker run -itd --name test5 --net=container:test1 busybox af3a29e3171f82ef1a2e827d9307fbd2de6484ec225c6227de5de2fe6e557a90 [root@docker01 ~]# docker exec -it test5 /bin/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 30: eth0@if31: <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
可以看出 test5 與 test1的網路配置信息是一致的。
5. 自定義網路模式:
與預設的bridge原理一樣,但自定義網路具備內部DNS發現,可以通過容器名或者主機名容器之間網路通信。
通過docker network create 創建自定義的網路:
[root@docker01 ~]# docker network create test [root@docker01 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 99c36d692cac bridge bridge local ec237fbb8837 host host local 94e84f3d8354 none null local ea714a707d9d test bridge local
創建容器指定自定義網橋:
[root@docker01 ~]# docker run -itd --name test6 --net=test busybox
6b4add91370de5e9ac727c5d8992e516c7a5e8f75846f55f4c314bc433083998
[root@docker01 ~]# docker run -itd --name test7 --net=test busybox
eb55f38600e725f050dea02d5227516858a4a3c7c6f85fec8bc9932864c811f8
與普通bridge網路不同的是,自定義網路中創建的容器可以通過容器名或者主機名互通。
[root@docker01 ~]# docker exec -it test6 /bin/sh / # ping test7 PING test7 (172.21.0.3): 56 data bytes 64 bytes from 172.21.0.3: seq=0 ttl=64 time=0.151 ms 64 bytes from 172.21.0.3: seq=1 ttl=64 time=0.132 ms ^C --- test7 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.083/0.122/0.151 ms / # exit [root@docker01 ~]# docker exec -it test7 /bin/sh / # ping test6 PING test6 (172.21.0.2): 56 data bytes 64 bytes from 172.21.0.2: seq=0 ttl=64 time=0.139 ms 64 bytes from 172.21.0.2: seq=1 ttl=64 time=0.087 ms ^C --- test6 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.087/0.104/0.139 ms
其原理是各容器內部的hosts文件做了ip與主機名解析。
/ # cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.21.0.3 eb55f38600e7