Docker 中的網絡功能介紹
node
Docker 容許經過外部訪問容器或容器互聯的方式來提供網絡服務 python
1) 外部訪問容器 linux
容器中能夠運行一些網絡應用,要讓外部也能夠訪問這些應用,能夠經過 -p或 -P參數來指定端口映射
web
運行容器時若是使用-P,Docker 會隨機映射一個在49000-49900區間內的端口到內部容器開放的網絡端口。 docker
好比下面的容器,就隨機選取了本地的32768端口映射到了容器中正開放的5000端口,此時訪問本機的 32768 端口便可訪問容器內 web 應用提供的界面 數據庫
userdeMacBook-Pro:~ user$ docker run -d -P --name web -v /webapp training/webapp python app.py Unable to find image 'training/webapp:latest' locally latest: Pulling from training/webapp e190868d63f8: Pull complete 909cd34c6fd7: Pull complete 0b9bfabab7c1: Pull complete a3ed95caeb02: Pull complete 10bbbc0fc0ff: Pull complete fca59b508e9f: Pull complete e7ae2541b15b: Pull complete 9dd97ef58ce9: Pull complete a4c1b0cb7af7: Pull complete Digest: sha256:06e9c1983bd6d5db5fba376ccd63bfa529e8d02f23d5079b8f74a616308fb11d Status: Downloaded newer image for training/webapp:latest 1ad71e9d38081c38dcd355fd7a438cd9f94503e8bc28e99a48c0738b51e7efef userdeMacBook-Pro:~ user$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1ad71e9d3808 training/webapp "python app.py" 42 minutes ago Up 42 minutes 0.0.0.0:32768->5000/tcp web
在瀏覽器中訪問http://localhost:32768:ubuntu
而後能夠經過 docker logs 命令來查看瀏覽器訪問應用的信息: api
userdeMacBook-Pro:~ user$ docker logs web * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) 172.17.0.1 - - [15/Dec/2018 10:20:08] "GET / HTTP/1.1" 200 - 172.17.0.1 - - [15/Dec/2018 10:20:08] "GET /favicon.ico HTTP/1.1" 404 -
-p(小寫的)則能夠指定要映射的端口,而且,在一個指定端口上只能夠綁定一個 容器。瀏覽器
支持的格式有:安全
1》 映射全部接口地址
使用主機端口:容器端口格式,本地的 5000 端口能夠映射到容器的 5000 端 口,如:
sudo docker run -d -p 5000:5000 training/webapp python app.py
此時默認會綁定本地全部接口上的全部ip地址
2》映射到指定地址的指定端口
使用 ip地址:主機端口:容器端口格式指定映射使用一個特定地址,好比 localhost 地址 127.0.0.1
docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
3》映射到指定地址的任意端口
使用ip地址::容器端口格式綁定 localhost 的任意端口到容器的 5000 端口,本地主機會自動分配一個端口:
docker run -d -p 127.0.0.1::5000 training/webapp python app.py
還可使用 udp 標記來指定 udp 端口
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
查看映射端口配置——docker port
查看當前映射的端口配置,也能夠查看到綁定的地址
userdeMacBook-Pro:~ user$ docker port web 5000 0.0.0.0:32768
⚠️:
容器有本身的內部網絡和 ip 地址(使用 docker inspect能夠獲取全部的變量,Docker 還能夠有一個可變的網絡配置。)
-p 標記能夠屢次使用來綁定多個端口,如:
docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py
2)容器互聯
容器的鏈接(linking)系統是除了端口映射外,另外一種跟容器中應用交互的方式。
該系統會在源和接收容器之間建立一個隧道,接收容器能夠看到源容器指定的信息。
1》自定義容器命名——使用 --name參數
鏈接系統依據容器的名稱來執行。所以,首先須要自定義一個好記的容器命名
當建立容器的時候,系統默認會分配一個名字。
可是自定義命名容器有2個好處:
docker run -d -P --name web training/webapp python app.py
可使用docker ps -l查看,也可使用 docker inspect來查看容器的名字
userdeMacBook-Pro:~ user$ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1ad71e9d3808 training/webapp "python app.py" About an hour ago Up About an hour 0.0.0.0:32768->5000/tcp web userdeMacBook-Pro:~ user$ docker inspect -f "{{ .Name }}" 1ad71e9d3808 /web
注意:容器的名稱是惟一的。若是已經命名了一個叫 web 的容器,當你要再次使用 web 這個名稱的時候,須要先用docker rm來刪除以前建立的同名容器。
在執行 docker run的時候若是添加 -rm 標記,則容器在終止後會馬上刪除。
⚠️-rm 和 -d(後臺運行)參數不能同時使用。
2》 容器互聯——使用 --link參數
格式: --link name:alias
其中 name是要連接的容器的名稱, alias是這個鏈接的別名
先建立一個新的數據庫容器db:
userdeMacBook-Pro:~ user$ docker run -d --name db training/postgres Unable to find image 'training/postgres:latest' locally latest: Pulling from training/postgres a3ed95caeb02: Pull complete 6e71c809542e: Pull complete 2978d9af87ba: Pull complete e1bca35b062f: Pull complete 500b6decf741: Pull complete 74b14ef2151f: Pull complete 7afd5ed3826e: Pull complete 3c69bb244f5e: Pull complete d86f9ec5aedf: Pull complete 010fabf20157: Pull complete Digest: sha256:a945dc6dcfbc8d009c3d972931608344b76c2870ce796da00a827bd50791907e Status: Downloaded newer image for training/postgres:latest 2fca948912dcfd40849d1f2080db69bed0f51a9b1c1a10ceba7e3bf7d0960e5f
刪除以前建立的 web 容器:
userdeMacBook-Pro:~ user$ docker rm -f web
web
而後建立一個新的 web 容器,並將它鏈接到 db 容器:
userdeMacBook-Pro:~ user$ docker run -d -P --name web --link db:db training/webapp python app.py
d734bf29ad945f25e65e451d5d207b007a24004002dbaa722b28e02fb46ed51e
此時,db 容器和 web 容器成功創建了互聯關係
使用 docker ps來查看容器的鏈接:
userdeMacBook-Pro:~ user$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d734bf29ad94 training/webapp "python app.py" 7 seconds ago Up 6 seconds 0.0.0.0:32769->5000/tcp web 2fca948912dc training/postgres "su postgres -c '/us…" 39 seconds ago Up 38 seconds 5432/tcp db
這樣子就不用像上面同樣須要使用-p 或 -P映射端口了。
Docker 經過 2 種方式爲容器公開鏈接信息:
首先是環境變量方式:
使用 env 命令來查看 web 容器的環境變量:
userdeMacBook-Pro:~ user$ docker run --rm --name web --link db:db training/webapp env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=994146340f40 DB_PORT=tcp://172.17.0.3:5432 DB_PORT_5432_TCP=tcp://172.17.0.3:5432 DB_PORT_5432_TCP_ADDR=172.17.0.3 DB_PORT_5432_TCP_PORT=5432 DB_PORT_5432_TCP_PROTO=tcp DB_NAME=/web/db DB_ENV_PG_VERSION=9.3 HOME=/root
其中 DB_ 開頭的環境變量是供 web 容器鏈接 db 容器使用,前綴採用大寫的鏈接別名。
而後更新 /etc/hosts文件方式,Docker 添加了host信息到父容器的 /etc 的文件。下面是父容器 web的 hosts文件:
userdeMacBook-Pro:~ user$ docker run -t -i --rm --link db:db training/webapp /bin/bash root@36078e6ba58f:/opt/webapp# 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.17.0.3 db 2fca948912dc //db容器的 容器名和ID 172.17.0.2 36078e6ba58f //web容器的ID
能夠在 web 容器中安裝 ping 命令來測試跟db容器的連通:
root@36078e6ba58f:/opt/webapp# apt-get install -yqq inetutils-ping (Reading database ... 18233 files and directories currently installed.) Removing ubuntu-minimal (1.325) ... Removing iputils-ping (3:20121221-4ubuntu1.1) ... Selecting previously unselected package inetutils-ping. (Reading database ... 18221 files and directories currently installed.) Preparing to unpack .../inetutils-ping_2%3a1.9.2-1_amd64.deb ... Unpacking inetutils-ping (2:1.9.2-1) ... Setting up inetutils-ping (2:1.9.2-1) ... root@36078e6ba58f:/opt/webapp# ping db PING db (172.17.0.3): 56 data bytes 64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.099 ms 64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.120 ms 64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.063 ms 64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.202 ms 64 bytes from 172.17.0.3: icmp_seq=4 ttl=64 time=0.101 ms 64 bytes from 172.17.0.3: icmp_seq=5 ttl=64 time=0.133 ms 64 bytes from 172.17.0.3: icmp_seq=6 ttl=64 time=0.129 ms 64 bytes from 172.17.0.3: icmp_seq=7 ttl=64 time=0.104 ms 64 bytes from 172.17.0.3: icmp_seq=8 ttl=64 time=0.129 ms 64 bytes from 172.17.0.3: icmp_seq=9 ttl=64 time=0.130 ms 64 bytes from 172.17.0.3: icmp_seq=10 ttl=64 time=0.128 ms 64 bytes from 172.17.0.3: icmp_seq=11 ttl=64 time=0.128 ms 64 bytes from 172.17.0.3: icmp_seq=12 ttl=64 time=0.063 ms 64 bytes from 172.17.0.3: icmp_seq=13 ttl=64 time=0.130 ms 64 bytes from 172.17.0.3: icmp_seq=14 ttl=64 time=0.130 ms ^C--- db ping statistics --- 15 packets transmitted, 15 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.063/0.119/0.202/0.032 ms
用 ping 來測試db容器,它會解析成 172.17.0.3。 *注意:官方的 ubuntu 鏡像 默認沒有安裝 ping,須要自行安裝
用戶能夠連接多個父容器到子容器,好比能夠連接多個 web 到 db 容器上
3) 高級網絡配置
1》默認網絡
docker network命令使用
1.首先查看docker network命令怎麼使用
userdeMBP:~ user$ docker network --help Usage: docker network COMMAND Manage networks Commands: connect Connect a container to a network 將容器鏈接到網絡上,默認鏈接的是bridge網絡 create Create a network 建立一個網絡,使用--driver參數指定網絡類型 disconnect Disconnect a container from a network 斷開容器鏈接的網絡 inspect Display detailed information on one or more networks 展現一個或多個網絡的詳細信息 ls List networks 列舉現有的全部網絡 prune Remove all unused networks 移除全部再也不使用的網絡 rm Remove one or more networks 移除一個或多個網絡 Run 'docker network COMMAND --help' for more information on a command.
2.而後查看目前的網絡狀況,初始時是默認有下面的三類網絡的
userdeMBP:~ user$ docker network ls NETWORK ID NAME DRIVER SCOPE 5a8633141529 bridge bridge local 78c9cc883ccc host host local 454aa19cf801 none null local
當 Docker 啓動時,會自動在主機上建立一個虛擬網橋,其實是 Linux 的一個 bridge(即這上面的bridge網絡),能夠理解爲一個軟件交換機。它會在掛載到它的網口之間進行轉發。
none網絡——即什麼都沒有的網絡
打開兩個鏈接了默認bridge網絡的ubuntu容器和一個鏈接了none網絡的ubuntu容器,而後查看它們的ip配置信息,並ping本地主機看可否連通:
當你想要實現一些對安全要求比較高而且不須要聯網的操做時,就可使用none網絡
上圖可見,若是你使用的是bridge網絡,你是能夠ping通你如今的主機的網絡的;若是你是none網絡,你是沒法鏈接網絡的
好比你有些容器的做用時生成密鑰文件等操做時,使用none網絡就能保證密鑰文件的安全行,不會被竊取
host網絡
打開了一個鏈接了host網絡的ubuntu容器,而後查看其ip信息
userdeMBP:~ user$ docker run -it --network=host --name=ubuntu3 ubuntu:14.04 /bin/bash root@linuxkit-025000000001:/# 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 brd 127.255.255.255 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 02:50:00:00:00:01 brd ff:ff:ff:ff:ff:ff inet 192.168.65.3/24 brd 192.168.65.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::50:ff:fe00:1/64 scope link valid_lft forever preferred_lft forever 3: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1 link/ipip 0.0.0.0 brd 0.0.0.0 4: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1 link/tunnel6 :: brd :: 5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:c4:a0:b5:3e 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:c4ff:fea0:b53e/64 scope link valid_lft forever preferred_lft forever 9: veth4a027b0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 96:2b:b2:b1:de:52 brd ff:ff:ff:ff:ff:ff inet6 fe80::942b:b2ff:feb1:de52/64 scope link valid_lft forever preferred_lft forever 11: veth3406c1a@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether ba:80:0c:67:c0:9e brd ff:ff:ff:ff:ff:ff inet6 fe80::b880:cff:fe67:c09e/64 scope link valid_lft forever preferred_lft forever 13: vethcee69e2@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 72:51:1e:7b:01:0c brd ff:ff:ff:ff:ff:ff inet6 fe80::7051:1eff:fe7b:10c/64 scope link valid_lft forever preferred_lft forever
(參考https://blog.csdn.net/liukuan73/article/details/51603074)
由於docker使用了Linux的Namespace技術來進行資源的隔離,如PID Namespace隔離進程,Mount Namespace隔離文件系統,Network Namespace隔離網絡等
使用bridge網絡時,一個容器會分配一個獨立的Network Namespace。可是若是使用的是host網絡,容器將不會得到一個獨立的Network Namespace,而是與宿主機公用一個Network Namespace。在這種狀況下,容器將不會虛擬出本身的網卡,配置本身的IP等,而是使用宿主機的IP和端口。容器能夠和宿主機同樣,使用宿主機的eth0,實現和外界的通訊。換言之,容器的IP地址即爲宿主機eth0的IP地址
所以上面開啓的容器使用ip addr命令時,發現獲得的信息都是宿主機上的信息。所以當外界想要訪問該容器時,直接訪問宿主機的IP和容器開放的端口便可,不須要任何的NAT轉換,就像直接運行在宿主機同樣。
⚠️可是容器的其餘方面,如文件系統、進程列表等仍是和宿主機隔離的
host網絡實際上是bridge網絡的一種補充,可是也有不足的地方:
同時查看host網絡此時的詳細信息:
userdeMacBook-Pro:~ user$ docker network inspect 78c9cc883ccc [ { "Name": "host", "Id": "78c9cc883ccc186865ab14c31f7d3ebafecd725e2524a7ab3bb550fb91a73705", "Created": "2018-07-21T02:08:33.191948595Z", "Scope": "local", "Driver": "host", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "084fd2f2927a18f8c6003f7ee70e5fef80e6ffca6246f75d8ada71c5be76a8bf": { "Name": "ubuntu3", //即上面鏈接了host網絡的容器 "EndpointID": "a57a350fb83a4c45d276eefaf29c0ef13278af2cfbfa3a6a7c9f36a1430f07cb", "MacAddress": "", "IPv4Address": "", "IPv6Address": "" }, "3c3f1551282d8f983faf974d96e366262d133da662108c43506e6dcb16902b4c": { "Name": "k8s_POD_etcd-docker-for-desktop_kube-system_1f439806cd68459343e83b51b9f719eb_0", "EndpointID": "6c2f76ff13c3ebe545a1c3f36d864d9525aadaebced72270abb88fe92aaed69e", "MacAddress": "", "IPv4Address": "", "IPv6Address": "" }, "636bc1e866ed8f215261e30a522feeb91b2a8417be0a4f55324a013e7efadfcf": { "Name": "k8s_POD_kube-controller-manager-docker-for-desktop_kube-system_ac5424d04b6928ef15ca302888630c4e_0", "EndpointID": "25234b9025957c835fc0669334affd6a74bc03d9b679e50b2fe713cbfe1c9f8c", "MacAddress": "", "IPv4Address": "", "IPv6Address": "" }, "7a58a9d0aa01abb785392264a8c5406593d4fa2b6749f27094b4f80b939e1ab4": { "Name": "k8s_POD_kube-scheduler-docker-for-desktop_kube-system_ea66a171667ec4aaf1b274428a42a7cf_0", "EndpointID": "3a83f9b42be6f8b0a68e440b839aff4326d4d524590f5471ed6882560bb9658d", "MacAddress": "", "IPv4Address": "", "IPv6Address": "" }, "f9d84fe15fe1591d15d76fad2162285426aef4a700ed78c54b28c4a71b19c28c": { "Name": "k8s_POD_kube-apiserver-docker-for-desktop_kube-system_f10287b5cba0247140caeedc2e1fd602_0", "EndpointID": "3b43272e8ab15a3fe91d1c04cae74af2ce560b8431aaa3027bfe81b7e41fa531", "MacAddress": "", "IPv4Address": "", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
bridge網絡
Docker 會隨機分配一個本地未佔用的私有網段(在 RFC1918 中定義)中的一 個地址給 docker0接口。好比典型的 172.17.42.1,掩碼爲255.255.0.0。此後啓動的容器內的網口也會自動分配一個同一網段( 172.17.0.0/16 )的地址。
當建立一個 Docker 容器的時候,同時會建立了一對 veth pair接口(當數據包發送到一個接口時,另一個接口也能夠收到相同的數據包)。這對接口一端在容器內,即eth0 ——下面打開的容器查看IP信息時的eth0;
userdeMBP:~ user$ docker run -it ubuntu:14.04 /bin/bash root@481d94d59f9f:/# ifconfig eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:03 inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:6 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:508 (508.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) root@481d94d59f9f:/# ping 10.240.203.84 PING 10.240.203.84 (10.240.203.84) 56(84) bytes of data. 64 bytes from 10.240.203.84: icmp_seq=1 ttl=37 time=0.647 ms 64 bytes from 10.240.203.84: icmp_seq=2 ttl=37 time=0.513 ms 64 bytes from 10.240.203.84: icmp_seq=3 ttl=37 time=0.674 ms ^C --- 10.240.203.84 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2043ms rtt min/avg/max/mdev = 0.513/0.611/0.674/0.073 ms root@481d94d59f9f:/# ping ww.baidu.com PING ps_other.a.shifen.com (123.125.114.144) 56(84) bytes of data. 64 bytes from 123.125.114.144: icmp_seq=1 ttl=37 time=46.3 ms 64 bytes from 123.125.114.144: icmp_seq=2 ttl=37 time=48.1 ms 64 bytes from 123.125.114.144: icmp_seq=3 ttl=37 time=47.1 ms ^C --- ps_other.a.shifen.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 46.341/47.210/48.168/0.748 ms
能夠ping通本地主機網絡可外部網絡
另外一端在本地並被掛載到docker0網橋,名稱以 veth開頭(例如vethAQI2QT)。經過這種方式,主機能夠跟容器通訊,容器之間也能夠相互通訊。Docker 就建立了在主機和全部容器之間一個虛擬共享網絡。
由於我使用的是mac系統,爲了使用Linux的命令來查看網橋信息,能夠在剛剛使用--network=host的容器上進行查看:
root@linuxkit-025000000001:/# brctl show //沒有安裝brctl bash: brctl: command not found root@linuxkit-025000000001:/# apt-get install bridge-utils Reading package lists... Done Building dependency tree Reading state information... Done E: Unable to locate package brctl-utils //沒有找到這個包,可能須要更新下源 root@linuxkit-025000000001:/# apt-get update //更新源 Ign http://archive.ubuntu.com trusty InRelease Get:1 http://archive.ubuntu.com trusty-updates InRelease [65.9 kB] ... Get:21 http://archive.ubuntu.com trusty/multiverse amd64 Packages [169 kB] Fetched 13.3 MB in 52s (252 kB/s) Reading package lists... Done root@linuxkit-025000000001:/# apt-get install bridge-utils //而後從新下載便可 Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: bridge-utils 0 upgraded, 1 newly installed, 0 to remove and 6 not upgraded. ...
而後就能夠查看網橋信息了
root@linuxkit-025000000001:/# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242c4a0b53e no veth3406c1a veth4a027b0 vethcee69e2
能夠看見掛載到docker0網橋這邊的接口爲veth3406c1a、veth4a027b0和vethcee69e2
查看默認使用的bridge網絡,若是在開啓容器時沒有制定,通常就會默認使用的是bridge網絡。由於docker的橋接網絡使用虛擬網橋,bridge網絡用於同一主機上的docker容器相互通訊,鏈接到同一個網橋的docker容器能夠相互通訊
userdeMacBook-Pro:~ user$ docker network inspect a782ffdae16f [ { "Name": "bridge", "Id": "a782ffdae16f9c3dbfec0a992a9a6d605429c657263dc83f33c71ad499f5e2b8", "Created": "2018-12-19T01:34:27.308734153Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "481d94d59f9f363fd3b00f09b793c9d7e1d90169626a7170f4d1012949c9ace4": { "Name": "wonderful_matsumoto", "EndpointID": "9dd9be72550d24135202f430dfeea0fb0132d52089045c933a5bfb6fd5ddb779", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "876cdcff687d83e5ea85d3c2eb16d01aac62bfd3e5051e5e65f0fd49230d7333": { "Name": "ubuntu2", "EndpointID": "9c16f983ff075f1499dcc1de4ead5ac77097829a68ff868a328e90e336660e29", "MacAddress": "02:42:ac:11:00:04", "IPv4Address": "172.17.0.4/16", "IPv6Address": "" }, "b4a512f0230fa598e7e40171e0597ea6db0740105449314a1a3767dcaa4a0edb": { "Name": "registry", "EndpointID": "b164dd37f23eac13364f1378642c5e8b88b783ea48fbbce26017ab02b33b542e", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true",//說明這個是默認的bridge網絡 "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",//默認網橋的名字爲docker0 "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ] //上面可見爲開啓的三個容器分別分配了172.17.0.0/16網段下的地址 userdeMacBook-Pro:~ user$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 084fd2f2927a ubuntu:14.04 "/bin/bash" About an hour ago Up About an hour ubuntu3 876cdcff687d ubuntu:14.04 "/bin/bash" About an hour ago Up About an hour ubuntu2 e6ba811ecb6a ubuntu:14.04 "/bin/bash" About an hour ago Up About an hour thirsty_germain 481d94d59f9f ubuntu:14.04 "/bin/bash" About an hour ago Up About an hour wonderful_matsumoto b4a512f0230f registry "/entrypoint.sh /etc…" 3 days ago Up 2 hours 0.0.0.0:5000->5000/tcp registry
1.多個容器可使用docker volume(這是docker存儲數據的一種方式,之後會介紹)掛載到同一個文件,在文件中指明環境變量,從而實現所容器的環境變量共享
2.多個容器可使用同一個docker-compose.yml(與docker service有關)文件啓動 ,能夠在該文件中定義共享環境變量
3.可使用swarm services,而且經過 secrets 和 configs (這兩個還沒看)實現環境變量共享從上圖可見,基本上就至關於打開了別名爲ubuntu10的ubuntu8容器,二者的IP地址是徹底同樣的,連主機名都是同樣的。固然,ubuntu10容器也是開啓了的:
userdeMBP:~ user$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3b854b76e02e ubuntu:14.04 "/bin/bash" 2 minutes ago Up 2 minutes ubuntu10 f07c50c1c6ee ubuntu:14.04 "/bin/bash" 27 minutes ago Up 27 minutes ubuntu8
userdeMacBook-Pro:~ user$ docker network ls //查看當前的網絡 NETWORK ID NAME DRIVER SCOPE a782ffdae16f bridge bridge local 78c9cc883ccc host host local 454aa19cf801 none null local userdeMacBook-Pro:~ user$ docker network create --driver bridge myNetwork1 //新添加一個bridge網絡,名字叫myNetwork1 f16ae5c303c68f25e63ff80c09a3289fcf1785c1bc86a3baabeef6687035cf0b userdeMacBook-Pro:~ user$ docker network ls //查看獲得新的網絡myNetwork1 NETWORK ID NAME DRIVER SCOPE a782ffdae16f bridge bridge local 78c9cc883ccc host host local f16ae5c303c6 myNetwork1 bridge local 454aa19cf801 none null local
root@linuxkit-025000000001:/# brctl show bridge name bridge id STP enabled interfaces br-f16ae5c303c6 8000.0242751521cb no //這個就是新生成的bridge網絡,尚未鏈接容器,因此interfaces爲空 docker0 8000.0242c4a0b53e no veth3406c1a veth4a027b0 vethcee69e2 root@linuxkit-025000000001:/# ip addr ... 14: br-f16ae5c303c6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:75:15:21:cb brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-f16ae5c303c6 //能夠看見其被自動分配的網段爲172.18.0.1/16 valid_lft forever preferred_lft forever
網橋名稱br-f16ae5c303c6 即 br-networkId
使用docker network inspect命令查看生成的network信息:
userdeMacBook-Pro:~ user$ docker network inspect f16ae5c303c6 [ { "Name": "myNetwork1", "Id": "f16ae5c303c68f25e63ff80c09a3289fcf1785c1bc86a3baabeef6687035cf0b", "Created": "2018-12-19T03:56:51.09420804Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", //自動分配的網段和網關 "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ]
userdeMacBook-Pro:~ user$ docker network create --driver bridge --subnet 172.20.11.0/24 --gateway 172.20.11.1 myNetwork2 9dc30b4c7e392ad993540f19638653e62b4cff8af4944d8ab29b7b88c467331d userdeMacBook-Pro:~ user$ docker network ls NETWORK ID NAME DRIVER SCOPE a782ffdae16f bridge bridge local 78c9cc883ccc host host local f16ae5c303c6 myNetwork1 bridge local 9dc30b4c7e39 myNetwork2 bridge local 454aa19cf801 none null local userdeMacBook-Pro:~ user$ docker network inspect 9dc30b4c7e39 [ { "Name": "myNetwork2", "Id": "9dc30b4c7e392ad993540f19638653e62b4cff8af4944d8ab29b7b88c467331d", "Created": "2018-12-19T04:13:47.531039833Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.20.11.0/24", "Gateway": "172.20.11.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ] userdeMacBook-Pro:~ user$
指明瞭網段爲172.20.11.0/24,網關爲172.20.11.1
root@linuxkit-025000000001:/# ifconfig br-9dc30b4c7e39 br-9dc30b4c7e39 Link encap:Ethernet HWaddr 02:42:99:f9:5d:06 inet addr:172.20.11.1 Bcast:172.20.11.255 Mask:255.255.255.0 UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
這樣咱們在啓動容器的時候就可以使用上面自定義的bridge網絡了:
userdeMacBook-Pro:~ user$ docker run -it --name=ubuntu4 --network=myNetwork2 ubuntu:14.04 /bin/bash root@57fb8937e663:/# ifconfig eth0 Link encap:Ethernet HWaddr 02:42:ac:14:0b:02 inet addr:172.20.11.2 Bcast:172.20.11.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:14 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1156 (1.1 KB) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) root@57fb8937e663:/#
可見的確是在172.20.11.0/24網段下
上面的容器的IP地址都是動態分配的,若是用戶想要實現指定靜態的IP地址的話,可使用--ip參數:
userdeMacBook-Pro:~ user$ docker run -it --name=ubuntu5 --network=myNetwork2 --ip=172.20.11.8 ubuntu:14.04 /bin/bash root@9e11c1b9e90d:/# ifconfig eth0 Link encap:Ethernet HWaddr 02:42:ac:14:0b:08 inet addr:172.20.11.8 Bcast:172.20.11.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:6 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:508 (508.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
指定了靜態地址172.20.11.8
⚠️只有當鏈接的網絡指定了--subnet時,相應的容器開啓時纔可以使用--ip參數
root@9e11c1b9e90d:/# ping -c 3 172.20.11.1 PING 172.20.11.1 (172.20.11.1) 56(84) bytes of data. 64 bytes from 172.20.11.1: icmp_seq=1 ttl=64 time=0.092 ms 64 bytes from 172.20.11.1: icmp_seq=2 ttl=64 time=0.101 ms 64 bytes from 172.20.11.1: icmp_seq=3 ttl=64 time=0.090 ms --- 172.20.11.1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2049ms rtt min/avg/max/mdev = 0.090/0.094/0.101/0.009 ms
那若是咱們去ping默認bridge網絡下的ubuntu容器,發現是不可以ping通的:
root@9e11c1b9e90d:/# ping -c 3 172.17.0.4 PING 172.17.0.4 (172.17.0.4) 56(84) bytes of data. --- 172.17.0.4 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2068ms
root@linuxkit-025000000001:/# ip r //查看本地主機上的路由表信息 ... 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 172.20.11.0/24 dev br-9dc30b4c7e39 proto kernel scope link src 172.20.11.1 ...
而後再查看本地系統是否開啓了轉發支持:
root@linuxkit-025000000001:/# sysctl net.ipv4.ip_forward net.ipv4.ip_forward = 1 //開啓了
而後再查看防火牆iptables,須要從新使用--privileged參數的--network=host的容器:
userdeMBP:~ user$ docker run -it --privileged --network=host --name=ubuntu6 ubuntu:14.04 /bin/bash root@linuxkit-025000000001:/# ip r ... 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 172.20.11.0/24 dev br-9dc30b4c7e39 proto kernel scope link src 172.20.11.1 ... root@linuxkit-025000000001:/# iptables-save //須要安裝iptables bash: iptables-save: command not found root@linuxkit-025000000001:/# apt-get install iptables Reading package lists... Done Building dependency tree Reading state information... Done E: Unable to locate package iptables //須要更新源 root@linuxkit-025000000001:/# apt-get update //更新源 Ign http://archive.ubuntu.com trusty InRelease ... Get:21 http://archive.ubuntu.com trusty/multiverse amd64 Packages [169 kB] Fetched 13.3 MB in 50s (266 kB/s) Reading package lists... Done root@linuxkit-025000000001:/# apt-get install iptables //而後就可以成功安裝了 Reading package lists... Done ... Setting up libnfnetlink0:amd64 (1.0.1-2) ... Setting up libxtables10 (1.4.21-1ubuntu1) ... Setting up iptables (1.4.21-1ubuntu1) ... Processing triggers for libc-bin (2.19-0ubuntu6.14) ... root@linuxkit-025000000001:/# iptables-save //查看獲得此時的防火牆規則 ... -A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 5000 -j ACCEPT -A DOCKER-ISOLATION-STAGE-1 -i br-9dc30b4c7e39 ! -o br-9dc30b4c7e39 -j DOCKER-ISOLATION-STAGE-2 -A DOCKER-ISOLATION-STAGE-1 -i br-f16ae5c303c6 ! -o br-f16ae5c303c6 -j DOCKER-ISOLATION-STAGE-2 -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2 -A DOCKER-ISOLATION-STAGE-1 -j RETURN -A DOCKER-ISOLATION-STAGE-2 -o br-9dc30b4c7e39 -j DROP -A DOCKER-ISOLATION-STAGE-2 -o br-f16ae5c303c6 -j DROP -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP -A DOCKER-ISOLATION-STAGE-2 -j RETURN -A DOCKER-USER -j RETURN -A KUBE-FIREWALL -m comment --comment "kubernetes firewall for dropping marked packets" -m mark --mark 0x8000/0x8000 -j DROP COMMIT # Completed on Wed Dec 19 06:46:37 2018
從這兩句:
-A DOCKER-ISOLATION-STAGE-2 -o br-9dc30b4c7e39 -j DROP -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
可知iptables DROP 掉了網橋 docker0 與 br-9dc30b4c7e39 之間雙向的流量
從規則的命名 DOCKER-ISOLATION
可知 docker 在設計上就是要隔離不一樣的 netwrok
那咱們要如何讓二者通訊呢?
方法就是而後容器ubuntu5,即網絡爲 br-9dc30b4c7e39的容器添加一個新網卡,方法就是鏈接上docker0的bridge網絡:
一開始它的網卡狀況以下所示:
root@9e11c1b9e90d:/# ip a 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 2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1 link/ipip 0.0.0.0 brd 0.0.0.0 3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1 link/tunnel6 :: brd :: 18: eth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:14:0b:08 brd ff:ff:ff:ff:ff:ff inet 172.20.11.8/24 brd 172.20.11.255 scope global eth0 valid_lft forever preferred_lft forever
而後爲該容器添加bridge網絡:
userdeMacBook-Pro:~ user$ docker network connect bridge 9e11c1b9e90d
而後咱們就可以看見它多了一個網卡,地址爲172.17.0.5/16
root@9e11c1b9e90d:/# ip a 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 2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1 link/ipip 0.0.0.0 brd 0.0.0.0 3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1 link/tunnel6 :: brd :: 18: eth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:14:0b:08 brd ff:ff:ff:ff:ff:ff inet 172.20.11.8/24 brd 172.20.11.255 scope global eth0 valid_lft forever preferred_lft forever 20: eth1@if21: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff inet 172.17.0.5/16 brd 172.17.255.255 scope global eth1 valid_lft forever preferred_lft forever
而後再次嘗試ping ubuntu5的容器,發現可以成功ping通了:
root@9e11c1b9e90d:/# ping -c 3 172.17.0.4 PING 172.17.0.4 (172.17.0.4) 56(84) bytes of data. 64 bytes from 172.17.0.4: icmp_seq=1 ttl=64 time=0.133 ms 64 bytes from 172.17.0.4: icmp_seq=2 ttl=64 time=0.110 ms 64 bytes from 172.17.0.4: icmp_seq=3 ttl=64 time=0.165 ms --- 172.17.0.4 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2108ms rtt min/avg/max/mdev = 0.110/0.136/0.165/0.022 ms
若是你想要解除上面ubuntu5的bridge網絡鏈接:
userdeMacBook-Pro:~ user$ docker network disconnect bridge 9e11c1b9e90d