Docker 概念很難理解?一文搞定 Docker 端口綁定

Docker 概念很難理解?一文搞定 Docker 端口綁定

作者 | Dieter Jordens

譯者 | 蘇本如,責編 | 夕顏出品 | CSDN(ID:CSDNnews)以下為譯文:

作為初級開發人員的你,是不是參加過這樣的面試,在面試中面試官希望你準確地回答Docker的工作原理?現今的面試官們希望應聘者能夠深入瞭解8項、10項、甚至更多的技術。其實這有點瘋狂。在大學或其他學校裡,他們很可能根本不會教你任何關於Docker的知識。然而,如果你真的能夠深入瞭解Docker,那麼你就可以從一大群應聘者中脫穎而出。

當你開始使用Docker時,首先會遇到的問題之一是你無法連接到Docker容器。這篇文章將詳細解釋這個問題為什麼會發生,同時我也會解釋端口綁定(port binding)是如何工作的。

即使你是一個經驗豐富的開發人員,你也應該瞭解什麼是端口綁定。否則,你在面試時會顯得很傻。如果你還沒有了解,那麼現在就給自己拿杯咖啡。我一定會讓你把你想知道的關於這個話題的一切內容都記在你的腦子裡,只需要花費你六分鐘!


Docker 概念很難理解?一文搞定 Docker 端口綁定

讓我們從一個Nginx Docker容器開始吧!


如果你對Docker有一點點了解的話,你就無需擔心了。因為我會盡量詳細地解釋關於Docker的一切。首先,我需要確保你理解Docker容器和Docker鏡像之間的區別。


你可以把Docker鏡像看作一個文件,它包含了運行一個特定程序的所有依賴項和配置。為什麼要這樣做?因為Docker想要解決的首個問題就是系統/程序安裝的噩夢。


我們都經歷過在Windows、Mac或Linux系統上安裝程序的情況。然而令人沮喪的是,系統每次都會提示你缺少另一個程序。就像下面系統提示你要不要安裝的那樣,我猜你每次遇到這個問題都會選擇安裝,對吧?


你也要安裝這個程序嗎?…


最終你會發現,你不但需要安裝很多不同的程序,而且經常還需要配置系統變量等等。在最壞的情況下,這些會把你的系統弄得一團糟。


你一定不希望你組織裡的每個人都經歷這種麻煩,對嗎?


Docker鏡像可以幫助你解決這個麻煩,因為一個Docker鏡像裡包含了安裝程序所需的所有內容。而Docker容器則是Docker鏡像的運行實例。


Docker為你解決了安裝的噩夢。而Docker容器包含了它運行時所需要的一切,不多也不少。你可以在Windows、Linux或Mac上運行一個Docker容器。基本上,只要你將Docker安裝好,你就可以在任何地方運行它。


關於Docker的優勢已經講得夠多了。接下來,我們要做的是讓一個Docker容器開始運行起來。


讓我們從一個Nginx Docker容器開始。Nginx是一個運行在端口80上的web服務器。下面,我將使用Nginx Docker鏡像以分離模式(後臺運行)啟動一個Docker容器,命令如下:

<code>docker container run -d nginx/<code>


這個命令將會生成一個新的Docker容器,你會看到這個新的Docker容器的UUID。如果你不知道UUID是什麼,那麼請認真閱讀我寫的這篇文章中的所有內容。使用Docker容器的ps命令(docker ps),你將看到這個Docker容器處於活躍狀態:

Docker 概念很難理解?一文搞定 Docker 端口綁定

現在,如果你試圖使用curl命令或使用一個瀏覽器直接連接到這個Docker容器,你會遇到連接失敗的錯誤(見下面)。因為你不能直接連接到一個Docker容器,原因是什麼呢?Docker的文檔只是解釋說端口80易受攻擊…這個解釋有點不明不白。但是別擔心,我會在下一節詳細給出解釋!

<code>curl -I 127.0.0.1:80curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused/<code>


為什麼我不能直接連接到一個Docker容器?


事實上,Docker容器可以在不作任何配置的情況下連接到外部世界。這一點太好了,因為這樣我們就不必改變我們以前編程過的任何東西。


