作者 | Dieter Jordens
譯者 | 蘇本如,責編 | 夕顏
出品 | CSDN(ID:CSDNnews)
以下為譯文:
作為初級開發人員的你,是不是參加過這樣的面試,在面試中面試官希望你準確地回答Docker的工作原理?現今的面試官們希望應聘者能夠深入了解8項、10項、甚至更多的技術。其實這有點瘋狂。在大學或其他學校里,他們很可能根本不會教你任何關于Docker的知識。然而,如果你真的能夠深入了解Docker,那么你就可以從一大群應聘者中脫穎而出。
當你開始使用Docker時,首先會遇到的問題之一是你無法連接到Docker容器。這篇文章將詳細解釋這個問題為什么會發生,同時我也會解釋端口綁定(port binding)是如何工作的。
即使你是一個經驗豐富的開發人員,你也應該了解什么是端口綁定。否則,你在面試時會顯得很傻。如果你還沒有了解,那么現在就給自己拿杯咖啡。我一定會讓你把你想知道的關于這個話題的一切內容都記在你的腦子里,只需要花費你六分鐘!
讓我們從一個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容器,命令如下:
docker container run -d nginx
這個命令將會生成一個新的Docker容器,你會看到這個新的Docker容器的UUID。如果你不知道UUID是什么,那么請認真閱讀我寫的這篇文章中的所有內容。使用Docker容器的ps命令(docker ps),你將看到這個Docker容器處于活躍狀態:
現在,如果你試圖使用curl命令或使用一個瀏覽器直接連接到這個Docker容器,你會遇到連接失敗的錯誤(見下面)。因為你不能直接連接到一個Docker容器,原因是什么呢?Docker的文檔只是解釋說端口80易受攻擊…這個解釋有點不明不白。但是別擔心,我會在下一節詳細給出解釋!
curl -I 127.0.0.1:80
curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused
為什么我不能直接連接到一個Docker容器?
事實上,Docker容器可以在不作任何配置的情況下連接到外部世界。這一點太好了,因為這樣我們就不必改變我們以前編程過的任何東西。
但是默認地,外部世界無法直接連接到一個Docker容器。
說到這里,我想你應該明白了,這一點和我們預想的不同。那么你應該如何連接到你的Docker容器呢?好吧,有多種選擇。讓我們探索一下。
1. 公開Docker的所有端口
docker container run -P -d nginx
這里的-P命令打開容器公開的每個端口。Docker會標識在Dockerfile中公開的每個端口,以及使用帶有--expose 參數的Docker container build命令公開的每個端口。每個公開的端口都直接綁定在主機的一個“隨機”端口上。
聽起來不錯,但是我們現在該怎么找到這些端口呢?別擔心,我們會找到你心愛的端口的,甚至有多種方法可以幫助找到它們。接下來我將向你展示兩種不同的方法:
Docker container port
netstat
我們的第一個選擇是使用上面的Docker命令(docker container port)。你只需要鍵入上面的命令和容器UUID。你就會看到Docker容器的端口80綁定到了IP地址為0.0.0.0的主機端口32768上(如果你自己嘗試執行該命令,則會看到一個不同的端口)。
docker container port *insert container_uuid*
80/tcp -> 0.0.0.0:32768
我們的另一個選擇是使用netstat命令。要查找所有打開的端口,你可以執行以下命令。注意,Docker公開的端口混雜在其他端口中間,本例中第三行的那個端口就是我們要找的。
netstat -ntlp
使用netstat命令找到的所有打開的端口。
2. 公開一個特定端口
端口綁定示例:將Docker容器的80端口綁定到主機的8080端口上。
公開所有Docker端口通常不是一個好主意,默認情況是根本不公開任何端口,這是為了安全起見。你不想公開一切,因為這樣做根本沒有任何好處,對吧?
如果你只想公開一個端口,請執行以下命令:
docker container run -p 8080:80 -d nginx
這個命令使得Nginx容器的80端口通過主機端口8080對外公開。現在,我們就可以通過多種方式連接到容器。例如,使用curl命令或通過一個瀏覽器。這是不是太棒了!
恭喜你,現在你終于明白了Docker端口綁定最重要的部分了!下面我將向你展示curl命令執行的結果:
curl -I 0.0.0.0:8080HTTP/1.1 200 OK
Server: nginx/1.17.9
Date: Sun, 08 Mar 2020 11:38:47 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 03 Mar 2020 14:32:47 GMT
Connection: keep-alive
ETag: "5e5e6a8f-264"
Accept-Ranges: bytes
如果你在瀏覽器中訪問這個地址:0.0.0.0:8080,那么你的瀏覽器會向你展示如下的內容:
通過瀏覽器連接到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(也稱為本地主機)上,你只需運行以下命令:
docker run -d -p 127.0.0.1:8000:80 nginx
結束語
對于使用Docker容器來說,Docker的端口綁定是一個很重要的概念。一開始可能因為需要配置傳入連接(incoming connection)的問題,會讓人困惑。但是Docker在提供所有需要的文檔方面做得很出色。
不過,作為開發者,有些Docker的概念比其他概念更難理解。希望讀完這篇文章后,你對Docker端口綁定已經很清楚了。如果沒有,請在下面留言!
原文鏈接:
https://medium.com/better-programming/how-does-docker-port-binding-work-b089f23ca4c8
本文為CSDN翻譯文章,轉載請注明出處。
有同事最近遇到了一個問題,在運行某個程序的時候,總提示說程序端口被占用,不能運行,那么,在winserver下怎么知道端口是被哪個程序占用了呢?下面我們一起來看看具體內容。
點擊電腦左下角的開始,然后選擇運行選項,接著我們在彈出的窗口中,輸入【cmd】命令,進行命令提示符。
然后在窗口中輸入【netstat -ano】按下回車,即會顯示所有的端口占用情況。如圖所示:
在窗口中,繼續輸入【netstat -aon|findstr "提示的端口"】,例如提示的端口為8080,那么就輸入命令為【netstat -aon|findstr "8080"】,回車之后就可以看見列表中的PID,然后根據PID在電腦的任務管理器中查看對應的占用程序,接著進行關閉即可。
如果在上面步驟之后,我們得到的PID為9564,那么就可以輸入命令【tasklist|findstr "9564"】,在第一行顯示的名字就是程序名,以下可以看到很明顯是微信占用的端口。
輸入命令【taskkill /f /t /im 程序名】即可
后面會分享更多devops和DBA方面的內容,感興趣的朋友可以關注下~
如果你覺得這篇文章對你有幫助, 請小小打賞下.