將您的 Go 映象作為容器執行
先決條件
請按照構建您的 Go 映象中的步驟,將 Go 應用程式容器化。
概述
在上一模組中,您為示例應用程式建立了一個 `Dockerfile`,然後使用 `docker build` 命令建立了 Docker 映象。現在您有了映象,可以執行該映象並檢視應用程式是否正常執行。
容器是一個正常的作業系統程序,只不過此程序是隔離的,擁有自己的檔案系統、自己的網路和與主機分離的獨立程序樹。
要在容器內執行映象,請使用 `docker run` 命令。它需要一個引數,即映象名稱。啟動您的映象並確保其正常執行。在終端中執行以下命令。
$ docker run docker-gs-ping
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.10.2
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:8080
當您執行此命令時,會注意到您沒有返回到命令提示符。這是因為您的應用程式是一個 REST 伺服器,它將在迴圈中執行,等待傳入請求,直到您停止容器,否則不會將控制權返回給作業系統。
使用 curl 命令向伺服器發出 GET 請求。
$ curl https://:8080/
curl: (7) Failed to connect to localhost port 8080: Connection refused
您的 curl 命令失敗了,因為與伺服器的連線被拒絕。這意味著您無法連線到 localhost 的 8080 埠。這是預料之中的,因為您的容器在隔離環境中執行,其中包含網路。停止容器並重新啟動,將 8080 埠釋出到您的本地網路。
要停止容器,請按 ctrl-c。這會將您返回到終端提示符。
要為容器釋出埠,您將在 `docker run` 命令中使用 `--publish` 標誌(簡寫為 `-p`)。`--publish` 命令的格式為 `[host_port]:[container_port]`。因此,如果您想將容器內的 `8080` 埠暴露給容器外的 `3000` 埠,您可以將 `3000:8080` 傳遞給 `--publish` 標誌。
啟動容器並將容器的 `8080` 埠暴露給主機的 `8080` 埠。
$ docker run --publish 8080:8080 docker-gs-ping
現在,重新執行 curl 命令。
$ curl https://:8080/
Hello, Docker! <3
成功了!您已經能夠連線到在容器內執行的應用程式的 8080 埠。切換回您的容器正在執行的終端,您應該會看到 `GET` 請求已記錄到控制檯。
按 `ctrl-c` 停止容器。
在分離模式下執行
目前為止一切順利,但您的示例應用程式是一個 Web 伺服器,您不應該將終端連線到容器。Docker 可以在後臺以分離模式執行您的容器。為此,您可以使用 `--detach` 或簡寫為 `-d`。Docker 將像以前一樣啟動您的容器,但這次將與容器分離並返回到終端提示符。
$ docker run -d -p 8080:8080 docker-gs-ping
d75e61fcad1e0c0eca69a3f767be6ba28a66625ce4dc42201a8a323e8313c14e
Docker 在後臺啟動了您的容器,並在終端上列印了容器 ID。
再次確認您的容器正在執行。執行相同的 `curl` 命令。
$ curl https://:8080/
Hello, Docker! <3
列出容器
既然您在後臺運行了容器,如何知道您的容器是否正在執行,或者您的機器上還有哪些其他容器正在執行?要檢視機器上正在執行的容器列表,請執行 `docker ps`。這類似於 `ps` 命令在 Linux 機器上用於檢視程序列表的方式。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d75e61fcad1e docker-gs-ping "/docker-gs-ping" 41 seconds ago Up 40 seconds 0.0.0.0:8080->8080/tcp inspiring_ishizaka
`ps` 命令會告訴您有關正在執行的容器的許多資訊。您可以看到容器 ID、容器內執行的映象、用於啟動容器的命令、建立時間、狀態、暴露的埠以及容器的名稱。
您可能想知道容器的名稱從何而來。由於您在啟動容器時沒有提供名稱,Docker 生成了一個隨機名稱。我們稍後會解決這個問題,但首先您需要停止容器。要停止容器,請執行 `docker stop` 命令,並傳入容器的名稱或 ID。
$ docker stop inspiring_ishizaka
inspiring_ishizaka
現在重新執行 `docker ps` 命令,檢視正在執行的容器列表。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
停止、啟動和命名容器
Docker 容器可以啟動、停止和重新啟動。當您停止一個容器時,它並沒有被移除,只是狀態變為停止,並且容器內的程序也停止了。當您執行 `docker ps` 命令時,預設輸出只顯示正在執行的容器。如果您傳遞 `--all` 或簡寫為 `-a`,您將看到系統上的所有容器,包括已停止的容器和正在執行的容器。
$ docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d75e61fcad1e docker-gs-ping "/docker-gs-ping" About a minute ago Exited (2) 23 seconds ago inspiring_ishizaka
f65dbbb9a548 docker-gs-ping "/docker-gs-ping" 3 minutes ago Exited (2) 2 minutes ago wizardly_joliot
aade1bf3d330 docker-gs-ping "/docker-gs-ping" 3 minutes ago Exited (2) 3 minutes ago magical_carson
52d5ce3c15f0 docker-gs-ping "/docker-gs-ping" 9 minutes ago Exited (2) 3 minutes ago gifted_mestorf
如果您一直跟著操作,您應該會看到列出了幾個容器。這些是您啟動並停止但尚未移除的容器。
重新啟動您剛剛停止的容器。找到容器的名稱,並用您系統上容器的名稱替換以下 `restart` 命令中的容器名稱。
$ docker restart inspiring_ishizaka
現在,再次使用 `ps` 命令列出所有容器
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d75e61fcad1e docker-gs-ping "/docker-gs-ping" 2 minutes ago Up 5 seconds 0.0.0.0:8080->8080/tcp inspiring_ishizaka
f65dbbb9a548 docker-gs-ping "/docker-gs-ping" 4 minutes ago Exited (2) 2 minutes ago wizardly_joliot
aade1bf3d330 docker-gs-ping "/docker-gs-ping" 4 minutes ago Exited (2) 4 minutes ago magical_carson
52d5ce3c15f0 docker-gs-ping "/docker-gs-ping" 10 minutes ago Exited (2) 4 minutes ago gifted_mestorf
請注意,您剛剛重新啟動的容器已在分離模式下啟動,並暴露了 8080 埠。另外,請注意容器的狀態是 `Up X seconds`。當您重新啟動容器時,它將使用最初啟動時使用的相同標誌或命令來啟動。
停止並移除所有容器,然後看看如何解決隨機命名問題。
停止您剛剛啟動的容器。找到您正在執行的容器的名稱,並用您系統上容器的名稱替換以下命令中的名稱。
$ docker stop inspiring_ishizaka
inspiring_ishizaka
既然您的所有容器都已停止,請將其移除。當容器被移除時,它不再執行,也不處於停止狀態。相反,容器內的程序被終止,容器的元資料被移除。
要移除容器,請執行 `docker rm` 命令,並傳入容器名稱。您可以在一個命令中向該命令傳遞多個容器名稱。
再次強調,請務必將以下命令中的容器名稱替換為您系統中的容器名稱。
$ docker rm inspiring_ishizaka wizardly_joliot magical_carson gifted_mestorf
inspiring_ishizaka
wizardly_joliot
magical_carson
gifted_mestorf
再次執行 `docker ps --all` 命令以驗證所有容器都已消失。
現在,解決惱人的隨機命名問題。標準做法是為容器命名,原因很簡單:更容易識別容器中執行的內容以及它與哪個應用程式或服務相關聯。就像您程式碼中變數的良好命名約定使其更易於閱讀一樣,容器命名也遵循同樣的道理。
要命名容器,您必須將 `--name` 標誌傳遞給 `run` 命令
$ docker run -d -p 8080:8080 --name rest-server docker-gs-ping
3bbc6a3102ea368c8b966e1878a5ea9b1fc61187afaac1276c41db22e4b7f48f
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3bbc6a3102ea docker-gs-ping "/docker-gs-ping" 25 seconds ago Up 24 seconds 0.0.0.0:8080->8080/tcp rest-server
現在,您可以根據名稱輕鬆識別您的容器。
後續步驟
在本模組中,您學習瞭如何執行容器和釋出埠。您還學習瞭如何管理容器的生命週期。然後,您瞭解了為容器命名的重要性,以便它們更容易識別。在下一模組中,您將學習如何在容器中執行資料庫並將其連線到您的應用程式。