Docker 網(wǎng)絡(luò)-bridge 模式
容器與主機(jī)、容器與容器之間是互相隔離的。同時(shí),我們可以通過(guò)配置 docker 網(wǎng)絡(luò),為容器創(chuàng)建完全獨(dú)立的網(wǎng)絡(luò)命名空間,或者使容器共享主機(jī)或者其他容器的網(wǎng)絡(luò)命名空間,以應(yīng)對(duì)不同場(chǎng)景的需要。
這里有4 種常用的單宿主機(jī)網(wǎng)絡(luò)模式:
- bridge 模式;
- host 模式;
- container 模式;
- none 模式。
本節(jié)將介紹網(wǎng)絡(luò)模式中的 bridge 模式。
1. bridge 模式
Docker 服務(wù)啟動(dòng)時(shí),會(huì)自動(dòng)在宿主機(jī)上創(chuàng)建一個(gè) docker0 虛擬網(wǎng)橋 (Linux Bridge, 可以理解為一個(gè)軟件虛擬出來(lái)的交換機(jī))。它會(huì)在掛載到它的網(wǎng)口之間進(jìn)行轉(zhuǎn)發(fā)。同時(shí) Docker 隨機(jī)分配一個(gè)可用的私有 IP 地址給 docker0 接口。如果容器使用默認(rèn)網(wǎng)絡(luò)參數(shù)啟動(dòng),那么它的網(wǎng)口也會(huì)自動(dòng)分配一個(gè)與 docker0 同網(wǎng)段的 IP 地址。
我們使用命令 ip address show dev docker0
獲取 docker0 網(wǎng)絡(luò)信息,它的地址是 172.17.0.1, 子網(wǎng)掩碼為 255.255.0.0,如下圖所示:
我們來(lái)做個(gè)測(cè)試,看看默認(rèn)新建的容器是否能互相連通。
使用 busybox 鏡像分別運(yùn)行 b0,b1 兩個(gè)容器:
docker run -d -t --name b0 busybox
docker run -d -t --name b1 busybox
容器新建并運(yùn)行成功后,查看兩個(gè)容器的 IP 地址:
docker inspect --format '{{ .NetworkSettings.IPAddress }}' b0 # 172.17.0.2
docker inspect --format '{{ .NetworkSettings.IPAddress }}' b1 # 172.17.0.3
Tips:獲取的 IP 是隨機(jī)的,跟 Docker 版本與運(yùn)行環(huán)境有關(guān),以自己獲取的 IP 為準(zhǔn),下同
兩個(gè)容器互相 ping 一下,證明它們的網(wǎng)絡(luò)能連通:
docker exec -it b0 ping 172.17.0.3
docker exec -it b1 ping 172.17.0.2
此時(shí)網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)如下所示:
容器 b1 之后用不到,我們可以先刪除它來(lái)釋放資源。
1.1 自定義網(wǎng)橋
除了使用默認(rèn) docker0 做網(wǎng)橋,我們還可以使用 docker network
相關(guān)命令自定義網(wǎng)橋:
這里將創(chuàng)建一個(gè)網(wǎng)橋 br0
,設(shè)定網(wǎng)段是 172.71.0.0/24
,網(wǎng)關(guān)為 172.71.0.1
:
docker network create -d bridge --subnet '172.71.0.0/24' --gateway '172.71.0.1' br0
# -d 指定管理網(wǎng)絡(luò)的驅(qū)動(dòng)方式,默認(rèn)為bridge
# --subnet 指定子網(wǎng)網(wǎng)段
# --gateway 指定默認(rèn)網(wǎng)關(guān)
使用命令 docker network ls
查看當(dāng)前的 docker 網(wǎng)絡(luò)列表,發(fā)現(xiàn)新增的 br0 網(wǎng)橋。
接下來(lái),我們嘗試在使用這個(gè)網(wǎng)橋 br0 來(lái)新建運(yùn)行兩個(gè)容器,并測(cè)試它們的連通性。使用 busybox 鏡像分別運(yùn)行 b2,b3 兩個(gè)容器:
docker run -d -t --network br0 --name b2 busybox
docker run -d -t --network br0 --name b3 busybox
容器新建并運(yùn)行成功后,分別執(zhí)行下列命令,互相 ping 一下驗(yàn)證網(wǎng)絡(luò)連通:
docker exec b2 ping b3
docker exec b3 ping b2
ping 測(cè)試過(guò)程中,輸入的并不是 IP,而是容器名。在自定義網(wǎng)橋中,容器名會(huì)在需要的時(shí)候自動(dòng)解析到對(duì)應(yīng)的 IP,也解決了容器重啟可能導(dǎo)致 IP 變動(dòng)的問(wèn)題。
其他
不再使用的容器記得刪除掉,釋放資源和空間
docker rm -f b2 b3
docker network rm br0 # 刪除自定義的網(wǎng)橋
1.2 端口映射訪(fǎng)問(wèn)容器
將宿主機(jī)的本地端口,與指定容器的服務(wù)端口進(jìn)行映射綁定,之后訪(fǎng)問(wèn)宿主機(jī)端口時(shí),會(huì)將請(qǐng)求自動(dòng)轉(zhuǎn)發(fā)到容器的端口上,實(shí)現(xiàn)外部對(duì)容器內(nèi)網(wǎng)絡(luò)服務(wù)的訪(fǎng)問(wèn)。
創(chuàng)建名為 n0 的 nginx 容器,映射宿主機(jī) 8000 端口到它的 80 端口
docker run -d -t -p 8000:80 --name n0 nginx
Tips:指定的宿主機(jī)端口必須是未被占用的端口,否則操作會(huì)失敗,且生成一個(gè)無(wú)法正常啟動(dòng)的容器 n0, 需要手動(dòng)刪除。
使用 docker port n0
查看 n0 的端口映射信息,顯示如下:
80/tcp -> 0.0.0.0:8000
打開(kāi)瀏覽器,地址欄輸入 http://localhost:8000 或 http:// 宿主機(jī) IP:8000, 都能訪(fǎng)問(wèn)到 n0 的 nginx 服務(wù)。
如果需要綁定多個(gè)容器端口,可以連續(xù)使用 -p
參數(shù)多次指定
docker run -d -t -p 8001:80 -p 8433:443 --name n1 ngin
如果不想主動(dòng)指定宿主機(jī)端口,可以使用 -P
參數(shù),宿主機(jī)隨機(jī)使用一個(gè)可用端口與容器端口進(jìn)行映射
docker run -d -t -P --name n2 nginx
如果只想使用宿主機(jī)上特定的網(wǎng)口與容器進(jìn)行映射
docker run -d -t -p 192.168.1.13:8002:80 --name n3 nginx
Tips:此處
192.168.1.13
指代 宿主機(jī)映射網(wǎng)口的 IP 地址,需要根據(jù)網(wǎng)口的實(shí)際 IP 更改 *。
我們執(zhí)行 docker ps
可能出現(xiàn)如下幾個(gè)的 nginx 容器:
再執(zhí)行 iptables -t nat -nL
查看下防火墻:
比對(duì)上面兩個(gè)的輸出,不難發(fā)現(xiàn),這種端口轉(zhuǎn)發(fā)方式的本質(zhì)是通過(guò)配置 iptables 規(guī)則轉(zhuǎn)發(fā)實(shí)現(xiàn)的,效率較低,如果容器的服務(wù)端口數(shù)量過(guò)多,需要配置較多的映射,占用大量宿主機(jī)端口,也不便于管理。
不再使用的容器記得刪除掉,釋放資源和空間
docker rm -f n0 n1 n2 n3
2. 小結(jié)
使用端口映射訪(fǎng)問(wèn)容器是常用的方式之一,它配置簡(jiǎn)單,通用性強(qiáng),可以跨宿主機(jī)訪(fǎng)問(wèn),基本覆蓋個(gè)人日常使用的場(chǎng)景,但它仍有一些缺陷。