但是默認地,外部世界無法直接連接到一個Docker容器。


說到這裡,我想你應該明白了,這一點和我們預想的不同。那麼你應該如何連接到你的Docker容器呢?好吧,有多種選擇。讓我們探索一下。


1. 公開Docker的所有端口

<code>docker container run -P -d nginx/<code>


這裡的-P命令打開容器公開的每個端口。Docker會標識在Dockerfile中公開的每個端口,以及使用帶有--expose 參數的Docker container build命令公開的每個端口。每個公開的端口都直接綁定在主機的一個“隨機”端口上。

聽起來不錯,但是我們現在該怎麼找到這些端口呢?別擔心,我們會找到你心愛的端口的,甚至有多種方法可以幫助找到它們。接下來我將向你展示兩種不同的方法:

  • Docker container port
  • netstat


我們的第一個選擇是使用上面的Docker命令(docker container port)。你只需要鍵入上面的命令和容器UUID。你就會看到Docker容器的端口80綁定到了IP地址為0.0.0.0的主機端口32768上(如果你自己嘗試執行該命令,則會看到一個不同的端口)。

<code>docker container port *insert container_uuid*80/tcp -> 0.0.0.0:32768/<code>


我們的另一個選擇是使用netstat命令。要查找所有打開的端口,你可以執行以下命令。注意,Docker公開的端口混雜在其他端口中間,本例中第三行的那個端口就是我們要找的。

<code>netstat -ntlp/<code>

Docker 概念很難理解?一文搞定 Docker 端口綁定

使用netstat命令找到的所有打開的端口


2. 公開一個特定端口

Docker 概念很難理解?一文搞定 Docker 端口綁定

端口綁定示例:將Docker容器的80端口綁定到主機的8080端口上


公開所有Docker端口通常不是一個好主意,默認情況是根本不公開任何端口,這是為了安全起見。你不想公開一切,因為這樣做根本沒有任何好處,對吧?

如果你只想公開一個端口,請執行以下命令:

<code>docker container run -p 8080:80 -d nginx/<code>

這個命令使得Nginx容器的80端口通過主機端口8080對外公開。現在,我們就可以通過多種方式連接到容器。例如,使用curl命令或通過一個瀏覽器。這是不是太棒了!

恭喜你,現在你終於明白了Docker端口綁定最重要的部分了!下面我將向你展示curl命令執行的結果:

<code>curl -I 0.0.0.0:8080HTTP/1.1 200 OKServer: nginx/1.17.9Date: Sun, 08 Mar 2020 11:38:47 GMTContent-Type: text/htmlContent-Length: 612Last-Modified: Tue, 03 Mar 2020 14:32:47 GMTConnection: keep-aliveETag: "5e5e6a8f-264"Accept-Ranges: bytes/<code>


如果你在瀏覽器中訪問這個地址:0.0.0.0:8080,那麼你的瀏覽器會向你展示如下的內容:

Docker 概念很難理解?一文搞定 Docker 端口綁定

通過瀏覽器連接到0.0.0.0:8080的情況

還有一件事

默認情況下,Docker會將容器端口公開到IP地址0.0.0.0(這個地址和系統上的任何IP都匹配)上。你也可以告訴Docker要綁定哪個IP,這個IP可以是127.0.0.1,也可以是其他IP地址。


如果你想將Docker容器的80端口綁定到主機系統端口8000和IP地址127.0.0.1(也稱為本地主機)上,你只需運行以下命令:

<code>docker run -d -p 127.0.0.1:8000:80 nginx/<code>


Docker 概念很難理解?一文搞定 Docker 端口綁定

結束語


對於使用Docker容器來說,Docker的端口綁定是一個很重要的概念。一開始可能因為需要配置傳入連接(incoming connection)的問題,會讓人困惑。但是Docker在提供所有需要的文檔方面做得很出色。


不過,作為開發者,有些Docker的概念比其他概念更難理解。希望讀完這篇文章後,你對Docker端口綁定已經很清楚了。如果沒有,請在下面留言!


分享到:


相關文章: