了解Docker容器網(wǎng)絡(luò)

Docker Engine -> User guide -> Network configuration -> Docker container networking

了解Docker容器網(wǎng)絡(luò)

利用Docker的網(wǎng)絡(luò)功能去構(gòu)件一個(gè)web app會(huì)更安全。Docker的network可以為容器提供一個(gè)完全隔離的網(wǎng)絡(luò)環(huán)境。能夠掌控運(yùn)行的app網(wǎng)絡(luò)對(duì)你是非常重要的。Docker的容器網(wǎng)絡(luò)可以給予你這個(gè)掌控網(wǎng)絡(luò)的能力。

這一節(jié)關(guān)于Docker Engine原生提供的默認(rèn)的網(wǎng)絡(luò)行為。描述了默認(rèn)創(chuàng)建的或是屬于你自己的用戶自定義的network類(lèi)型,還有當(dāng)創(chuàng)建一個(gè)network在單主機(jī)或是一個(gè)跨主機(jī)集群中需要的資源。

默認(rèn)的網(wǎng)絡(luò)

當(dāng)你安裝Docker后,它會(huì)自動(dòng)創(chuàng)建三個(gè)network,你可以使用命令:docker network ls 列出它們:

$ docker network ls
NETWORK ID          NAME                DRIVER
7fca4eb8c647        bridge              bridge
9f904ee27bf5        none                null
cf03ee007fb4        host                host

從歷史上看,這三個(gè)network是Docker實(shí)現(xiàn)的一部分。當(dāng)你運(yùn)行一個(gè)container時(shí),你可以用--net 標(biāo)志去指定這個(gè)container運(yùn)行在哪一種network上。這三種network你都可以使用。

這個(gè)bridgenetwork 代表所有安裝了Docker的主機(jī)的docker0 network。除非使用docker run --set=<NETWORK>選項(xiàng)指定一個(gè)其它的network,否則Docker daemon會(huì)默認(rèn)使用這個(gè)network連接contrainer。你可以使用系統(tǒng)的ifconfig命令查看主機(jī)的network stack中的docker0:

$ ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:47:bc:3a:eb  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:47ff:febc:3aeb/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:17 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1100 (1.1 KB)  TX bytes:648 (648.0 B)

這個(gè)nonenetwork 會(huì)將容器添加到一個(gè) container-specific 的 network stack。這個(gè)容器缺少一個(gè)network interface。如果你想連接這個(gè)容器并查看它的stack,你可以這樣:

// use the commond "docker attach <container-name>" to attaching this container
$ docker attach nonenetcontainer

root@0cb243cd1293:/# 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
root@0cb243cd1293:/# ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          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:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

root@0cb243cd1293:/#

注意:你可以通過(guò) CTRL-p CTRL-q 脫離容器。

這個(gè)hostnetwork,將container添加到主機(jī)的network stack。你會(huì)發(fā)現(xiàn)這個(gè)container的網(wǎng)絡(luò)配置與主機(jī)是一致的。

除了bridgenetwork,你可能不需要其他的默認(rèn)network。雖然你可以列出并查看這些network,但是你不能刪除它們。這些是Docker所需要的。然而你可以添加屬于你的自定義network,當(dāng)你不再需要這些network的時(shí)候你可以刪除它們。在你了解更多關(guān)于創(chuàng)建屬于你自己的network之前,默認(rèn)的bridgenetwork還是值得你看看的。

詳解brigdenetwork

這個(gè)默認(rèn)的bridgenetwork存在于所有的Docker主機(jī)。docker network inspect命令可以返回關(guān)于network的信息:

$ docker network inspect bridge
[
   {
       "Name": "bridge",
       "Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f",
       "Scope": "local",
       "Driver": "bridge",
       "IPAM": {
           "Driver": "default",
           "Config": [
               {
                   "Subnet": "172.17.0.1/16",
                   "Gateway": "172.17.0.1"
               }
           ]
       },
       "Containers": {},
       "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": "9001"
       }
   }
]

Docker Engine 會(huì)自動(dòng)創(chuàng)建一個(gè) SubnetGateway在這個(gè)network。docker run命令自動(dòng)添加一個(gè)新的container到這個(gè)network:

$ docker run -itd --name=container1 busybox
3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c

