docker內部容器之間的端口訪問實現方法
Docker 的普及促使眾多應用遷至其上部署,得益其諸多優(yōu)勢。然而,相較于傳統(tǒng)非 Docker 環(huán)境中各應用通過 127.0.0.1:端口 即可輕松互訪,Docker 容器若未經端口映射,彼此間端口則無法直接相通。是否存在更優(yōu)方案以應對這一挑戰(zhàn)?
1 場景描述
場景簡述:alpine-client 與 alpine-server 兩容器,前者訪問后者監(jiān)聽之端口,以此探析 Docker 內部容器間端口訪問機制。
2 建立兩個容器
2.1 通過 Dockerfile 構建鏡像
由于這次測試功能很簡單,可以通過一個 Dockerfile 來創(chuàng)建容器,一個鏡像加載成兩個容器,容器里執(zhí)行的代碼不同而已。
2.1.1 創(chuàng)建 Dockerfile 文件
此 Dockerfile 可以用做一個通用的模板,包含了基本功能框架,用戶可以自行在此基礎上修改。
# 以 alpine:3.10 為基礎鏡像 FROM alpine:3.10 # 設置鏡像源為清華大學鏡像 RUN echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.10/main" > /etc/apk/repositories \ && echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.10/community" >> /etc/apk/repositories \ && apk update && apk upgrade # 安裝依賴包及工具 RUN apk add --no-cache \ bash \ netcat-openbsd # 設置工作目錄 WORKDIR /root # 拷貝需要的文件,支持通配符 # COPY *.sh /root/ # 在 Dockerfile 中添加Entrypoint test.sh,根據需要添加即可 # ENTRYPOINT ["/bin/bash", "-c", "/root/test.sh"]
簡單解釋一下這個 Dockerfile 模板文件:
1)引用基礎鏡像
這個必須有(此語句后面的語句都是可選項),且必須是第一句。我習慣引用 alpine 鏡像,體積小巧、功能強大。
2)設置鏡像源
先改寫鏡像路徑文件,并運行 update、upgrade,使更改生效。關于鏡像源,清華、阿里、根據您的喜好選擇就可以了,主要是用來加快軟件安裝速度。
3)安裝依賴包及工具
使用 RUN 命令來執(zhí)行依賴包及工具的安裝,安裝工作最好是在一個命令里執(zhí)行完成,這樣鏡像就不會添加很多層,導致鏡像文件變大。其中"\“是用來將分行的命令字符串串接起來,”&&"是用來按序依次安裝多個命令。
4)設置工作目錄
設置工作目錄后,容器內部默認目錄就是設置的工作目錄,方便操作。
5)拷貝需要的文件
這一步可以將需要的文件從本機拷入鏡像文件。
6)執(zhí)行 ENTRYPOINT 入口腳本(或者使用CMD)
當容器啟動時,會執(zhí)行此處指定的腳本或命令。
2.1.2 編譯鏡像
docker build -t alpine-net:1.0.0 .
2.2 生成容器
生成 alpine-client 容器:
docker run -itd --name alpine-client alpile-net:1.0.0
生成 alpine-server 容器:`
docker run -itd -p 8888:8888 --name alpine-server alpile-net:1.0.0
alpine-server 容器加了一個端口映射,將 alpine-server 里監(jiān)聽的 8888 端口映射到該容器的宿主機的 8888 端口。
3 獲取 IP 地址
3.1 獲取 alpine-client 相關 IP 地址
3.1.1 獲得 alpine-client 容器本身的 IP 地址
在 alpine-client 終端輸入:
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:65535 Metric:1
RX packets:197 errors:0 dropped:0 overruns:0 frame:0
TX packets:89 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:22832 (22.2 KiB) TX bytes:5821 (5.6 KiB)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:7 errors:0 dropped:0 overruns:0 frame:0
TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:524 (524.0 B) TX bytes:524 (524.0 B)
得到兩個 IP ,127.0.0.1 和 172.17.0.2
3.1.2 獲取 alpine-client 容器網關 IP 地址
在 alpine-client 終端輸入:
route -n
運行后返回結果如下:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
得到網關 IP 地址:172.17.0.1。
3.1.3 獲取 alpine-server 容器網關 IP 地址
同上操作,過程略。
可以得到 alpine-server 相關地址:
alpine-server 本機地址:127.0.0.1 和 和 172.17.0.3
alpine-server 網關地址:172.17.0.1
4 測試訪問
在 alpine-server 的終端里輸入網絡端口監(jiān)聽命令:
nc -lk 8888 # 監(jiān)聽 8888 端口
監(jiān)聽 8888 端口,測試讓 alpine-client 連接。以下如果沒有特殊說明,默認命令行運行窗口為 alpine-client 的終端窗口
4.1 通過容器名稱訪問
nc alpine-server 8888
返回:
nc: getaddrinfo: Name does not resolve
提示:目標容器名 alpine-server 找不到,所以連接失?。?/p>
4.2 通過容器 IP 訪問
nc 127.17.0.3 8888
連接失??!說明容器端口并沒有對“隔壁”容器開放。
4.3 通過網關 IP 訪問
nc 127.17.0.1 8888
連接失??!說明容器端口映射,并不是映射到網關上。
4.4 通過 docker 宿主機名訪問
docker 提供了一個宿主機名:host.docker.internal,所有容器都可以訪問到這個主機名。測試:
nc host.docker.internal 8888
連接成功!且在 alpine-client 輸入的信息可以成功發(fā)送到 alpine-server,且實現的是雙向通訊??梢酝ㄟ^ host.docker.internal 這個主機名可以訪問到容器映射/出來的端口,但無法訪問到容器內部的端口。
4.5 通過 docker-compose 創(chuàng)建容器的方案
此部分在我的博文《docker安裝、調試qsign簽名服務器》里已經應用過,此處就不再贅述。這種方式的 docker-compose.yml 文件已經定義好了容器之間的關系,將各個容器納入一個統(tǒng)一的網卡里,靈活性稍差一點,推薦用在成熟、穩(wěn)定的項目里。
此文描述的方式是采用“分離式”,各個容器是獨立的,容器之間的聯(lián)系通過映射端口的方式,通過 host.docker.internal 進行連接,便于動態(tài)靈活調整連接關系,以及系統(tǒng)的擴展等。
5 總結
在未實施容器分組編排的場景中,本文深入探究并揭示了一種利用 host.docker.internal 實現容器間直接互訪的有效途徑。相較于傳統(tǒng)的基于 IP 地址的訪問方式,選用 host.docker.internal 作為連接標識具有顯著優(yōu)勢:
1)穩(wěn)定性增強:
在容器內部的配置文件中,可以將 host.docker.internal 作為固定的目標地址進行硬編碼(即“寫死”)。此舉消除了因依賴動態(tài)分配或可能變動的 IP 地址而導致的配置脆弱性。當容器重啟、遷移或者網絡環(huán)境發(fā)生調整時,IP 地址可能會發(fā)生變化,而使用 host.docker.internal 則能確保連接指向始終有效,無需隨 IP 變動而頻繁更新配置。
2)簡化管理:
采用 host.docker.internal 作為連接字符串,簡化了容器間交互的管理復雜度。運維人員無需跟蹤每個容器的具體 IP 地址,也不必在 IP 變化時手動調整關聯(lián)容器的配置文件。這種抽象化的尋址方式使得容器間的依賴關系更為清晰,易于理解和維護。
3)兼容性與可移植性提升:
host.docker.internal 是 Docker 系統(tǒng)內建的特殊域名,旨在提供一種標準、跨平臺的方式來訪問宿主機提供的服務。這意味著無論宿主機的實際IP如何變化,或者在不同的部署環(huán)境中(如開發(fā)、測試、生產),只要支持 Docker,該域名即可確保容器間的互訪順利進行。這種設計增強了容器應用在不同環(huán)境中的兼容性和可移植性。
綜上所述,在無編排工具介入的情況下,利用 host.docker.internal 進行容器間的互訪是一種既穩(wěn)健又便捷的選擇。它不僅避免了因 IP 變動引發(fā)的連接失敗問題,還簡化了管理流程,提升了應用在不同 Docker 環(huán)境下的適應性。
到此這篇關于如何實現docker內部容器之間的端口訪問的文章就介紹到這了,更多相關docker內部容器端口訪問內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Docker安裝MySQL并使用Navicat連接的使用示例
在Docker里運行MySQL的方式還是很方便的,本文主要介紹了Docker安裝MySQL并使用Navicat連接的使用示例,具有一定的參考價值,感興趣的可以了解一下2023-10-10如何使用Docker部署briefing視頻聊天系統(tǒng)
briefing是一個開源的、安全的直接視頻群聊平臺,這篇文章主要介紹了使用Docker部署briefing視頻聊天系統(tǒng)的詳細過程,需要的朋友可以參考下2024-01-01在CentOS 7上安裝Docker環(huán)境的方法與注意事項
這篇文章主要介紹了在CentOS 7上安裝Docker環(huán)境的方法與注意事項,需要的朋友可以參考下2016-10-10