容器正在以很快的速度成為軟體應用部署的業界標準。 容器化所帶來的商業以及技術上的好處正在推動很多團隊將他們的應用移到容器內。 本教程會提供一個基礎的示範, 示範如何將一個無狀態的應用, 從 VM 上轉移到 Kubernetes Engine (GKE), 本範例示範了應用轉移的過程, 從典型的 VM/OS-based 部署, 到特定的容器化的 os, 再到一個你所知道的容器專用的平台 GKE
概述
容器化部署應用有許多的好處, 像是:
- 隔離 - 應用們有各自的 libraries; 各個應用之間不會因為有不同的 libraries 而產生衝突。
- 限制(CPU/memory) - 應用們不會佔用其他應用的資源
- 可攜帶 - 容器含有任何所需的東西, 且不會被 OS 或雲端服務商綁死
- 輕量化 - 共享 Kernel, 比完整的 OS 鏡像還要輕量且快速
學習目標
這個專案示範了轉移一個名為 Prime-flask 的簡單 Python 應用, 到:
- 一台 虛擬機(Debian VM),
Prime-flask
是被部署在這台機器上的唯一應用, 就好像是傳統的運行在一台實體資料中心上的應用。 - 一個容器化版本的
Prime-flask
, 被部署在 Container-Optimized OS (COS) - 使用 [Kubernetes] 將
Prime-flask
部署在 Kubernetes Engine 上, 並且使負載平衡來暴露服務。
在完成部署後, 你將會針對最後版本的部署實施一個負載測試, 並且擴縮服務來適應負載
在教程途中, 如果有遇到什麼錯誤, 可以重新執行失敗的 script, 因為偶而會因為網路連線問題出錯, 重試之後就好了。
本教程由 GKE Helmsman 工程師建立, 讓你更了解如何轉移到容器。 你可以在這檢視範例, 並且, 我們歡迎任何人貢獻這個專案。
架構
佈局 1: 運行 Debian 的虛擬機, 應用被直接部署到主機的 OS, 無容器
佈局 2: 虛擬機運行容器優化的 OS, 應用被部署在容器內
佈局 3: Kubernetes Engine (GKE) 平台, 很多容器運行在很多機器上
用於此範例的一個簡單的 Python Flask web 應用 (Prime-flask
) 已被建立, 並且擁有兩個端點:http://<ip>:8080/factorial/
以及 http://<ip>:8080/prime/
使用範例如下:
curl http://35.227.149.80:8080/prime/10 |
以及也可用來驗證是否成功部署
設定及要求
在你按下 Start Lab 按鈕之前
詳讀所有的教學。 Labs 是有時間限制的, 而且你不可以停止時間倒數。 倒數計時器在你按下 Start Lab 按鈕後開始倒數, 上面顯示的時間為你還能使用 Cloud 資源的時間。
Qwiklabs 的手把手環境, 讓你可以在真實環境中來操作進行 Qwiklabs 上提供的課程, 而不是在一個模擬或是展示的環境。 我們透過提供你一個全新的、暫時的帳號密碼, 在計時器歸零之前, 你可以用來登入並存取 Google Cloud Platform。
你需要什麼?
要完成這個 lab, 你需要:
- 一個一般的網路瀏覽器(推薦 Chrome)
- 完成這個 lab 的時間
備註: 如果你已經有你自己的個人 GCP 帳號或專案,請不要使用在這一個 lab
現在你已經開始你的 lab
, 你將會登入 Google Cloud Shell
主控台, 然後開啟命令列工具
如何開始你的 lab, 然後登入 Console?
- 按下 Start Lab 按鈕。 如果你需要付費, 會有一個彈出視窗來讓你選擇付費的方式。 在左方你會看到一個面板, 上面有暫時的帳號密碼, 你必須使用這些帳號密碼在此次 lab
- 複製
username
, 然後點擊Open Google Console
。 Lab 會開啟另外一個視窗, 顯示選擇帳號
的頁面
tip: 開啟一個全新的視窗,然後跟原本的頁面並排
- 在
選擇帳號
頁面, 點擊Use Another Account
- 登入頁面開啟, 貼上之前複製的
username
以及password
, 然後貼上
重要: 必須使用之前於 Connection Details 面板
取得的帳號密碼,不要使用你自己的 Qwiklabs 帳號密碼。 如果你有自己的 GCP 帳號, 請不要用在這裡(避免產生費用)
- 點擊並通過接下來的頁面:
- 接受
terms
以及conditions
- 不要增加
recovery optoins
或two factor authentication
(因為這只是一個臨時帳號) - 不要註冊免費體驗
- 接受
稍待一些時候, GCP 控制台將會在這個視窗開啟。
注意: 按下左上方位於 Google Cloud Platform
隔壁的 Navigation menu
, 你可以瀏覽選單, 裡面有一系列的 GCP 產品以及服務
啟動 Google Cloud Shell
Google Cloud Shell
是載有開發工具的虛擬機器。 它提供了5GB的 home 資料夾, 並且運行在 Google Cloud
上。 Google Cloud Shell
讓你可以利用 command-line 存取 GCP
資源
- 在
GCP 控制台
, 右上的工具列,點擊Open Cloud Shell
按鈕
- 在打開的對話框裡, 按下
START CLOUD SHELL
:
你可以立即按下 START CLOUD SHELL
當對話視窗打開。
連結並提供環境會需要一點時間。 當你連結成功, 這代表你已成功獲得授權, 且此專案已被設為你的專案ID, 例如:
gcloud 是 Google Cloud Platform
的 command-line 工具, 他已事先被安裝在 Cloud Shell
並且支援自動補齊
使用這個 command, 你可以列出有效帳戶名稱:
gcloud auth list |
輸出:
Credentialed accounts: |
範例輸出:
Credentialed accounts: |
你可以使用以下 command 來列出專案 ID
gcloud config list project |
輸出:
[core] |
範例輸出:
[core] |
gcloud
的完整文件可以參閱 Google Cloud gcloud Overview
安裝 ApacheBench
現在安裝 ApacheBench:
sudo apt-get install apache2-utils |
當被詢問是否繼續是, 輸入 “y”
驗證安裝是否成功:
ab -V |
輸出應如下:
This is ApacheBench, Version 2.3 <$Revision: 1757674 $> |
建立虛擬環境
執行以下指令下載並更新套件清單:
sudo apt-get update |
Python 虛擬環境是被用來獨立系統內的套件安裝
sudo apt-get install vitualenv |
如果跳出 [Y/n], 選擇 Y
, 然後按 Enter
virtualenv -p python3 venv |
啟動虛擬環境
source venv/bin/activate |
複製倉庫
git clone https://github.com/GoogleCloudPlatform/gke-migration-to-containers.git |
到範例資料夾內:
cd gke-migration-to-containers |
設定你的 region 以及 zone
特定的 Compute Engine 資源位於 regions 以及 zones, 一個 region 為一個運行你的資源的特定地理位置, 然一個 region 有一或多個 zones
更多有關 regions 以及 zones 的資訊可以參考 Regions & Zones documentation
運行以下的指令來設定本教程中的 region 以及 zone (你也可以使用對你來說最佳的 region/zone)
gcloud config set compute/region us-central1 |
部署
這個專案需要的基礎設施可執行以下指令部署
make create |
這個範例的設定大概需要最多 15 分鐘。 如果沒有跳錯的話, 建議持續等待。 不要中斷 make create
的執行。 資源建立的過程中, 你可以從主控台的 Compute Engine > VM instances 確認目前進度。
等待過程中, 可以看一下 create.sh
script 的內容, 了解它幫你建立了什麼。
你可以使用編輯器來檢視 gke-migration-to-containers/scripts/create.sh
make create
指令執行了 create.sh script, 做了以下幾件事:
- 打包
Prime-flask
應用, 使它可以被複製到 Google Cloud Storage - 透過 Google Cloud Build 建立容器鏡像, 並推送到這個專案的 private Container Registry (GCR)
- 產生 Terraform 適當的設置
- 執行 Terraform, 建立上述的情境
範例輸出如下:
Terraform 建立一個 VM, COS VM, 以及 GKE 叢集:
Terraform 輸出顯示在 Debain VM 以及 COS 系統的 (factorial endpoints) 階乘端點:
Kubernetes 叢集以及 Prime-flask
服務也被啟動:
測試進度
點擊 Check my progress 來確認目前的進度。如果你已經成功建立基礎設施, 你將獲得一個評價分數。
探索 Prime-Flask 環境
三個不一樣的環境已經完成設置, Prime-flask app 可以橫跨這些環境, 成為一個在單一虛擬機上運行的容器化應用, 到一個 pod, 運行在一個編排容器的平台, 像是 Kubernetes
一旦你的資源已經準備就緒, 這對你探索系統來說有很大的幫助。
執行以下指令到 vm-webserver
機器, 在這台機器上, 應用正運行在主機的作業系統
gcloud compute ssh vm-webserver --zone us-central1-a |
如果有詢問是否繼續, 輸入 “Y”, 按下 Enter 兩次來確認不使用密碼
這個環境中沒有隔離效果, 攜帶性也不好。 在某種意義上, 這個應用具有整個系統的存取權, 且在一些其他因素下, 可能無法在失敗後自動回復。 若要擴充這個應用可能需要更多台的虛擬機, 而這很可能無法有效地利用資源。
列出所有程序:
ps aux |
(輸出)
root 882 0.0 1.1 92824 6716 ? Ss 18:41 0:00 sshd: user [priv] |
離開:
exit |
執行以下指令到 cos-vm
機器, 在這台機器上你運行著 docker 容器
gcloud compute ssh cos-vm --zone us-central1-a |
如果有詢問是否繼續, 輸入 “Y”, 按下 Enter 兩次來確認不使用密碼
COS 是一個優化過的作業系統, 作業系統佔用了很小的空間, 這也是它比較適合運行容器化工作的原因之一。 它是先安裝了 cloud-init 以及 Docker runtime, 而如果有些容器並不需要跑在一些高可靠性的平台的話, 也是很適合跑在這樣的系統。
你可以在宿主機上運行 ps aux
來檢視運行中的 prime-flask
ps aux |
注意到 docker 以及容器的參考資訊:
root 626 0.0 5.7 496812 34824 ? Ssl Mar19 0:14 /usr/bin/docker run --rm --name=flaskservice -p 8080:8080 gcr.io/migration-to-containers/prime-flask:1.0.2 |
並且, 如果你試著列出 python path, 會顯示不存在
ls /usr/local/bin/python |
(輸出)
ls: cannot access '/usr/local/bin/python': No such file or directory |
Docker 列出容器
sudo docker ps |
(輸出)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
現在你可以執行以下指令來檢視運行在容器內的程序:
sudo docker exec -it $(sudo docker ps |awk '/prime-flask/ {print $1}') ps aux |
(輸出)
PID USER TIME COMMAND |
退出:
exit |
接下來, 讓我們到 Kubernetes 環境。 在 Kubernetes 我們可以運行千百個 pods, pods 代表容器的群組。 Kubernetes 是現今部署容器的標準。 它提供了高生產力, 可靠性, 以及擴充性。 Kubernetes 讓你的容器有個家, 且當你的容器失敗了, 它會再次重啟它。 你可以使用很多機器來組成一個叢集, 所以你可以讓它橫跨了不同的區域, 確保了可用性, 以及一些對潛在問題的高適應性。
取得叢集配置:
gcloud container clusters get-credentials prime-server-cluster |
取得運行在預設命名空間下的 pods
kubectl get pods |
(輸出)
NAME READY STATUS RESTARTS AGE |
檢視 pod 內運行著什麼:
kubectl exec $(kubectl get pods -lapp=prime-server -ojsonpath='{.items[].metadata.name}') -- ps aux |
(輸出)
PID USER TIME COMMAND |
如你所見, python 應用目前正運行在容器內。 這個應用無法存取任何主機上的東西, 因為這個容器是被隔離的。 它運行在一個 Linux 命名空間, 且(預設)無法存取檔案, 網路, 或在 VM 上的, 在容器裡的, 或任何地方的其他資源。
驗證
現在此應用已被部署, 執行以下指令來驗證三種部署:
make validate |
API 可能會花一些時間完成。 立即執行 make validate
可能會出現錯誤, 但那是因為 instances 還沒有完成初始化。 等個 1 或 2 分鐘然後重試一次應可以解決任何問題。
一個成功的輸出將如下:
Validating Debian VM Webapp... |
當然, IP 位址會與你的不同。
負載測試
在 Cloud Shell 點擊 + 打開新的 Cloud Shell 視窗。
執行以下指令, 記得將 [IP_ADDRESS]
替換成從驗證輸出得到的 IP 位址以及 port, 注意 Kubernetes 部署運行在 port 80
, 而其他兩個部署運行在 port 8080
ab -c 120 -t 60 http://<IP_ADDRESS>/prime/10000 |
ApacheBench(ab
) 將在一分鐘內每秒鐘對指定端點發送 120 個併發請求。
範例應用的規模並不足以處理這個數量的請求。
結果可以經由 ab
指令的輸出來確認, 如果你看到一個 Failed requests
的值大於 0, 這表示 server 無法成功回應這個負荷
注意: 能不會三個資源都有錯誤
測試進度
點擊 Check my progress 來確認目前的進度。如果你已經成功地實施負載測試, 你將獲得一個評價分數。
若要確保你的系統可以處理這樣的流量, 可以使用擴充。 在此範例中, 我們將水平的擴充服務
在 Debian 以及 COS 架構, 水平擴充包含:
- 建立一個平衡負載
- 開啟額外的機器
- 使用平衡負載來重新註冊機器
這是一個複雜的程序, 且不在本範例的範圍內。
在第三個部署中 (Kubernetes), 這個程序簡單多了
在你的第一個 Cloud Shell 視窗, 執行以下指令:
kubectl scale --replicas 3 deployment/prime-server |
測試進度
點擊 Check my progress 來確認目前的進度。如果你成功地擴充了你的部署, 你將獲得一個評價分數。
等待 30 秒鐘讓 replicas 初始化, 重新執行以下負載測試:
ab -c 120 -t 60 http://<IP_ADDRESS>/prime/10000 |
可以注意到, Failed requests
現在是 0, 這代表針對這所有的 10,000+ 請求, server 都有成功回應。
清理
儘管 Qwiklabs 將會清理所有在本教程中提供的資源, 不過也可以學學如何清理你的環境
在第一個 Cloud Shell 執行以下指令:
make teardown |
這將執行 terraform destroy
, 它會刪除所有本範例中建立的資源。
恭喜
你已完成本教程
留言