多容器應用程式
解釋
啟動單個容器應用程式很容易。例如,執行特定資料處理任務的 Python 指令碼可以在包含所有依賴項的容器內執行。類似地,使用小型 API 端點提供靜態網站的 Node.js 應用程式可以使用其所有必要庫和依賴項進行有效地容器化。但是,隨著應用程式規模的增長,將它們作為單個容器進行管理變得越來越困難。
想象一下,資料處理 Python 指令碼需要連線到資料庫。突然之間,你不僅要管理指令碼,還要在同一個容器中管理資料庫伺服器。如果指令碼需要使用者登入,你需要一個身份驗證機制,這會進一步增加容器大小。
容器的最佳實踐之一是每個容器應該只做一件事,並且做好這件事。雖然這個規則有例外,但要避免在一個容器中做多件事的趨勢。
現在你可能會問,“我需要單獨執行這些容器嗎?如果我單獨執行它們,我應該如何將它們連線在一起?”
雖然 docker run
是一個方便的啟動容器工具,但使用它來管理不斷增長的應用程式堆疊變得很困難。這是因為
- 想象一下,執行多個
docker run
命令(前端、後端和資料庫),它們使用不同的配置來應對開發、測試和生產環境。這很容易出錯,而且很耗時。 - 應用程式通常依賴於彼此。隨著堆疊的擴充套件,以特定順序手動啟動容器和管理網路連線變得很困難。
- 每個應用程式都需要其
docker run
命令,這使得難以擴充套件各個服務。擴充套件整個應用程式意味著可能在不需要提升的元件上浪費資源。 - 持久化每個應用程式的資料需要在每個
docker run
命令中單獨進行卷掛載或配置。這會建立一種分散的資料管理方法。 - 透過單獨的
docker run
命令為每個應用程式設定環境變數既繁瑣又容易出錯。
這就是 Docker Compose 出現的地方。
Docker Compose 在一個名為 compose.yml
的單個 YAML 檔案中定義你的整個多容器應用程式。該檔案指定了所有容器的配置、它們的依賴關係、環境變數,甚至卷和網路。使用 Docker Compose
- 你不需要執行多個
docker run
命令。你只需要在一個 YAML 檔案中定義你的整個多容器應用程式即可。這集中了配置並簡化了管理。 - 你可以按特定順序執行容器,並輕鬆管理網路連線。
- 你只需在多容器設定中輕鬆地向上或向下擴充套件各個服務。這允許根據即時需求進行有效的分配。
- 你可以輕鬆地實現持久化卷。
- 在 Docker Compose 檔案中設定環境變數非常容易。
透過利用 Docker Compose 執行多容器設定,你可以在應用程式的核心構建模組化、可擴充套件性和一致性。
試一試
在本實踐指南中,你將首先了解如何使用 docker run
命令構建和執行基於 Node.js、Nginx 反向代理和 Redis 資料庫的計數器 Web 應用程式。你還將瞭解如何使用 Docker Compose 簡化整個部署過程。
設定
獲取示例應用程式。如果你有 Git,你可以克隆示例應用程式的儲存庫。否則,你可以下載示例應用程式。選擇以下選項之一。
在終端中使用以下命令克隆示例應用程式儲存庫。
$ git clone https://github.com/dockersamples/nginx-node-redis
導航到
nginx-node-redis
目錄$ cd nginx-node-redis
在這個目錄中,你會發現兩個子目錄 -
nginx
和web
。下載原始碼並解壓縮它。
導航到
nginx-node-redis-main
目錄$ cd nginx-node-redis-main
在這個目錄中,你會發現兩個子目錄 -
nginx
和web
。下載並安裝 Docker Desktop。
構建映象
導航到
nginx
目錄,透過執行以下命令構建映象$ docker build -t nginx .
導航到
web
目錄,執行以下命令構建第一個 Web 映象$ docker build -t web .
執行容器
在執行多容器應用程式之前,你需要為它們建立一個網路,讓它們可以相互通訊。你可以使用
docker network create
命令來實現$ docker network create sample-app
透過執行以下命令啟動 Redis 容器,該命令會將其附加到之前建立的網路,並建立一個網路別名(對 DNS 查詢很有用)
$ docker run -d --name redis --network sample-app --network-alias redis redis
透過執行以下命令啟動第一個 Web 容器
$ docker run -d --name web1 -h web1 --network sample-app --network-alias web1 web
透過執行以下命令啟動第二個 Web 容器
$ docker run -d --name web2 -h web2 --network sample-app --network-alias web2 web
透過執行以下命令啟動 Nginx 容器
$ docker run -d --name nginx --network sample-app -p 80:80 nginx
注意
Nginx 通常用作 Web 應用程式的反向代理,將流量路由到後端伺服器。在本例中,它路由到 Node.js 後端容器(web1 或 web2)。
透過執行以下命令驗證容器是否已啟動
$ docker ps
你將看到類似以下的輸出
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2cf7c484c144 nginx "/docker-entrypoint.…" 9 seconds ago Up 8 seconds 0.0.0.0:80->80/tcp nginx 7a070c9ffeaa web "docker-entrypoint.s…" 19 seconds ago Up 18 seconds web2 6dc6d4e60aaf web "docker-entrypoint.s…" 34 seconds ago Up 33 seconds web1 008e0ecf4f36 redis "docker-entrypoint.s…" About a minute ago Up About a minute 6379/tcp redis
如果你檢視 Docker Dashboard,你可以看到容器,並深入瞭解它們的配置。
在一切啟動並執行之後,你可以在瀏覽器中開啟 https://,檢視網站。重新整理頁面幾次,檢視處理請求的主機和請求的總數
web2: Number of visits is: 9 web1: Number of visits is: 10 web2: Number of visits is: 11 web1: Number of visits is: 12
注意
你可能已經注意到,Nginx 充當反向代理,很可能以輪詢方式在兩個後端容器之間分配傳入的請求。這意味著每個請求都可能被定向到不同的容器(web1 和 web2),以輪流的方式進行。輸出顯示 web1 和 web2 容器的連續增量,並且只有在響應傳送回客戶端之後,儲存在 Redis 中的實際計數器值才會更新。
你可以使用 Docker Dashboard 透過選擇容器並選擇刪除按鈕來刪除容器。
使用 Docker Compose 簡化部署
Docker Compose 為管理多容器部署提供了結構化和簡化的方式。如前所述,使用 Docker Compose,你不需要執行多個 docker run
命令。你只需要在一個名為 compose.yml
的單個 YAML 檔案中定義你的整個多容器應用程式。讓我們看看它是如何工作的。
導航到專案的根目錄。在這個目錄中,你會發現一個名為 compose.yml
的檔案。這個 YAML 檔案就是所有魔法發生的地方。它定義了構成應用程式的所有服務,以及它們的配置。每個服務都指定了它的映象、埠、卷、網路以及任何其他使其正常執行所需的設定。
使用
docker compose up
命令啟動應用程式$ docker compose up -d --build
當你執行此命令時,你應該看到類似以下的輸出
Running 5/5 ✔ Network nginx-nodejs-redis_default Created 0.0s ✔ Container nginx-nodejs-redis-web1-1 Started 0.1s ✔ Container nginx-nodejs-redis-redis-1 Started 0.1s ✔ Container nginx-nodejs-redis-web2-1 Started 0.1s ✔ Container nginx-nodejs-redis-nginx-1 Started
如果你檢視 Docker Dashboard,你可以看到容器,並深入瞭解它們的配置。
或者,你可以使用 Docker Dashboard 透過選擇應用程式堆疊並選擇刪除按鈕來刪除容器。
在本指南中,你瞭解了與 docker run
相比,使用 Docker Compose 啟動和停止多容器應用程式是多麼容易,而 docker run
容易出錯且難以管理。