Docker從默認(rèn)網(wǎng)絡(luò)到自定義網(wǎng)絡(luò)實(shí)現(xiàn)方式
引言:容器通信的 “隱形障礙”—— 為什么默認(rèn)網(wǎng)絡(luò)不夠用?
當(dāng)你使用Docker啟動(dòng)了MySQL容器和Java應(yīng)用容器,讓Java應(yīng)用通過MySQL的IP地址連接數(shù)據(jù)庫,一切看似順利。然而,一旦重啟MySQL容器,IP地址發(fā)生變化,Java應(yīng)用就會(huì)直接報(bào)錯(cuò)“連接不上數(shù)據(jù)庫”。這就是Docker默認(rèn)網(wǎng)絡(luò)給我們帶來的困擾。
本文將深入解析Docker網(wǎng)絡(luò)機(jī)制,從默認(rèn)bridge模式存在的問題,到自定義網(wǎng)絡(luò)的解決方案,教會(huì)你如何讓容器之間能夠“用名字說話”,徹底擺脫IP變動(dòng)帶來的麻煩。適合有一定容器操作基礎(chǔ)的Docker用戶,以及需要部署多容器應(yīng)用(如前端 + 后端 + 數(shù)據(jù)庫)的開發(fā)者閱讀。
Docker 默認(rèn)網(wǎng)絡(luò):bridge 模式的 “利與弊”
虛擬網(wǎng)橋 docker0
Docker安裝后會(huì)自動(dòng)創(chuàng)建一個(gè)名為docker0的虛擬網(wǎng)卡,它就好比一個(gè)“虛擬交換機(jī)”。其默認(rèn)IP段為172.17.0.0/16,這意味著前16位是固定的,后16位可供分配,范圍從172.17.0.1到172.17.255.254。
我們可以通過執(zhí)行ip addr命令來驗(yàn)證,在輸出結(jié)果中能看到名為docker0的網(wǎng)卡及其IP地址,比如172.17.0.1 。
IP分配機(jī)制
所有容器在啟動(dòng)時(shí)默認(rèn)會(huì)連接到docker0網(wǎng)橋,并自動(dòng)分配IP地址。
第一個(gè)容器通常會(huì)被分配到172.17.0.2,第二個(gè)則是172.17.0.3,依此類推。由于這些容器都連接到docker0網(wǎng)橋,處于同一網(wǎng)段,所以它們可以通過IP直接進(jìn)行通信,例如使用ping 172.17.0.2命令。
痛點(diǎn):IP 變動(dòng)導(dǎo)致的 “連接失效” 問題
雖然默認(rèn)的bridge模式能讓容器間實(shí)現(xiàn)基本通信,但它存在一個(gè)致命的缺點(diǎn),即容器的IP地址是動(dòng)態(tài)分配的。當(dāng)容器重啟、刪除重建后,IP地址很可能發(fā)生變化。
比如MySQL容器重啟后,IP地址可能從172.17.0.2變成172.17.0.4 。
對(duì)于依賴IP地址進(jìn)行連接的應(yīng)用,如Java應(yīng)用連接數(shù)據(jù)庫,這種IP變動(dòng)會(huì)導(dǎo)致連接失效,并且需要手動(dòng)修改配置,操作起來極其繁瑣。
Docker 網(wǎng)絡(luò)操作命令:從創(chuàng)建到管理
核心命令
- 創(chuàng)建自定義網(wǎng)絡(luò):使用docker network create [網(wǎng)絡(luò)名]命令可以創(chuàng)建一個(gè)獨(dú)立的虛擬網(wǎng)絡(luò),幫助我們避免默認(rèn)網(wǎng)絡(luò)的IP變動(dòng)問題。例如,執(zhí)行docker network create itheima就能創(chuàng)建一個(gè)名為itheima的網(wǎng)絡(luò)。
- 查看所有網(wǎng)絡(luò):docker network ls命令會(huì)以列表形式顯示系統(tǒng)中的所有網(wǎng)絡(luò),包括默認(rèn)的bridge、host、none網(wǎng)絡(luò),以及我們自定義創(chuàng)建的網(wǎng)絡(luò),如itheima 。
- 連接容器到網(wǎng)絡(luò):通過docker network connect [網(wǎng)絡(luò)名] [容器名],可以讓已運(yùn)行的容器加入指定網(wǎng)絡(luò),并且容器能夠同時(shí)屬于多個(gè)網(wǎng)絡(luò)。比如執(zhí)行docker network connect itheima mysql,就能將mysql容器加入到itheima網(wǎng)絡(luò)。
- 查看網(wǎng)絡(luò)詳情:docker network inspect [網(wǎng)絡(luò)名]命令可以獲取網(wǎng)絡(luò)的詳細(xì)信息,包括IP段、連接的容器等。以docker network inspect itheima為例,通過該命令我們能查看容器在itheima網(wǎng)絡(luò)中的IP等配置。
輔助命令
- 刪除網(wǎng)絡(luò):docker network rm [網(wǎng)絡(luò)名]用于刪除指定的網(wǎng)絡(luò),但需要先斷開所有容器與該網(wǎng)絡(luò)的連接。
- 清理未使用網(wǎng)絡(luò):docker network prune命令會(huì)刪除沒有容器使用的網(wǎng)絡(luò),從而釋放系統(tǒng)資源。
- 斷開連接:使用docker network disconnect [網(wǎng)絡(luò)名] [容器名],可以斷開容器與指定網(wǎng)絡(luò)的連接。
命令記憶法
所有關(guān)于Docker網(wǎng)絡(luò)的操作命令都以docker network開頭,這樣記憶起來更加方便,你可以簡單理解為“網(wǎng)絡(luò)操作 = docker network + 具體動(dòng)作(create/ls/rm等)”。
實(shí)戰(zhàn):用自定義網(wǎng)絡(luò)解決容器通信難題
步驟1:創(chuàng)建自定義網(wǎng)絡(luò)
執(zhí)行docker network create itheima命令創(chuàng)建名為itheima的網(wǎng)絡(luò),然后通過docker network ls確認(rèn)網(wǎng)絡(luò)已成功創(chuàng)建。
自定義網(wǎng)絡(luò)有個(gè)特點(diǎn),它會(huì)自動(dòng)選擇未被占用的IP段。
比如默認(rèn)bridge網(wǎng)絡(luò)使用了172.17.x.x網(wǎng)段,自定義網(wǎng)絡(luò)可能就會(huì)使用172.18.x.x網(wǎng)段。
步驟2:將容器加入自定義網(wǎng)絡(luò)
- 方式一:創(chuàng)建容器時(shí)指定網(wǎng)絡(luò)(推薦)
啟動(dòng)MySQL容器時(shí),直接使用–network itheima參數(shù)將其加入itheima網(wǎng)絡(luò),命令如下:
docker run -d --name mysql --network itheima -e MYSQL_ROOT_PASSWORD=123 mysql:8
同樣,啟動(dòng)Java應(yīng)用容器時(shí)也加入itheima網(wǎng)絡(luò):
docker run -d --name myapp --network itheima -p 8080:8080 app:1.0
- 方式二:給已運(yùn)行的容器動(dòng)態(tài)加入網(wǎng)絡(luò)
假設(shè)mysql容器已經(jīng)在默認(rèn)網(wǎng)絡(luò)中運(yùn)行,我們可以使用以下命令將其動(dòng)態(tài)加入itheima網(wǎng)絡(luò):
docker network connect itheima mysql
通過這種方式,mysql容器會(huì)同時(shí)屬于默認(rèn)bridge和itheima網(wǎng)絡(luò),也就會(huì)擁有兩個(gè)IP地址。
步驟3:驗(yàn)證 “容器名通信”
首先通過docker exec -it myapp bash進(jìn)入myapp容器,然后在容器內(nèi)使用ping mysql命令測試與MySQL容器的連接。
結(jié)果是能成功ping通,這是因?yàn)镈ocker會(huì)自動(dòng)將mysql解析為其在itheima網(wǎng)絡(luò)中的IP地址,比如172.18.0.2 。而且即使mysql容器重啟,IP地址發(fā)生變化,ping mysql命令依然有效,因?yàn)镈ocker的DNS會(huì)更新解析。
自定義網(wǎng)絡(luò)的核心優(yōu)勢與原理
內(nèi)置DNS
在自定義網(wǎng)絡(luò)中,Docker自帶了DNS服務(wù),它會(huì)將容器名映射為該網(wǎng)絡(luò)內(nèi)的IP地址。
這使得容器之間可以直接使用容器名進(jìn)行通信,無需記住復(fù)雜的IP地址。而默認(rèn)的bridge網(wǎng)絡(luò)并沒有這個(gè)功能,在bridge網(wǎng)絡(luò)中容器通信必須使用IP地址,或者手動(dòng)配置hosts文件。
多網(wǎng)絡(luò)支持
一個(gè)容器可以同時(shí)加入多個(gè)網(wǎng)絡(luò),比如同時(shí)處于默認(rèn)bridge和自定義itheima網(wǎng)絡(luò)。
我們可以通過docker inspect myapp命令,在輸出結(jié)果的Networks字段中查看容器所屬所有網(wǎng)絡(luò)的配置信息,每個(gè)網(wǎng)絡(luò)都會(huì)為容器分配獨(dú)立的IP地址。
這種多網(wǎng)絡(luò)支持不僅增加了容器通信的靈活性,還提升了網(wǎng)絡(luò)的隔離性,不同自定義網(wǎng)絡(luò)之間默認(rèn)是隔離的,只有加入同一網(wǎng)絡(luò)的容器才能相互通信,安全性更高。
對(duì)比默認(rèn)bridge
與默認(rèn)的bridge網(wǎng)絡(luò)相比,自定義網(wǎng)絡(luò)解決了IP變動(dòng)的問題,容器之間通過容器名通信更加穩(wěn)定。默認(rèn)bridge網(wǎng)絡(luò)依賴動(dòng)態(tài)變化的IP地址,一旦IP改變就會(huì)導(dǎo)致通信故障,而自定義網(wǎng)絡(luò)通過內(nèi)置DNS實(shí)現(xiàn)容器名到IP的動(dòng)態(tài)解析,即使IP變化也不影響通信。
避坑指南:網(wǎng)絡(luò)配置常見錯(cuò)誤與解決
容器加入網(wǎng)絡(luò)后仍無法通信?
- 檢查是否在同一網(wǎng)絡(luò):使用docker network inspect 網(wǎng)絡(luò)名命令,確認(rèn)兩個(gè)需要通信的容器都在該網(wǎng)絡(luò)的容器列表中。
- 檢查防火墻:宿主機(jī)的防火墻可能會(huì)阻止容器間的通信,可以臨時(shí)關(guān)閉防火墻進(jìn)行測試,命令為systemctl stop firewalld 。
- 檢查應(yīng)用端口:確認(rèn)容器內(nèi)應(yīng)用是否監(jiān)聽了正確的端口,比如MySQL默認(rèn)端口是3306,需要檢查其配置中是否開放了該端口。
自定義網(wǎng)絡(luò)IP段沖突怎么辦?
如果擔(dān)心自定義網(wǎng)絡(luò)IP段沖突,可以在創(chuàng)建網(wǎng)絡(luò)時(shí)手動(dòng)指定IP段,例如:
docker network create --subnet 192.168.100.0/24 mynet
如何查看容器的所有網(wǎng)絡(luò)IP?
使用以下命令可以查看容器的所有網(wǎng)絡(luò)IP:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}} {{end}}' 容器名
總結(jié):容器網(wǎng)絡(luò)的 “最佳實(shí)踐”
對(duì)于多容器應(yīng)用,使用自定義網(wǎng)絡(luò)是必不可少的,它能有效避免IP變動(dòng)帶來的問題。在創(chuàng)建容器時(shí),優(yōu)先使用–network參數(shù)指定網(wǎng)絡(luò),這樣比動(dòng)態(tài)加入網(wǎng)絡(luò)更加規(guī)范和可靠。
當(dāng)遇到網(wǎng)絡(luò)配置問題時(shí),docker network inspect命令是排查問題的有力工具。另外,定期使用docker network prune命令清理無用網(wǎng)絡(luò),有助于釋放系統(tǒng)資源。
簡而言之,自定義網(wǎng)絡(luò)實(shí)現(xiàn)了容器通信從“記IP”到“叫名字”的轉(zhuǎn)變,是Docker多容器部署中必須掌握的技能。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Docker如何創(chuàng)建一個(gè)Jar服務(wù)容器
這篇文章主要介紹了Docker如何創(chuàng)建一個(gè)Jar服務(wù)容器問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
Docker Registry以及Docker-Registry-UI部署過程
這篇文章主要介紹了Docker Registry以及Docker-Registry-UI部署過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2026-03-03
Docker部署Laravel應(yīng)用實(shí)現(xiàn)隊(duì)列&任務(wù)調(diào)度
這篇文章主要介紹了Docker部署Laravel應(yīng)用實(shí)現(xiàn)隊(duì)列&任務(wù)調(diào)度,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
Docker網(wǎng)段和內(nèi)網(wǎng)網(wǎng)段ip沖突導(dǎo)致無法訪問網(wǎng)絡(luò)的兩種解決方法
本文主要介紹了Docker網(wǎng)段和內(nèi)網(wǎng)網(wǎng)段沖突導(dǎo)致無法訪問網(wǎng)絡(luò)的兩種解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
docker-compose安裝MySQL8.0.39全過程
這篇文章主要介紹了docker-compose安裝MySQL8.0.39全過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-10-10

