這是學習路徑的第四個教學課程,說明如何將單體式應用程式模組化及容器化。
這個學習路徑包含下列教學課程:
- 總覽
- 瞭解單體式架構
- 將單體應用程式模組化
- 準備將模組化應用程式容器化
- 將模組化應用程式容器化 (本教學課程)
- 將應用程式部署至 GKE 叢集
在上一個教學課程「準備將模組化應用程式容器化」中,您瞭解了為準備容器化,Cymbal Books 應用程式的模組化版本需要進行哪些變更。在本教學課程中,您會將應用程式容器化。
費用
完成本教學課程不會產生任何費用。不過,按照本系列下一個教學課程的步驟操作時,系統會向您的Trusted Cloud by S3NS 帳戶收費。啟用 GKE 並將 Cymbal Books 應用程式部署至 GKE 叢集後,就會開始產生費用。這些費用包括 GKE 的叢集費用 (如定價頁面所述),以及執行 Compute Engine VM 的費用。
為避免產生不必要的費用,請務必在完成本教學課程後停用 GKE 或刪除專案。
事前準備
開始本教學課程前,請先完成本系列先前的教學課程。如要查看整個系列課程的總覽,以及特定教學課程的連結,請參閱「學習路徑:將單體式應用程式轉換為 GKE 應用程式 - 總覽」。
設定環境
在本節中,您將設定環境,以便將模組化應用程式容器化。具體來說,您會執行下列步驟:
- 選取或建立 Trusted Cloud by S3NS 專案
- 啟用必要的 API
- 將 Cloud Shell 連線至 Trusted Cloud by S3NS 專案。
- 設定預設環境變數
- 在 Artifact Registry 中建立存放區
- 為 Artifact Registry 設定 Docker
- 取得教學課程程式碼
選取或建立 Trusted Cloud by S3NS 專案
-
In the Trusted Cloud console, on the project selector page, select or create a Trusted Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
Verify that billing is enabled for your Trusted Cloud project.
啟用必要的 API
如要在 Trusted Cloud by S3NS 專案中使用容器映像檔和 Kubernetes,請啟用下列 API:
- Artifact Registry API:這項 API 可啟用 Artifact Registry,這項服務用於儲存及管理容器映像檔。
- Kubernetes Engine API:這個 API 可存取 GKE。
如要啟用這些 API,請前往啟用 API Trusted Cloud 控制台。
將 Cloud Shell 連線至 Trusted Cloud by S3NS 專案
Trusted Cloud by S3NS 專案設定完成後,請啟動 Cloud Shell 執行個體,並連結至 Trusted Cloud by S3NS專案。Cloud Shell 是一種指令列工具,可讓您直接在瀏覽器中建立及管理專案資源。Cloud Shell 已預先安裝兩項重要工具:gcloud CLI 和 kubectl
CLI。在本教學課程中,您將使用 gcloud CLI 與 Trusted Cloud by S3NS 互動,而在下一個教學課程中,您將使用 kubectl
CLI 管理在 GKE 上執行的 Cymbal Books 應用程式。
如要將 Cloud Shell 執行個體連線至專案,請按照下列步驟操作: Trusted Cloud by S3NS
前往 Trusted Cloud 控制台:
在控制台中,按一下「啟用 Cloud Shell」按鈕:
此時 Cloud Shell 工作階段會在控制台底部的頁框中開啟,
使用下列指令,在 Google Cloud CLI 中設定預設專案:
gcloud config set project PROJECT_ID
將
PROJECT_ID
替換為您在上一節建立或選取的專案 ID,選取或建立 Trusted Cloud by S3NS 專案。 專案 ID 是專屬字串,可將您的專案與 Trusted Cloud by S3NS中的所有其他專案區分開來。如要找出專案 ID,請前往專案選取器。您可以在該頁面查看每個專案的專案 ID。 Trusted Cloud by S3NS
設定預設環境變數
為簡化本教學課程中執行的指令,您現在要在 Cloud Shell 中設定一些環境變數。這些變數會儲存專案 ID、存放區區域和映像檔標記等值。定義這些變數後,您就可以在多個指令中重複使用這些變數,方法是參照變數名稱 (例如 $REPOSITORY_NAME
),而不必每次都重新輸入或取代值。這種做法可讓您更輕鬆地跟上本教學課程,並降低出錯風險。
如要使用 Cloud Shell 設定環境,請執行下列步驟:
export PROJECT_ID=$(gcloud config get project)
export REPOSITORY_REGION=REPOSITORY_REGION
export REPOSITORY_NAME=REPOSITORY_NAME
export REPOSITORY_DESCRIPTION="REPOSITORY_DESCRIPTION"
export TAG=TAG
更改下列內容:
REPOSITORY_REGION
:您要代管 Artifact Registry 存放區的區域。例如us-central1
(愛荷華州)、us-west1
(奧勒岡州) 或europe-west1
(比利時)。如需完整地區清單,請參閱「地區和區域」一文。REPOSITORY_NAME
:存放區名稱。 例如:book-review-service-repo
。REPOSITORY_DESCRIPTION
:簡要說明存放區的用途。例如:"Repository for storing Docker images for the book review service"
。TAG
:要套用至圖片的標記。 標記是可附加至特定容器映像檔版本的標籤。您可以採用下列標記命名慣例,清楚指出不同版本的映像檔:v1
v1.2.3
- 描述性標記,例如
feature-x-dev
- 指出環境的標記,例如
test
在 Artifact Registry 中建立存放區
接著,在 Artifact Registry 中建立存放區。存放區是儲存容器映像檔的儲存位置。建構容器映像檔時,您需要將其儲存在某處,以便稍後部署至 Kubernetes 叢集。您可以在 Trusted Cloud by S3NS 專案中建立及管理這些存放區。
如要在 Artifact Registry 中建立存放區,請執行下列指令:
gcloud artifacts repositories create ${REPOSITORY_NAME} \
--repository-format=docker \
--location=${REPOSITORY_REGION} \
--description="${REPOSITORY_DESCRIPTION}"
指令成功輸出內容如下所示:
Waiting for operation [...] to complete...done.
Created repository [book-review-service-repo].
為 Artifact Registry 設定 Docker
接著,您要設定 Docker,確保 Docker 能安全地與Trusted Cloud的 Artifact Registry 通訊。Docker 是一種工具,可用於在不同環境中以一致的方式封裝及執行軟體。下一節將進一步說明 Docker 的運作方式。目前您需要設定,讓其連線至 Artifact Registry。
如果未以這種方式設定 Docker,您就無法將容器映像檔推送至 Artifact Registry (您會在稍後的本教學課程中執行這項工作)。您也無法從 Artifact Registry 提取容器映像檔,並將其部署至 GKE 叢集 (您會在下一個教學課程中執行這項工作)。
如要設定 Docker 向 Artifact Registry 進行驗證,請執行下列指令:
gcloud auth configure-docker ${REPOSITORY_REGION}-docker.pkg.dev
取得教學課程程式碼
Cloud Shell 環境設定完成後,您需要在 Cloud Shell 中下載教學課程程式碼。即使您先前已在本機電腦上複製存放區,仍須在 Cloud Shell 執行個體上再次複製。
雖然您可以在本機完成本教學課程,但必須手動安裝及設定 Docker、kubectl
和 gcloud CLI 等多種工具。Cloud Shell 預先設定了所有這些工具,因此使用起來更輕鬆。
在 Cloud Shell 執行個體中,執行下列指令來複製 GitHub 存放區:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
容器化基礎知識:容器映像檔、容器和 Dockerfile
您已設定環境並下載容器化程式碼,現在可以開始將應用程式容器化。將應用程式容器化時,請使用 Dockerfile 將 Cymbal Books 的每個模組 (首頁、書籍詳細資料、圖片和書評) 封裝到容器映像檔中。應用程式部署至 GKE 叢集後,Kubernetes 會使用這些容器映像檔,在叢集中建立執行中的容器。
以下各節將詳細說明這些概念。
什麼是容器化?
容器化技術會將模組及其所有依附元件 (例如程式庫和設定檔) 封裝成單元,也就是容器映像檔。開發人員可以使用這個容器映像檔,在任何環境中建立及執行容器,包括開發人員的筆電、測試伺服器或 Kubernetes 生產環境叢集。
什麼是容器映像檔?
容器映像檔包含執行應用程式所需的所有檔案。這些檔案包括應用程式程式碼本身、系統程式庫、執行階段環境 (例如 Python 解譯器)、靜態資料和任何其他依附元件。
在本教學課程中,您會為書評應用程式的每個模組建立容器映像檔。
什麼是容器?
容器是獨立的環境,可執行容器映像檔中的程式碼。
您可以透過兩種方式建立容器:在開發期間使用 docker run
指令進行測試,或是將容器映像檔部署至 Kubernetes 叢集。
在容器化版本的 Cymbal Books 應用程式中,模組化應用程式的每個模組都會在自己的容器中執行:
- 首頁容器會執行首頁模組,並處理對
/
的要求。 - 書籍詳細資料容器會執行書籍詳細資料模組,並為
/book/1
或/book/3
等端點提供資料。 - 書評容器會執行書評模組,並管理對
/book/2/reviews
等端點的要求。 - 圖片容器會執行圖片模組,並為
/images/fungi_frontier.jpg
等端點提供書籍封面圖片。
容器的主要優點是 Kubernetes 可在需要時自動建立更多容器。舉例來說,如果許多使用者都在閱讀書評,Kubernetes 可以啟動額外的書評容器來處理負載。
如要在未使用容器的模組化應用程式中實作擴縮功能,您需要編寫自訂程式碼,啟動模組的新例項,並在這些例項之間分配流量。Kubernetes 內建這項資源調度功能,您不必編寫任何自訂資源調度程式碼。
什麼是 Dockerfile?
Dockerfile 是一種指令碼,用於定義如何將模組封裝至容器映像檔。在本教學課程中,您不需要建立任何 Dockerfile,因為稍早複製的 GitHub 存放區中已提供這些檔案。在 kubernetes-engine-samples/quickstarts/monolith-to-microservices/containerized/
的本機副本中,每個模組的目錄都包含自己的 Dockerfile。
舉例來說,您可以在 Cloud Shell 執行個體的 kubernetes-engine-samples/quickstarts/monolith-to-microservices/containerized/home_app/Dockerfile
中找到 home_app
模組的 Dockerfile。這個 Dockerfile 如下所示:
# Dockerfile for home_app
FROM python:3.9-slim #line 1
WORKDIR /app #line 2
COPY requirements.txt . #line 3
RUN pip install --no-cache-dir -r requirements.txt #line 4
COPY home_app.py . #line 5
COPY templates/ ./templates/ #line 6
COPY static/ ./static/ #line 7
CMD ["python", "home_app.py"] #line 8
這個 Dockerfile 會執行下列步驟,為 home_app
模組建立容器映像檔:
- 第 1 行:
FROM python:3.9-slim
會將 Python 3.9 解譯器及其必要檔案下載到容器映像檔中。這些檔案可讓模組執行。 - 第 2 行:
WORKDIR /app
會在容器內建立名為/app
的目錄,並將這個目錄設為目前的工作目錄。在容器內執行的所有指令都會從這個目錄執行。 - 第 3 和 4 行:
COPY requirements.txt .
會將本機電腦中的requirements.txt
檔案複製到容器映像檔的/app
目錄。requirements.txt
檔案會列出home_app.py
需要的所有 Python 程式庫。RUN pip install
這行程式碼會將這些程式庫安裝到容器映像檔中。 - 第 5 至 7 行:這些行中顯示的
COPY
指令會將模組的程式碼 (home_app.py
) 及其支援檔案 (範本和靜態資產) 複製到容器映像檔中的/app
目錄。 - 第 8 行:
CMD
指定 Docker 在容器啟動時執行的預設指令。在這個 Dockerfile 中,CMD ["python", "home_app.py"]
會指示 Docker 在容器啟動時,使用 Python 解譯器自動執行home_app.py
模組。
容器化如何強制執行更嚴格的資料隔離
Dockerfile 的第 5 至 7 行 (如上一節所述) 說明,與應用程式的模組化版本相比,容器化如何強制執行更嚴格的資料隔離。在先前的教學課程中,您在「只允許每個模組存取所需資料」一節中瞭解到,應用程式的模組化版本會將資料整理到不同的目錄中,但模組仍共用相同檔案系統,因此可能會存取彼此的資料。
在應用程式的容器化版本中,每個模組的容器只包含必要檔案。舉例來說,如果 home_app
模組不需要存取書籍評論資料,該資料就不會存在於 home_app
容器中。根據預設,容器無法存取其他容器的檔案,除非明確設定允許存取。這有助於確保每個模組完全隔離,並防止意外或未經授權的資料存取。
在下一節中,您會看到 docker build
指令如何將 Dockerfile 做為輸入內容,並按照 Dockerfile 中的指示建立容器映像檔。
使用 Docker 建構容器映像檔
在本節中,您將為每個書評模組建構 Docker 容器映像檔,並將其推送至 Artifact Registry 存放區。您將在後續教學課程中使用這些容器映像檔,在 Kubernetes 中部署及執行 Cymbal Books 範例應用程式。
前往容器化應用程式的根目錄:
cd kubernetes-engine-samples/quickstarts/monolith-to-microservices/containerized/
使用
docker build
指令建立容器映像檔:docker build -t ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/home-app:${TAG} ./home_app docker build -t ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/book-details-app:${TAG} ./book_details_app docker build -t ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/book-reviews-app:${TAG} ./book_reviews_app docker build -t ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/images-app:${TAG} ./images_app
查看在 Cloud Shell 執行個體中建構的容器映像檔:
docker images
確認清單中顯示下列圖片:
home-app
book-details-app
book-reviews-app
images-app
如果列出所有四張圖片,表示您已成功建立容器映像檔。
在 Cloud Shell 中測試容器
如要確認容器映像檔是否建構正確,可以將其做為容器執行,並在 Cloud Shell 中測試端點。
book_details_app
、book_reviews_app
和 images_app
容器不需要彼此通訊,因此可以個別測試。不過,使用 Docker 測試 home_app
容器很困難,因為 home_app
會設定為尋找使用服務名稱 (例如 http://book-details-service:8081
) 的其他容器。
雖然可以透過找出每個容器的 IP 位址,並將 home_app
設為使用這些位址 (而非服務名稱) 來測試 home_app
容器,但這種做法需要投入大量心力。建議您先將應用程式部署至 Kubernetes 叢集,再測試 home_app
容器。應用程式位於叢集上後,您可以判斷主模組是否正常運作。
請按照下列步驟測試容器:
啟動
book_details_app
、book_reviews_app
和images_app
容器:docker run -d -p 8081:8080 ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/book-details-app:${TAG} docker run -d -p 8082:8080 ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/book-reviews-app:${TAG} docker run -d -p 8083:8080 ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/images-app:${TAG}
列出所有使用中的容器,確認容器是否正在執行:
docker ps
這項指令的輸出內容應顯示三個正在執行的容器,狀態為
Up
:CONTAINER ID IMAGE PORTS STATUS a1b2c3d4e5f6 REGION/.../details 0.0.0.0:8081->8080/tcp Up g7h8i9j0k1l2 REGION/.../reviews 0.0.0.0:8082->8080/tcp Up m3n4o5p6q7r8 REGION/.../images 0.0.0.0:8083->8080/tcp Up
如要測試
book_details_app
容器的端點,請使用下列curl
指令:curl http://localhost:8081/books curl http://localhost:8081/book/1 curl http://localhost:8081/book/2 curl http://localhost:8081/book/3
這些指令都會以 JSON 格式傳回資料。舉例來說,
curl http://localhost:8081/book/1
指令的輸出內容如下所示:{"author":"Aria Clockwork","description":"In a world where time is a tangible substance, a young clockmaker discovers she can manipulate the fabric of time itself, leading to unforeseen consequences in her steampunk-inspired city.","id":1,"image_url":"zephyrs_timepiece.jpg","title":"Zephyr's Timepiece","year":2023}
使用這個
curl
指令,從book_reviews_app
容器擷取書評:curl http://localhost:8082/book/1/reviews
這個指令會以 JSON 格式傳回書籍 1 的 20 則評論清單。以下是清單中的其中一則評論範例:
{ "content": "The concept of time as a tangible substance is brilliantly explored in 'Zephyr's Timepiece'.", "rating": 5 }
測試
images_app
容器:按一下
**Web Preview**
按鈕選取「變更通訊埠」,然後輸入 8083。瀏覽器視窗隨即開啟,並顯示類似下列的網址:
https://8083-your-instance-id.cs-your-region.cloudshell.dev/?authuser=0
移除網址結尾的
?authuser=0
,並新增圖片檔案的路徑,例如/images/fungi_frontier.jpg
。範例如下:https://8083-your-instance-id.cs-your-region.cloudshell.dev/images/fungi_frontier.jpg
瀏覽器中應該會顯示「Fungi Frontier」的封面圖片。
測試完成後,請停止容器以釋出資源:
列出正在執行的容器,並找出容器 ID:
docker ps
停止每個容器:
docker stop CONTAINER_ID
將
CONTAINER_ID
替換為要停止的容器 ID。
將容器映像檔推送至 Artifact Registry
將應用程式部署至 Kubernetes 叢集前,必須先將容器映像檔儲存在叢集可存取的位置。在本步驟中,您會將映像檔推送至先前建立的 Artifact Registry 存放區。在下一個教學課程中,您會將這些映像檔從 Artifact Registry 存放區部署到 GKE 叢集:
如要將容器映像檔推送至 Artifact Registry,請執行下列指令:
docker push ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/home-app:${TAG} docker push ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/book-details-app:${TAG} docker push ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/book-reviews-app:${TAG} docker push ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/images-app:${TAG}
推送映像檔後,請列出映像檔,確認是否已成功上傳:
gcloud artifacts docker images list ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}
輸出結果應該會類似下列內容:
Listing items under project ${PROJECT_ID}, location ${REPOSITORY_REGION}, repository ${REPOSITORY_NAME}. IMAGE: ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/book-details-app DIGEST: sha256:f7b78f44d70f2eedf7f7d4dc72c36070e7c0dd05daa5f473e1ebcfd1d44b95b1 CREATE_TIME: 2024-11-14T00:38:53 UPDATE_TIME: 2024-11-14T00:38:53 SIZE: 52260143 IMAGE: ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/book-reviews-app DIGEST: sha256:875ac8d94ef54db2ff637e49ad2d1c50291087623718b854a34ad657748fac86 CREATE_TIME: 2024-11-14T00:39:04 UPDATE_TIME: 2024-11-14T00:39:04 SIZE: 52262041 IMAGE: ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/home-app DIGEST: sha256:70ddc54ffd683e2525d87ee0451804d273868c7143d0c2a75ce423502c10638a CREATE_TIME: 2024-11-14T00:33:56 UPDATE_TIME: 2024-11-14T00:33:56 SIZE: 52262412 IMAGE: ${REPOSITORY_REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY_NAME}/images-app DIGEST: sha256:790f0d8c2f83b09dc3b431c4c04d7dc68254fecc76c48f00a83babc2a5dc0484 CREATE_TIME: 2024-11-14T00:39:15 UPDATE_TIME: 2024-11-14T00:39:15 SIZE: 53020815
輸出內容會顯示每張圖片的詳細資訊,如下所示:
- IMAGE:存放區路徑和映像檔名稱。
- 摘要:圖片的專屬 ID。
- CREATE_TIME 或 UPDATE_TIME:圖片的建立時間或上次修改時間。
- SIZE:圖片大小 (以位元組為單位)。
使用容器映像檔路徑更新 Kubernetes 資訊清單
如您在先前的教學課程「準備將模組化應用程式容器化」中所學,Kubernetes 資訊清單是 YAML 檔案,用於定義應用程式在 Kubernetes 叢集中的執行方式。包括下列詳細資料:
- 應用程式的模組 (例如
home-app
、book-details-app
) - 容器映像檔的路徑
- 設定詳細資料,例如資源限制
- 用於在模組之間轉送要求的服務定義
在本節中,您會更新先前教學課程中查看的資訊清單檔案。該檔案為 kubernetes-manifest.yaml
,內含圖片路徑的預留位置值。您需要將這些預留位置,替換為您在上一節中推送至 Artifact Registry 存放區的容器映像檔實際路徑。
如要更新 kubernetes-manifest.yaml
Kubernetes 資訊清單檔案,請按照下列步驟操作:
在 Cloud Shell 中,前往
containerized/
目錄,其中包含 Kubernetes 資訊清單檔案kubernetes-manifest.yaml
:cd kubernetes-engine-samples/quickstarts/monolith-to-microservices/containerized/
在文字編輯器中開啟
kubernetes-manifest.yaml
檔案:vim kubernetes-manifest.yaml
找出含有預留位置的
image
欄位,例如:image: REPOSITORY_REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY_NAME/home-app:TAG
將每個預留位置替換為您推送至 Artifact Registry 的容器映像檔實際路徑:
REPOSITORY_REGION
:您在 Artifact Registry 中建立存放區時指定的區域。PROJECT_ID
:您的 Trusted Cloud by S3NS 專案 ID,可在專案選取器頁面中找到。REPOSITORY_NAME
:存放區名稱,也就是您在 Artifact Registry 中建立存放區時指定的名稱。例如:book-review-service-repo
。TAG
:您在建構容器映像檔時選擇的標記。
完成這些取代作業後,路徑可能如下所示:
image:us-west1-docker.pkg.dev/your-project-id/book-review-service-repo/home-app:v1
更新所有容器映像檔的路徑:
home-app
book-details-app
book-reviews-app
images-app
更新路徑後,請儲存資訊清單檔案並關閉編輯器。舉例來說,如果您使用 vim,請按下 Esc 鍵進入指令模式,輸入 wq,然後按下 Enter 鍵儲存並退出。
Kubernetes 資訊清單現已設定完畢,可將 Artifact Registry 存放區中的容器映像檔部署至 Kubernetes 叢集。
摘要
在本教學課程中,您已完成下列工作,為部署至 Kubernetes 叢集的模組化 Cymbal Books 應用程式做好準備:
- 設定專案,並為環境設定 Cloud Shell。 Trusted Cloud by S3NS
- 查看每個應用程式模組的 Dockerfile。
- 使用 Docker 建構應用程式模組的容器映像檔。
- 在 Cloud Shell 中測試容器,確認功能正常運作。
- 將容器映像檔推送至 Artifact Registry 儲存。
- 更新 Kubernetes 資訊清單,以使用 Artifact Registry 中的正確容器映像檔路徑。
後續步驟
在下一個教學課程「將應用程式部署至 GKE 叢集」中,您會將容器化應用程式部署至 GKE 叢集。