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