$ docker run -itd --name=container2 busybox
94447ca479852d29aeddca75c28f7104df3c3196d7b6d83061879e339946805c

在啟動(dòng)兩個(gè)新的container之后,查看一下bridge網(wǎng)絡(luò)。這兩個(gè)容器的id會(huì)出現(xiàn)在 Containers這個(gè)字段中:

$ docker network inspect bridge
{[
    {
        "Name": "bridge",
        "Id": "f7ab26d71dbd6f557852c7156ae0574bbf62c42f539b50c8ebde0f728a253b6f",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {
                    "Subnet": "172.17.0.1/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Containers": {
            "3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c": {
                "EndpointID": "647c12443e91faf0fd508b6edfe59c30b642abb60dfab890b4bdccee38750bc1",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "94447ca479852d29aeddca75c28f7104df3c3196d7b6d83061879e339946805c": {
                "EndpointID": "b047d090f446ac49747d3c37d63e4307be745876db7f0ceef7b311cbba615f48",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/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": "9001"
        }
    }
]

上面是 docker network inspect命令根據(jù)給定的network回顯的這個(gè)network已連接的容器和它的一些網(wǎng)絡(luò)資源。在這個(gè)默認(rèn)的network中的container可以利用IP地址相互通信。在默認(rèn)的bridgenetwork中Docker不支持自動(dòng)的服務(wù)發(fā)現(xiàn)。如果你的container想要通過(guò)其他container的name在這個(gè)默認(rèn)的bridgenetwork中通行,你必須通過(guò)docker run --linke選項(xiàng)來(lái)實(shí)現(xiàn)。

你可以attach一個(gè)正在運(yùn)行的container并查看它的網(wǎng)絡(luò)配置:

$ docker attach container1

root@0cb243cd1293:/# ifconfig
ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1296 (1.2 KiB)  TX bytes:648 (648.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          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:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

然后使用ping命令來(lái)做一個(gè)3秒測(cè)試,測(cè)試這個(gè)在bridgenetwork上的container的連通性。

root@0cb243cd1293:/# ping -w3 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.096 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.080 ms
64 bytes from 172.17.0.3: seq=2 ttl=64 time=0.074 ms

--- 172.17.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.074/0.083/0.096 ms

最后,使用cat命令來(lái)檢查container1的網(wǎng)絡(luò)配置:

root@0cb243cd1293:/# cat /etc/hosts
172.17.0.2  3386a527aa08
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

使用CTRL-p CTRL-q脫離container1后,連接到container2并重復(fù)這三個(gè)命令。

$ docker attach container2

root@0cb243cd1293:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03  
          inet addr:172.17.0.3  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:15 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1166 (1.1 KiB)  TX bytes:1026 (1.0 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          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:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

root@0cb243cd1293:/# ping -w3 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=0.067 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.075 ms
64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.072 ms

--- 172.17.0.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.067/0.071/0.075 ms
/ # cat /etc/hosts
172.17.0.3  94447ca47985
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

這個(gè)默認(rèn)的橋接網(wǎng)絡(luò)docker0支持使用端口映射和通過(guò)docker run --link使兩個(gè)在docker0中的container可以彼此通信。這些方式設(shè)置起來(lái)很麻煩并且容易出錯(cuò)。雖然你仍然可以這樣使用,但是最好避免這樣,更推薦你去定義你自己的橋接網(wǎng)路來(lái)替代它。

自定義的network

你可以創(chuàng)建屬于你的自定義network來(lái)更好的隔離container。為了創(chuàng)建這些network,Docker提供了一些默認(rèn)的network drivers。你可以創(chuàng)建一個(gè)新的bridge network或者overlay network。你也可以創(chuàng)建一個(gè)network plugin或是一個(gè)remote network

你可以創(chuàng)建多個(gè)網(wǎng)絡(luò)。可以添加一個(gè)container到多個(gè)網(wǎng)絡(luò)。container只能在這個(gè)網(wǎng)絡(luò)中通行不能跨越這個(gè)網(wǎng)絡(luò)。一個(gè)container可以附著到兩個(gè)network中,并分別與這兩個(gè)network中的container成員通信。

接下來(lái)的幾節(jié)更加詳細(xì)的描述每一個(gè)Docker內(nèi)建的網(wǎng)絡(luò)驅(qū)動(dòng)。

橋接網(wǎng)絡(luò)(bridge network)

很容易就可以創(chuàng)建一個(gè)自定義的bridge模式的network。這個(gè)network和docker0很像。這里又一些已添加的功能和一些已經(jīng)不可用的舊功能。

$ docker network create --driver bridge isolated_nw
1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b

$ docker network inspect isolated_nw
[
    {
        "Name": "isolated_nw",
        "Id": "1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1/16"
                }
            ]
        },
        "Containers": {},
        "Options": {}
    }
]

$ docker network ls
NETWORK ID          NAME                DRIVER
9f904ee27bf5        none                null
cf03ee007fb4        host                host
7fca4eb8c647        bridge              bridge
c5ee82f76de3        isolated_nw         bridge

創(chuàng)建這個(gè)network之后,你可以使用這個(gè)創(chuàng)建的network通過(guò)docker run --net=<NETWORK>選項(xiàng)啟動(dòng)一個(gè)container。

$ docker run --net=isolated_nw -itd --name=container3 busybox
8c1a0a5be480921d669a073393ade66a3fc49933f08bcc5515b37b8144f6d47c

$ docker network inspect isolated_nw
[
    {
        "Name": "isolated_nw",
        "Id": "1196a4c5af43a21ae38ef34515b6af19236a3fc48122cf585e3f3054d509679b",
        "Scope": "local",
        "Driver": "bridge",
        "IPAM": {
            "Driver": "default",
            "Config": [
                {}
            ]
        },
        "Containers": {
            "8c1a0a5be480921d669a073393ade66a3fc49933f08bcc5515b37b8144f6d47c": {
                "EndpointID": "93b2db4a9b9a997beb912d28bcfc117f7b0eb924ff91d48cfa251d473e6a9b08",
                "MacAddress": "02:42:ac:15:00:02",
                "IPv4Address": "172.21.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {}
    }
]

推入到這個(gè)network的container必須存在于同一個(gè)Docker主機(jī)。每一個(gè)network中的container可以立即與在這個(gè)network中的其它c(diǎn)ontainer通信。這個(gè)network將外部網(wǎng)絡(luò)與其內(nèi)部的container隔離開(kāi)來(lái)。

用戶自定義的橋接網(wǎng)絡(luò)是不支持link的。你可以將這個(gè)network中開(kāi)放的container的端口暴露出來(lái)。如果你想使一部分橋接網(wǎng)絡(luò)開(kāi)放給外部網(wǎng)絡(luò)這是很有用的。

一個(gè)bridgenetwork在單主機(jī)的相對(duì)較小的網(wǎng)絡(luò)環(huán)境中是很有用的一種解決方案。然而當(dāng)需要?jiǎng)?chuàng)建一個(gè)很龐大的網(wǎng)絡(luò)環(huán)境的時(shí)候你需要一個(gè)overlaynetwork.

覆蓋網(wǎng)絡(luò)(overlay network)

Docker的overlaynetwork 驅(qū)動(dòng)原生就支持一個(gè)多主機(jī)網(wǎng)絡(luò)。這種支持是在libnetwork的幫助下完成的,一個(gè)內(nèi)建的基于VXLANoverlaynetwork驅(qū)動(dòng)還有Docker的libkv庫(kù)。

這個(gè)overlaynetwork需要一個(gè)有效的key-value存貯服務(wù)。當(dāng)前,Docker的libkv支持Consul,Etcd和ZooKeeper(分布式存貯)。在創(chuàng)建這樣一個(gè)網(wǎng)絡(luò)之前你必須安裝配置一個(gè)你選用的key-value存貯服務(wù)。你創(chuàng)建network的Docker主機(jī)必須能夠與服務(wù)通信。


這個(gè)network中的主機(jī)必須運(yùn)行Docker Engine實(shí)例。最簡(jiǎn)單的方式是為每個(gè)主機(jī)提供一個(gè)Docker Machine。


你應(yīng)當(dāng)在每個(gè)主機(jī)上打開(kāi)下面的端口。

Protocol Port Description
udp 4789 Data plane(VXLAN)
tcp/udp 7946 Control plane

你的key-value存貯服務(wù)可能需要額外的端口。檢查你的供應(yīng)商文檔然后打開(kāi)所有需要的端口。

自定義的網(wǎng)絡(luò)插件

Docker中嵌入DNS服務(wù)

Links

Related information

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容