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