docker安裝完以后,自動(dòng)提供了3種網(wǎng)絡(luò):
創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),禹會(huì)企業(yè)網(wǎng)站建設(shè),禹會(huì)品牌網(wǎng)站建設(shè),網(wǎng)站定制,禹會(huì)網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,禹會(huì)網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
9ac63d7fc6e8 bridge bridge local
b46032ae4b5f host host local
60f69f2c7987 none null local
$
使用 inspect 命令可以查看docker對(duì)象的底層信息。比如可以查看容器的信息,其中網(wǎng)絡(luò)部分的信息如下:
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": n ll,
"NetworkID": "9ac63d7fc6e871eb47e39f9ec4e3fda6a23cb95a906a9ddc6431ed716e000fa1",
"EndpointID": "c8b64271d3d7ea5a0a8357c51fa5c80d398dbd07ad7e920792ebbaab628cb00d",
"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
}
}
這里可以查看容器內(nèi)部網(wǎng)卡的IP地址。
每一個(gè)容器都有各自一組獨(dú)立的6個(gè)Namespaces:Mount、PID、User、UTS、IPC、Network。
還有一種方案,讓每一個(gè)容器值只擁有獨(dú)立的Mount、PID、User。而其他的3個(gè)UTS、IPC、Network是共享的。就是有自己隔離的名稱空間,但也可以共享其中一部分名稱空間。一般只共享網(wǎng)絡(luò)通信相關(guān)的,主機(jī)名(UTS)、進(jìn)程間通信(IPC)、網(wǎng)絡(luò)(Network)。
這樣做帶來了一個(gè)便利?,F(xiàn)在不同的容器共享了網(wǎng)絡(luò)接口,使用的是同一個(gè)網(wǎng)絡(luò)。每個(gè)容器內(nèi)部的lo接口是同一個(gè)lo接口。這樣一個(gè)容器只要往本地的lo接口發(fā)請(qǐng)求,或者是往127.0.0.1發(fā)請(qǐng)求,共享網(wǎng)絡(luò)接口的其他容器也能夠接收到。
直接和宿主機(jī)共享名稱空間
還是上面的共享名稱空間,還可以直接和宿主機(jī)共享名稱空間。那么這個(gè)和宿主機(jī)共享名稱空間的容器,容器內(nèi)部的接口就是宿主機(jī)的網(wǎng)絡(luò)接口。容器對(duì)網(wǎng)絡(luò)的修改也就是對(duì)宿主機(jī)的網(wǎng)絡(luò)進(jìn)行了修改。這個(gè)容器就有了管理網(wǎng)絡(luò)的特權(quán)。
這種就是網(wǎng)絡(luò)類型中的host類型,就是讓容器使用宿主機(jī)的網(wǎng)絡(luò)名稱空間。
Docker一共有4種網(wǎng)絡(luò)模型
Bridged containers
橋接式容器一般擁有兩個(gè)接口:一個(gè)環(huán)回接口和一個(gè)連接至主機(jī)上某橋設(shè)備的以太網(wǎng)接口。
docker啟動(dòng)時(shí)默認(rèn)會(huì)創(chuàng)建一個(gè)名為docker0的網(wǎng)絡(luò)橋,并且創(chuàng)建的容器為橋接式容器,其以太網(wǎng)接口橋接至docker0。
docker0橋?yàn)镹ET橋,因此橋接式容器可通過此橋接口訪問外部網(wǎng)絡(luò)。
Closed containers
不參與網(wǎng)絡(luò)通信,運(yùn)行于此容器中的進(jìn)程僅能訪問本地環(huán)回接口。
僅適用于進(jìn)程無須網(wǎng)絡(luò)通信的場(chǎng)景中,例如備份、進(jìn)程診斷及各種離線任務(wù)等。
創(chuàng)建容器時(shí)(run或create),使用參數(shù)可以對(duì)容器的網(wǎng)絡(luò)進(jìn)行設(shè)定。
使用--nework參數(shù)可以指定容器的網(wǎng)絡(luò)模式,默認(rèn)值是default,這個(gè)就是bridge模式。
brideg模式
正常啟動(dòng)容器,不使用任何網(wǎng)絡(luò)參數(shù):
$ docker container run --name b1 --rm -it busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12 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:1032 (1.0 KiB) 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:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ #
以默認(rèn)的網(wǎng)絡(luò)模式啟動(dòng)容器。如果啟動(dòng)容器是加上參數(shù)--network bridge
效果也是一樣的。
none模式
使用--network none啟動(dòng)一個(gè)沒有任何網(wǎng)絡(luò)的容器:
$ docker container run --name b1 --rm -it --network none busybox
/ # ifconfig -a
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:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ #
這里顯示,只有一個(gè)lo接口,沒有其他網(wǎng)絡(luò)接口。
其他網(wǎng)絡(luò)模式
剩下的還有host模式和聯(lián)盟式網(wǎng)絡(luò),這部分需要單獨(dú)再展開說明。
在網(wǎng)絡(luò)上提供服務(wù)的時(shí)候,一般不是直接提供IP地址。而是提供主機(jī)名或域名,不但方便記憶也會(huì)有一些其他的便利。所以Docker容器的主機(jī)名也是一個(gè)重要的網(wǎng)絡(luò)屬性。
主機(jī)名
容器的主機(jī)名就是它的ID:
/ # hostname
6fb514e1fa3b
/ #
可以在啟動(dòng)容器時(shí),使用-h參數(shù)來設(shè)定容器的主機(jī)名:
$ docker container run --name b1 --rm -it -h b1.busybox busybox
/ # hostname
b1.busybox
/ #
DNS服務(wù)器
先看一下默認(rèn)使用的DNS服務(wù)器,就是網(wǎng)關(guān)的地址:
/ # cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 192.168.1.1
/ # nslookup -type=a baidu.com
Server: 192.168.1.1
Address: 192.168.1.1:53
Non-authoritative answer:
Name: baidu.com
Address: 220.181.38.148
Name: baidu.com
Address: 123.125.114.144
/ #
使用參數(shù)指定DNS服務(wù)器啟動(dòng)容器,然后查看容器的DNS的設(shè)置:
$ docker container run --name b1 --rm -it -h b1.busybox --dns 223.5.5.5 busybox
/ # cat /etc/resolv.conf
nameserver 223.5.5.5
/ #
搜索域
另外還有個(gè)參數(shù)是--dns-search,是用來指定搜索域的。這個(gè)搜索域就是當(dāng)給的名稱不是FQDN主機(jī)名格式的時(shí)候,自動(dòng)補(bǔ)的后綴。
$ docker container run --name b1 --rm -it -h b1.busybox --dns 223.5.5.5 --dns-search baidu.com busybox
/ # cat /etc/resolv.conf
search baidu.com
nameserver 223.5.5.5
/ # nslookup -type=a www
Server: 223.5.5.5
Address: 223.5.5.5:53
Non-authoritative answer:
www.baidu.com canonical name = www.a.shifen.com
Name: www.a.shifen.com
Address: 39.156.66.14
Name: www.a.shifen.com
Address: 39.156.66.18
/ #
指定主機(jī)名的時(shí)候,沒有給完整的域名后綴,不過因?yàn)樵O(shè)置了搜索域,所以就自動(dòng)補(bǔ)全了。
hosts文件
除了域名服務(wù)器,還可以通過本地hosts文件來管理主機(jī)名:
$ docker container run --name b1 --rm -it -h busybox1.idx.net --dns 223.5.5.5 --dns-search idx.net busybox
/ # 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.2 busybox1.idx.net busybox1
/ #
可以看到默認(rèn)就把主機(jī)名寫入到本地的hosts文件中了。這里加了2個(gè)名稱,前一個(gè)是完整的主機(jī)名,后一個(gè)是主機(jī)名除去后綴的部分。
還可以使用參數(shù)向hosts文件中注入信息:
$ docker container run --name b1 --rm -it -h busybox1.idx.net --dns 223.5.5.5 --dns-search idx.net --add-host host1.idx.net:192.168.100.1 --add-host host2.idx.net:192.168.100.2 busybox
/ # 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
192.168.100.1 host1.idx.net
192.168.100.2 host2.idx.net
172.17.0.2 busybox1.idx.net busybox1
/ #
添加記錄使用(host:ip)的格式。這個(gè)參數(shù)是list屬性,如果有多個(gè)記錄,就調(diào)用多次參數(shù)。
Docker0為NET橋,因此容器獲得的是私有網(wǎng)絡(luò)地址(內(nèi)網(wǎng)地址)。
從拓?fù)浣Y(jié)構(gòu)上看,容器就是一臺(tái)在宿主機(jī)NET服務(wù)之后的一臺(tái)主機(jī)。如果容器需要對(duì)外提供服務(wù),就要在宿主機(jī)上為其定義DNAT規(guī)則。
-p選項(xiàng)的使用格式
-p
將指定的容器端口映射至主機(jī)所有地址的一個(gè)動(dòng)態(tài)端口
-p :
將容器端口containerPort映射至主機(jī)端口hostPort
-p ::
將指定的容器端口containerPort映射至主機(jī)指定ip的動(dòng)態(tài)端口
命令中間是兩個(gè)冒號(hào),相當(dāng)于下面的3個(gè)變量的命令省略了中間的變量。
-p ::
將指定的容器端口containerPort映射至主機(jī)指定ip的端口hostPort
動(dòng)態(tài)端口指隨機(jī)端口,具體映射結(jié)果可以使用docker port
命令查看
-P(大寫),隨機(jī)映射端口到內(nèi)部容器開放的所有網(wǎng)絡(luò)端口。
這里開放的網(wǎng)絡(luò)端口是鏡像制作時(shí)設(shè)定的,啟動(dòng)容器時(shí)也可以使用參數(shù)--expose指定計(jì)劃要開放的端口。只有使用-P參數(shù),才需要指定具體要開放哪些端口,可以是鏡像中設(shè)定也可以是參數(shù)--expose設(shè)定。使用-p參數(shù)時(shí),是指定要映射的端口,所處沒有設(shè)置要開放的端口也沒問題。
可以指定使用的協(xié)議,默認(rèn)是tcp。udp需要指定
-p 127.0.0.1:5000:5000/udp
-p參數(shù)可以多次使用來綁定多個(gè)端口
用httpd鏡像測(cè)試端口映射
不使用端口映射:
$ docker container run -dit --name app1 --rm httpd:alpine
78e4e42fdd0c33a0410077731d26e418423a27827ab62e83dfe×××bca40f671
$ curl http://172.17.0.2
It works!
$ curl http://127.0.0.1
curl: (7) Failed connect to 127.0.0.1:80; 拒絕連接
$
由于沒有做端口映射,容器可以通過NAT訪問外部網(wǎng)絡(luò),但是無法被外部網(wǎng)絡(luò)訪問到,就是容器沒有暴露任何接口到公網(wǎng)。宿主機(jī)可以通過容器的私網(wǎng)地址訪問頁面,但是無法通過宿主機(jī)的接口地址訪問頁面,這樣外網(wǎng)也無法訪問到頁面。
使用-P參數(shù):
$ docker container run -dit --name app1 --rm -P httpd:alpine
fde094cc000be912e68b8f6321f38d97c76cbabb54454da11c65e0aabd90dc1e
$ docker container port app1
80/tcp -> 0.0.0.0:32769
$ curl http://127.0.0.1:32769
It works!
$
這次可以用個(gè)宿主機(jī)的環(huán)回口訪問了,直接用瀏覽器使用宿主機(jī)的地址也能夠訪問。但是端口是隨機(jī)的,這就是需要使用port命令查看隨機(jī)分配的端口號(hào)。
聯(lián)盟式是容器之間共享網(wǎng)絡(luò)名稱空間,而開放式是容器共享使用宿主機(jī)的網(wǎng)絡(luò)名稱空間。在原理上這兩者是一樣的。
聯(lián)盟式容器(joined containrs),是指使用某個(gè)已經(jīng)存在容器的網(wǎng)絡(luò)接口的容器。接口被聯(lián)盟內(nèi)的各容器共享使用。
聯(lián)盟式容器彼此間共享的是同一個(gè)網(wǎng)絡(luò)名稱空間,UTS、IPC、Network。其他名稱空間還是隔離的,Mount、PID、User。
聯(lián)盟式容器彼此間存在端口沖突的可能性。因此,通常只會(huì)在多個(gè)容器上的程序需要程序loopback接口互相通信、或?qū)δ骋汛娴娜萜鞯木W(wǎng)絡(luò)屬性進(jìn)行監(jiān)控時(shí)才使用此種模式的網(wǎng)絡(luò)類型。
介紹共享網(wǎng)絡(luò)名稱空間的時(shí)候,也講過共享后的便利,就是多個(gè)容器可以使用本地環(huán)回口實(shí)現(xiàn)互相間的通信。
啟動(dòng)第一個(gè)容器
使用交互式接口,開啟一個(gè)容器:
$ docker container run --name b1 --rm -it busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 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:516 (516.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:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ #
啟動(dòng)第二個(gè)容器
上一個(gè)終端被占用著,所以再開一個(gè)終端依然使用交互式接口開啟第二個(gè)容器。這里多了--network參數(shù),就是建立聯(lián)盟式容器的:
$ docker container run --name b2 --rm -it --network container:b1 busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 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:656 (656.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:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ #
查看兩個(gè)容器的ip地址、MAC地址,可見兩個(gè)容器的網(wǎng)絡(luò)接口是同一個(gè)。效果就相當(dāng)于傳統(tǒng)模式時(shí),同一個(gè)主機(jī)里的兩個(gè)進(jìn)程。和傳統(tǒng)的模式相比,容器之間有更多個(gè)隔離。
聯(lián)盟式容器的應(yīng)用場(chǎng)景
聯(lián)盟式容器可以直接向本地的lo接口發(fā)送請(qǐng)求,聯(lián)盟的其他容器也可以收到這個(gè)請(qǐng)求,就好比聯(lián)盟中的容器是運(yùn)行在同一個(gè)主機(jī)上的兩個(gè)進(jìn)程一樣。
比如,首先有一個(gè)brideg模式的容器,提供一個(gè)靜態(tài)Web頁面的服務(wù)。然后對(duì)于動(dòng)態(tài)頁面的請(qǐng)求則發(fā)送給另外一個(gè)容器處理。
這時(shí)啟動(dòng)第二個(gè)動(dòng)態(tài)頁面的容器。如果這個(gè)容器也是brideg模式,由于ip地址出動(dòng)態(tài)獲得的,那么靜態(tài)頁面容器就無法確定向哪個(gè)ip地址發(fā)送請(qǐng)求。此時(shí)如果這兩個(gè)容器是聯(lián)盟式的網(wǎng)絡(luò),直接向本地的lo接口發(fā)送請(qǐng)求就可以了。
要使用開放式網(wǎng)絡(luò),指定--network的參數(shù)為host即可:
[root@Docker ~]# docker container run --name b3 --rm -it --network host busybox
/ # ifconfig
docker0 Link encap:Ethernet HWaddr 02:42:3C:BE:06:75
inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0
inet6 addr: fe80::42:3cff:febe:675/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:71 errors:0 dropped:0 overruns:0 frame:0
TX packets:82 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:4773 (4.6 KiB) TX bytes:7313 (7.1 KiB)
eth0 Link encap:Ethernet HWaddr 00:15:5D:03:67:56
inet addr:192.168.24.170 Bcast:192.168.24.175 Mask:255.255.255.240
inet6 addr: fe80::4c95:4028:8e1:a795/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:36462 errors:0 dropped:0 overruns:0 frame:0
TX packets:20392 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:42167574 (40.2 MiB) TX bytes:1953899 (1.8 MiB)
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:48 errors:0 dropped:0 overruns:0 frame:0
TX packets:48 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3777 (3.6 KiB) TX bytes:3777 (3.6 KiB)
/ #
不要退出終端,繼續(xù)在容器里開放一個(gè)httpd:
/ # echo "Hello b3, network host
" > /var/www/index.html
/ # httpd -h /var/www/
/ # netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 192.168.24.170:10010 0.0.0.0:* LISTEN
tcp 0 0 :::80 :::* LISTEN
tcp 0 0 :::22 :::* LISTEN
tcp 0 0 ::1:25 :::* LISTEN
/ #
啟動(dòng)httpd服務(wù)后,也檢查了本地監(jiān)聽端口,沒有問題。
防火墻問題
在宿主機(jī)上是可以直接訪問這個(gè)Web頁面的:
$ curl 172.17.0.1
Hello b3, network host
$
但是外部網(wǎng)絡(luò)依然無法訪問,這個(gè)主要是宿主機(jī)的防火墻問題。
之前也開放過服務(wù),并且訪問都沒有問題。這個(gè)應(yīng)該是宿主機(jī)將訪問容器的流量都默認(rèn)放行了。而這次是要直接訪問宿主機(jī),雖然服務(wù)是在容器內(nèi)的,但是使用的網(wǎng)絡(luò)是宿主機(jī)的,所以需要防火墻放開策略。
臨時(shí)開放宿主機(jī)上的http服務(wù)
$ firewall-cmd --add-service=http
success
$ firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: ssh dhcpv6-client http
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
$
這個(gè)只是臨時(shí)測(cè)試,防火墻firewalld服務(wù)重啟后就會(huì)回復(fù)原樣。
宿主機(jī)防火墻策略開放后,就可以使用瀏覽器訪問宿主機(jī)的80端口打開頁面了。
開放式容器的應(yīng)用場(chǎng)景
部署方式簡單,方便遷移。充分利用容器的優(yōu)勢(shì),并能保證程序工作在宿主機(jī)上的要求,至少是通過宿主機(jī)的網(wǎng)絡(luò)接口對(duì)外提供服務(wù)。
以開放式容器的方式運(yùn)行和進(jìn)程差不多。都是在一個(gè)機(jī)器上運(yùn)行多個(gè)進(jìn)程。進(jìn)程之間原本就是互相隔離的,但是使用容器后,還可以隔離文件系統(tǒng)和用戶。另外一個(gè)好處就是部署和遷移方便。以往工作為宿主機(jī)首部進(jìn)程的那些系統(tǒng)級(jí)管理的進(jìn)程,以后就可以使用容器的方式來運(yùn)行。
上一節(jié)的內(nèi)容是使用docker默認(rèn)創(chuàng)建好的3個(gè)網(wǎng)絡(luò),容器選擇其中一個(gè)網(wǎng)絡(luò),并在運(yùn)行容器時(shí)對(duì)可選的參數(shù)進(jìn)行設(shè)置。
本節(jié)的內(nèi)容是不使用默認(rèn)提供的網(wǎng)絡(luò),而是先對(duì)網(wǎng)絡(luò)進(jìn)行自定義。自定義有兩種實(shí)現(xiàn)方式,一種是對(duì)默認(rèn)的網(wǎng)絡(luò)進(jìn)行修改,還有一種是完全創(chuàng)建一個(gè)新的網(wǎng)絡(luò)。
默認(rèn)設(shè)置,docker使用的是172.17.0.1/16的網(wǎng)絡(luò)。這個(gè)網(wǎng)絡(luò)的網(wǎng)絡(luò)類型是bridge,對(duì)應(yīng)的網(wǎng)絡(luò)名稱也是bridge,對(duì)應(yīng)在宿主機(jī)上的網(wǎng)卡是docker0。
使用ifconfig命令查看docker0橋的信息:
$ ifconfig
docker0: flags=4099 mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:3cff:febe:675 prefixlen 64 scopeid 0x20
ether 02:42:3c:be:06:75 txqueuelen 0 (Ethernet)
RX packets 71 bytes 4773 (4.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 82 bytes 7313 (7.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
這個(gè)默認(rèn)的dockr0橋接口是可以修改的。另外還可以額外定義新的橋接口網(wǎng)絡(luò)。
docker0橋是在docker daemon啟動(dòng)時(shí)創(chuàng)建的,會(huì)根據(jù)默認(rèn)屬性自動(dòng)創(chuàng)建,也可以通過修改配置文件來進(jìn)行自定義。
配置文件就是/etc/docker/daemon.json
,在添加鏡像加速器的時(shí)候已經(jīng)用過了。主要的屬性有如下這些:
json配置內(nèi)容示例:
{
"bip": "192.168.10.1/24",
"fixed-cidr": "192.168.10.128/25",
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,
"default-gateway": "192.168.1.1",
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["114.114.114.114", "223.5.5.5"]
}
核心選項(xiàng)是bip(bridge ip),用于指定docker0橋自身的IP地址。根據(jù)需要進(jìn)行自定義,可以只設(shè)置一個(gè)bip,其他保持默認(rèn)。其他選項(xiàng)會(huì)根據(jù)bip自動(dòng)計(jì)算得出,還有一些是默認(rèn)使用宿主機(jī)的網(wǎng)絡(luò)屬性。
實(shí)際修改本機(jī)的配置
修改后的配置文件如下:
{
"registry-mirrors": ["http://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn"],
"bip": "192.168.101.1/24",
"fixed-cidr": "192.168.101.128/25",
"dns": ["114.114.114.114", "223.5.5.5"]
}
重啟服務(wù)后,先查看宿主機(jī)的docker0橋:
$ systemctl restart docker
$ ifconfig
docker0: flags=4099 mtu 1500
inet 192.168.101.1 netmask 255.255.255.0 broadcast 192.168.101.255
inet6 fe80::42:3cff:febe:675 prefixlen 64 scopeid 0x20
ether 02:42:3c:be:06:75 txqueuelen 0 (Ethernet)
RX packets 81 bytes 5445 (5.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 92 bytes 8125 (7.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
此時(shí)docker0的網(wǎng)絡(luò)屬性已經(jīng)變了。
新建容器查看網(wǎng)絡(luò)
創(chuàng)建容器,查看容器內(nèi)的網(wǎng)絡(luò)屬性:
$ docker container run --name b4 --rm -it busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:65:80
inet addr:192.168.101.128 Bcast:192.168.101.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:516 (516.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:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ # cat /etc/resolv.conf
nameserver 114.114.114.114
nameserver 223.5.5.5
/ # exit
$
這里可以確認(rèn)到自動(dòng)獲取的ip地址也符合設(shè)置要求了,還有dns服務(wù)器的地址也是自定義的。
查看已有的網(wǎng)絡(luò):
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
8ec74d5bd709 bridge bridge local
d086953087bb host host local
fa0c7f1fb6ca none null local
$
查看網(wǎng)絡(luò)插件
這里先展開一下,看看docker支持哪些類型的網(wǎng)絡(luò)。
命令docker info里的插件Plugins的內(nèi)容:
$ docker info
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
在Network插件中,除了bridge、host、nul之外,還有overlay(疊加網(wǎng)絡(luò))、macvlan(基于mac的vlan虛擬網(wǎng)絡(luò)),這兩種網(wǎng)絡(luò)類型沒有展開。這些網(wǎng)絡(luò)插件在下面創(chuàng)建網(wǎng)路時(shí),通過-d參數(shù)可以指定,默認(rèn)是bridge。
創(chuàng)建網(wǎng)絡(luò)
使用命令docker network create
命令來創(chuàng)建網(wǎng)絡(luò):
$ docker network create -d bridge --subnet "192.168.111.0/24" mybr1
7128a28bbbf39a6ca483ecad03d5d85c8179507aff66ced73ca8de5233f16fee
[root@Docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8ec74d5bd709 bridge bridge local
d086953087bb host host local
7128a28bbbf3 mybr1 bridge local
fa0c7f1fb6ca none null local
[root@Docker ~]# ifconfig
br-7128a28bbbf3: flags=4099 mtu 1500
inet 192.168.111.1 netmask 255.255.255.0 broadcast 192.168.111.255
ether 02:42:1f:ff:fd:5d txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4099 mtu 1500
inet 192.168.101.1 netmask 255.255.255.0 broadcast 192.168.101.255
inet6 fe80::42:3cff:febe:675 prefixlen 64 scopeid 0x20
ether 02:42:3c:be:06:75 txqueuelen 0 (Ethernet)
RX packets 81 bytes 5445 (5.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 92 bytes 8125 (7.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
-d參數(shù)可以省略,默認(rèn)就是bridge。更多的參數(shù)可以使用--help選項(xiàng)查看:
指定網(wǎng)卡的名稱
在ifconfig查看的時(shí)候,網(wǎng)卡顯示的名稱是根據(jù)這個(gè)docker網(wǎng)絡(luò)額ID號(hào)自動(dòng)生成的。在創(chuàng)建網(wǎng)絡(luò)時(shí)使用-o參數(shù)可以進(jìn)行指定:
$ docker network create --subnet "192.168.112.0/24" -o "com.docker.network.bridge.name=docker1" mybr2
b8a2639ce1baef83e54b5a0bca5ba6c7bbd2e6b607e62016c930350235bea965
$ ifconfig
br-7128a28bbbf3: flags=4099 mtu 1500
inet 192.168.111.1 netmask 255.255.255.0 broadcast 192.168.111.255
ether 02:42:1f:ff:fd:5d txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4099 mtu 1500
inet 192.168.101.1 netmask 255.255.255.0 broadcast 192.168.101.255
inet6 fe80::42:3cff:febe:675 prefixlen 64 scopeid 0x20
ether 02:42:3c:be:06:75 txqueuelen 0 (Ethernet)
RX packets 81 bytes 5445 (5.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 92 bytes 8125 (7.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker1: flags=4099 mtu 1500
inet 192.168.112.1 netmask 255.255.255.0 broadcast 192.168.112.255
ether 02:42:74:95:cd:0b txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
這次創(chuàng)建的網(wǎng)卡的名字就舒服多了。
關(guān)于-o參數(shù),主要有下面這些:
選項(xiàng) | 等同 | 描述 |
---|---|---|
com.docker.network.bridge.name | - | 創(chuàng)建Linux bridge使用的bridge名稱 |
com.docker.network.bridge.enable_ip_masquerade | ip-masq | 啟用IP偽裝 |
com.docker.network.bridge.enable_icc | icc | 啟用或禁用容器間連接 |
com.docker.network.bridge.host_binding_ipv4 | ip | 綁定容器端口時(shí)默認(rèn)綁定的IP |
com.docker.network.driver.mtu | mtu | 設(shè)置容器網(wǎng)絡(luò)MTU |
這里沒有網(wǎng)絡(luò)基礎(chǔ)可能不太好理解,不過我們還可以參考默認(rèn)的bridge網(wǎng)絡(luò)的設(shè)置:
$ docker network inspect bridge
[
{
"Name": "bridge",
"Id": "80631c00ea3ece0280c786b90f5157be68fe76c26d52f4d9d870a7f5b59edde1",
"Created": "2019-07-21T10:16:03.635792707+08:00",
"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": {},
"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": {}
}
]
$
這個(gè)是默認(rèn)的沒有修改過的bridge橋的信息。除了Options參數(shù),其他參數(shù)也可以參考一下。
使用自定義網(wǎng)絡(luò)
這個(gè)之前已經(jīng)用到過了。之前可選的網(wǎng)絡(luò)只有默認(rèn)提供的3個(gè),brideg、host、none,現(xiàn)在創(chuàng)建的自定義網(wǎng)絡(luò)也可以使用了。命令docker network ls
可以查看,引用的時(shí)候使用--network參數(shù)指定網(wǎng)絡(luò)的名稱(NAME):
$ docker container run --rm -it --network mybr2 busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:70:02
inet addr:192.168.112.2 Bcast:192.168.112.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12 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:1032 (1.0 KiB) 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:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ #
通過容器內(nèi)的eth0的IP地址可以判斷使用的是剛才創(chuàng)建的自定義網(wǎng)絡(luò)。
docker守護(hù)進(jìn)程是C/S構(gòu)架,默認(rèn)只監(jiān)聽本機(jī)的UNIX sock文件。該文件位于/var/run/
目錄下:
$ ls /var/run/*.sock
/var/run/docker.sock
$
可以設(shè)置為監(jiān)聽TCP端口,這樣就可以讓網(wǎng)絡(luò)上其他主機(jī)上的客戶端連接到本地的服務(wù)端。
服務(wù)端需要修改配置文件,讓服務(wù)監(jiān)聽網(wǎng)絡(luò)端口。配置文件/etc/docker/daemon.json
添加一個(gè)hosts屬性:
{
"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
}
修改配置文件后需要重啟服務(wù)。默認(rèn)本地的UNIX sock文件還是保留著。
客戶端要連接到服務(wù)端,使用-H或--host參數(shù)來添加服務(wù)器。直接不帶任何參數(shù)執(zhí)行docker命令,可以查看到幫助信息:
-H, --host list Daemon socket(s) to connect to
之前使用客戶端的時(shí)候,都是不帶這個(gè)參數(shù)的,也就是默認(rèn)連接本機(jī)的UNIX sock文件。加上參數(shù)后,就可以指定連接的服務(wù)端了。
使用-H參數(shù),不過指定的服務(wù)器依然是本地的UNIX sock文件:
$ docker -H unix:///var/run/docker.sock network ls
如果開啟了網(wǎng)絡(luò)的監(jiān)聽,可以這樣:
$ docker -H 127.0.0.1 version
協(xié)議和端口號(hào)都可以省略,默認(rèn)是tcp的2375端口。
不能指定多個(gè)服務(wù)器
看幫助,這個(gè)參數(shù)是個(gè)list,就是可以多次調(diào)用-H來添加多個(gè)服務(wù)端。參數(shù)是這么設(shè)計(jì)的,但是程序的邏輯不允許:
$ docker -H unix:///var/run/docker.sock -H 127.0.0.1 images
Please specify only one -H
$
這里找到了源碼中對(duì)應(yīng)的處理函數(shù):
func getServerHost(hosts []string, tlsOptions *tlsconfig.Options) (string, error) {
var host string
switch len(hosts) {
case 0:
host = os.Getenv("DOCKER_HOST")
case 1:
host = hosts[0]
default:
return "", errors.New("Please specify only one -H")
}
return dopts.ParseHost(tlsOptions != nil, host)
}
參數(shù)只能是0個(gè)或1個(gè),否則就返回錯(cuò)誤。
設(shè)置環(huán)境變量
如果不使用-H參數(shù)指定,還可以通過環(huán)境變量DOCKER_HOST指定。好處是不用每次連接都加上-H參數(shù)了。
下面是設(shè)置和驗(yàn)證的命令:
$ export DOCKER_HOST="unix:///var/run/docker.sock"
$ echo $DOCKER_HOST
unix:///var/run/docker.sock
$
這里設(shè)置的環(huán)境變量是臨時(shí)生效的,重新登錄就沒有了。如果想讓環(huán)境變量永久生效請(qǐng)寫入 ~/.bashrc 。