本教學課程說明服務開發人員如何使用 Google Cloud Observability 工具進行探索,並透過本機開發工作流程進行調查,排解 Cloud Run 服務故障問題。
這份逐步「個案研究」是疑難排解指南的輔助說明,使用部署時會導致執行階段錯誤的範例專案,您可透過疑難排解找出並修正問題。
目標
- 編寫、建構服務並部署至 Cloud Run
- 使用 Error Reporting 和 Cloud Logging 找出錯誤
- 從 Container Registry 擷取容器映像檔,進行根本原因分析
- 修正「正式環境」服務,然後改善服務,減少日後發生問題
費用
在本文件中,您會使用下列 Google Cloud計費元件:
您可以使用 Pricing Calculator,根據預測用量估算費用。
事前準備
- 登入 Google Cloud 帳戶。如果您未曾使用過 Google Cloud,歡迎 建立帳戶,親自體驗實際使用我們產品的成效。新客戶還能獲得價值 $300 美元的免費抵免額,用於執行、測試及部署工作負載。
-
In the Google Cloud console, on the project selector page, select or create a Google 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 role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google 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 role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
- 啟用 Cloud Run Admin API
- 安裝並初始化 gcloud CLI。
- 更新元件:
gcloud components update
- 按照操作說明在本機安裝 Docker
必要的角色
如要取得完成教學課程所需的權限,請要求管理員在專案中授予您下列 IAM 角色:
- Cloud Build 編輯者 (
roles/cloudbuild.builds.editor) - Cloud Run 管理員 (
roles/run.admin) - Error Reporting 檢視者 (
roles/errorreporting.viewer) - 記錄檔檢視存取者 (
roles/logging.viewAccessor) - 專案 IAM 管理員 (
roles/resourcemanager.projectIamAdmin) - 服務帳戶使用者 (
roles/iam.serviceAccountUser) - 服務使用情形消費者 (
roles/serviceusage.serviceUsageConsumer) - 儲存空間管理員 (
roles/storage.admin)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。
設定 gcloud 預設值
如要針對 Cloud Run 服務設定 gcloud 的預設值:
設定您的預設專案:
gcloud config set project PROJECT_ID
將 PROJECT_ID 替換為您為本教學課程建立的專案名稱。
為所選區域設定 gcloud:
gcloud config set run/region REGION
將 REGION 替換為您選擇的支援 Cloud Run 區域。
Cloud Run 位置
Cloud Run 具有區域性,這表示執行 Cloud Run 服務的基礎架構位於特定區域,並由 Google 負責管理,實現該區域內所有可用區之間的備援可用性。
選擇執行 Cloud Run 服務的區域時,主要考量重點在於延遲時間、可用性或耐用性需求。原則上可以選擇距離使用者最近的區域,但也應考慮 Cloud Run 服務所用其他 Google Cloud產品的位置。如果跨多個位置使用 Google Cloud 產品,可能會影響服務的延遲時間和費用。
Cloud Run 可在下列地區使用:
採用級別 1 定價
asia-east1(臺灣)asia-northeast1(東京)asia-northeast2(大阪)asia-south1(印度孟買)asia-southeast3(曼谷)europe-north1(芬蘭)低二氧化碳排放
europe-north2(斯德哥爾摩)低二氧化碳排放
europe-southwest1(馬德里)低二氧化碳排放
europe-west1(比利時)低二氧化碳
europe-west4(荷蘭)低二氧化碳排放
europe-west8(米蘭)低二氧化碳排放
europe-west9(巴黎)低二氧化碳排放
me-west1(特拉維夫)northamerica-south1(墨西哥)us-central1(愛荷華州)低二氧化碳排放
us-east1(南卡羅來納州)us-east4(北維吉尼亞州)us-east5(哥倫布)us-south1(達拉斯)低二氧化碳排放
us-west1(奧勒岡州)低二氧化碳排放
採用級別 2 定價
africa-south1(約翰尼斯堡)asia-east2(香港)asia-northeast3(韓國首爾)asia-southeast1(新加坡)asia-southeast2(雅加達)asia-south2(印度德里)australia-southeast1(雪梨)australia-southeast2(墨爾本)europe-central2(波蘭華沙)低二氧化碳
europe-west10(柏林)europe-west12(杜林)低二氧化碳排放
europe-west2(英國倫敦)低二氧化碳排放
europe-west3(德國法蘭克福)europe-west6(瑞士蘇黎世)低二氧化碳
me-central1(杜哈)me-central2(達曼)northamerica-northeast1(蒙特婁)低二氧化碳排放
northamerica-northeast2(多倫多)低二氧化碳排放
southamerica-east1(巴西聖保羅)低二氧化碳排放
southamerica-west1(智利聖地牙哥)低二氧化碳排放
us-west2(洛杉磯)us-west3(鹽湖城)us-west4(拉斯維加斯)
如果您已建立 Cloud Run 服務,可以在Google Cloud 控制台的 Cloud Run 資訊主頁中查看區域。
正在組合程式碼
逐步建構新的 Cloud Run greeter 服務。提醒您,這項服務會刻意建立執行階段錯誤,以便進行疑難排解練習。
建立新專案:
Node.js
定義服務套件、初始依附元件和一些常見作業,建立 Node.js 專案。建立新的
hello-service目錄:mkdir hello-service cd hello-service產生
package.json檔案,建立新的 Node.js 專案:npm init --yes npm install express@4在編輯器中開啟新的
package.json檔案,並設定start指令碼來執行node index.js。完成後,檔案會如下所示:
如果您在完成本教學課程後繼續開發這項服務,請考慮填寫說明、作者和評估授權。詳情請參閱 package.json 說明文件。
Python
建立新的
hello-service目錄:mkdir hello-service cd hello-service建立 requirements.txt 檔案,並將依附元件複製到檔案中:
Go
建立新的
hello-service目錄:mkdir hello-service cd hello-service初始化新的 Go 模組,建立 Go 專案:
go mod init example.com/hello-service
您可以視需要更新特定名稱:如果程式碼發布至可透過網路存取的程式碼存放區,則應更新名稱。
Java
建立新的 Maven 專案:
mvn archetype:generate \ -DgroupId=com.example.cloudrun \ -DartifactId=hello-service \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DinteractiveMode=false將依附元件複製到
pom.xml依附元件清單 (<dependencies>元素之間):將建構設定複製到
pom.xml(<dependencies>元素下方):
建立 HTTP 服務來處理傳入要求:
Node.js
Python
Go
Java
建立
Dockerfile,定義用於部署服務的容器映像檔:Node.js
Python
Go
Java
這個範例使用 Jib,透過常見的 Java 工具建構 Docker 映像檔。Jib 可最佳化容器建構作業,不需要 Dockerfile 或安裝 Docker。進一步瞭解如何使用 Jib 建構 Java 容器。
推送程式碼
推送程式碼包含三個步驟:使用 Cloud Build 建構容器映像檔、將容器映像檔上傳至 Container Registry,以及將容器映像檔部署至 Cloud Run。
如要推送程式碼:
建構容器並發布至 Container Registry:
Node.js
gcloud builds submit --tag gcr.io/PROJECT_ID/hello-service
其中 PROJECT_ID 是您的 Google Cloud 專案 ID。您可以使用
gcloud config get-value project查看目前的專案 ID。成功後,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」訊息。映像檔會儲存在 Container Registry 中,日後如有需要,可以重複使用。
Python
gcloud builds submit --tag gcr.io/PROJECT_ID/hello-service
其中 PROJECT_ID 是您的 Google Cloud 專案 ID。您可以使用
gcloud config get-value project查看目前的專案 ID。成功後,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」訊息。映像檔會儲存在 Container Registry 中,日後如有需要,可以重複使用。
Go
gcloud builds submit --tag gcr.io/PROJECT_ID/hello-service
其中 PROJECT_ID 是您的 Google Cloud 專案 ID。您可以使用
gcloud config get-value project查看目前的專案 ID。成功後,您會看到包含 ID、建立時間和映像檔名稱的「SUCCESS」訊息。映像檔會儲存在 Container Registry 中,日後如有需要,可以重複使用。
Java
- 使用 gcloud 憑證輔助程式,授權 Docker 推送至 Container Registry。
gcloud auth configure-docker
- 使用 Jib Maven 外掛程式建構容器,並推送至 Container Registry。
mvn compile jib:build -Dimage=gcr.io/PROJECT_ID/hello-service
其中 PROJECT_ID 是您的 Google Cloud 專案 ID。您可以使用
gcloud config get-value project查看目前的專案 ID。成功後,您應該會看到「BUILD SUCCESS」訊息。映像檔會儲存在 Container Registry 中,日後如有需要,可以重複使用。
- 使用 gcloud 憑證輔助程式,授權 Docker 推送至 Container Registry。
執行下列指令來部署您的應用程式:
gcloud run deploy hello-service --image gcr.io/PROJECT_ID/hello-service
將 PROJECT_ID 替換為 Google Cloud 專案 ID。
hello-service是容器映像檔名稱,也是 Cloud Run 服務名稱。請注意,容器映像檔會部署到您先前在「設定 gcloud」中設定的服務和區域在「allow unauthenticated」提示中,回覆
y(是)。如要進一步瞭解 IAM 驗證,請參閱「管理存取權」。等待部署作業完成,這項作業約需半分鐘。部署成功後,指令列會顯示服務網址。
立即體驗
試用服務,確認已成功部署。要求應失敗,並傳回 HTTP 500 或 503 錯誤 (5xx 伺服器錯誤類別的成員)。本教學課程會逐步說明如何排解這項錯誤回應。
系統會自動為服務指派可導覽的網址。
使用網路瀏覽器前往這個網址:
開啟網路瀏覽器
找出先前部署指令輸出的服務網址。
如果部署指令未提供網址,表示發生錯誤。查看錯誤訊息並採取相應行動:如果沒有可行的指引,請參閱疑難排解指南,並視情況重試部署指令。
將這個網址複製到瀏覽器的網址列,然後按下 ENTER 鍵,即可前往該網址。
查看 HTTP 500 或 HTTP 503 錯誤。
如果收到 HTTP 403 錯誤,表示您可能在部署提示中拒絕了
allow unauthenticated invocations。如要修正這個問題,請授予服務公開存取權:gcloud run services add-iam-policy-binding hello-service \ --member="allUsers" \ --role="roles/run.invoker"
詳情請參閱「允許公開 (未經驗證) 存取」。
調查問題
假設您在「試用」中遇到的 HTTP 5xx 錯誤是實際執行階段錯誤。本教學課程將逐步說明處理這類問題的正式程序。雖然正式環境錯誤解決程序差異很大,但本教學課程會提供一系列步驟,說明如何應用實用的工具和技術。
如要調查這個問題,請按照下列階段操作:
- 收集更多有關回報錯誤的詳細資料,以便進一步調查並制定緩解策略。
- 決定要推送修正程式或復原至已知正常版本,減輕對使用者的影響。
- 重現錯誤,確認已收集正確的詳細資料,且錯誤並非一次性故障
- 對錯誤進行根本原因分析,找出造成這項錯誤的程式碼、設定或程序
調查開始時,您會取得網址、時間戳記和「內部伺服器錯誤」訊息。
收集更多詳細資料
收集更多問題相關資訊,瞭解發生什麼事,並決定後續步驟。
使用可用的 Google Cloud Observability 工具收集更多詳細資料:
使用 Error Reporting 控制台,其中提供資訊主頁,可追蹤具有可辨識堆疊追蹤的錯誤詳細資料和發生頻率。
記錄的錯誤清單。系統會依訊息將錯誤分組,並跨修訂版本、服務和平台顯示。 按一下錯誤即可查看堆疊追蹤詳細資料,請留意錯誤發生前執行的函式呼叫。
錯誤詳細資料頁面中的「堆疊追蹤範例」會顯示單一錯誤例項。您可以查看個別執行個體。 使用 Cloud Logging 查看導致問題的操作序列,包括因缺少可辨識的錯誤堆疊追蹤,而未包含在 Error Reporting 控制台中的錯誤訊息:
在第一個下拉式方塊中,依序選取「Cloud Run Revision」>「hello-service」。這樣一來,系統就會篩選記錄項目,只顯示服務產生的項目。
進一步瞭解如何在 Cloud Run 中查看記錄
復原至正常版本
如果這是已建立且已知可運作的服務,Cloud Run 上會有該服務的先前修訂版本。本教學課程使用的新服務沒有先前版本,因此無法復原。
不過,如果服務有可復原的舊版本,請按照「查看修訂版本詳細資料」一文的說明,擷取容器名稱和設定詳細資料,以便為服務建立新的工作部署作業。
重現錯誤
使用先前取得的詳細資料,確認問題在測試條件下持續發生。
再次試用,傳送相同的 HTTP 要求,看看是否會回報相同的錯誤和詳細資料。錯誤詳細資料可能需要一些時間才會顯示。
本教學課程中的範例服務為唯讀,不會觸發任何複雜的副作用,因此在實際工作環境中重現錯誤是安全的。不過,許多實際服務並非如此:您可能需要在測試環境中重現錯誤,或將這個步驟限制在本機調查。
重現錯誤可為後續工作建立背景資訊。舉例來說,如果開發人員無法重現錯誤,可能需要對服務進行額外檢測,才能進一步調查。
執行根本原因分析
根本原因分析是有效疑難排解的重要步驟,可確保您修正問題,而非只是症狀。
在本教學課程中,您先前已在 Cloud Run 重現問題,確認服務託管於 Cloud Run 時會發生問題。現在,請在本機重現問題,判斷問題是否僅限於程式碼,或只在正式版託管環境中出現。
如果您尚未在本機搭配使用 Docker CLI 與 Container Registry,請透過 gcloud 進行驗證:
gcloud auth configure-docker
如要瞭解其他方法,請參閱「Container Registry 驗證方式」。
如果無法取得最近使用的容器映像檔名稱,服務說明會提供最近部署的容器映像檔資訊:
gcloud run services describe hello-service
在
spec物件中找出容器映像檔名稱。更精確的指令可以直接擷取:gcloud run services describe hello-service \ --format="value(spec.template.spec.containers.image)"
這個指令會顯示容器映像檔名稱,例如
gcr.io/PROJECT_ID/hello-service。從 Container Registry 將容器映像檔提取至環境,這個步驟會下載容器映像檔,可能需要幾分鐘的時間:
docker pull gcr.io/PROJECT_ID/hello-service
日後更新容器映像檔時,如果重複使用這個名稱,可以使用相同指令擷取。如果略過這個步驟,本機電腦上沒有容器映像檔時,下方的
docker run指令會提取容器映像檔。在本機執行,確認問題並非 Cloud Run 獨有:
PORT=8080 && docker run --rm -e PORT=$PORT -p 9000:$PORT \ gcr.io/PROJECT_ID/hello-service
以下是上述指令的元素:
- 服務會使用
PORT環境變數,判斷要在容器內監聽的通訊埠。 run指令會啟動容器,預設為 Dockerfile 或父項容器映像檔中定義的進入點指令。--rm旗標會在容器執行個體結束時將其刪除。-e旗標會為環境變數指派值。-e PORT=$PORT會將PORT變數從本機系統傳播到具有相同變數名稱的容器。-p旗標會將容器發布為 localhost 上通訊埠 9000 的可用服務。傳送至 localhost:9000 的要求會轉送至通訊埠 8080 上的容器。這表示服務輸出的使用中通訊埠編號,與服務的存取方式不符。- 最後一個引數
gcr.io/PROJECT_ID/hello-service是容器映像檔tag,這是容器映像檔 sha256 雜湊 ID 的人類可讀標籤。如果本機沒有,docker 會嘗試從遠端登錄檔擷取映像檔。
在瀏覽器中開啟 http://localhost:9000。檢查終端機輸出內容,看看是否有與「{ops_name}」相符的錯誤訊息。
如果問題無法在本機重現,則可能是 Cloud Run 環境特有的問題。請參閱 Cloud Run 疑難排解指南,瞭解要調查的特定領域。
在本例中,錯誤是在本機重現。
- 服務會使用
現在,您已再次確認錯誤持續發生,且是由服務程式碼 (而非託管平台) 造成,接下來就要仔細檢查程式碼。
在本教學課程中,您可以放心地假設容器內的程式碼與本機系統中的程式碼相同。
重新查看錯誤報告的堆疊追蹤,並與程式碼交叉比對,找出發生錯誤的特定行。
Node.js
在index.js 檔案中,找出錯誤訊息的來源,位置大約在記錄中堆疊追蹤所指出的行號附近:
Python
在main.py 檔案中,找出錯誤訊息的來源,位置大約在記錄中堆疊追蹤所指出的行號附近:
Go
在 main.go 檔案中,找出錯誤訊息的來源,位置大約在記錄中堆疊追蹤所指出的行號附近:
Java
在 App.java 檔案中,找出錯誤訊息的來源,位置大約在記錄顯示的堆疊追蹤中指出的行號附近:
檢查這段程式碼後,如果未設定 NAME 環境變數,系統會採取下列動作:
- 錯誤會記錄到 Google Cloud Observability
- 傳送 HTTP 錯誤回應
問題是由缺少變數引起,但根本原因更具體:新增環境變數硬性依附元件的程式碼變更,未包含部署指令碼和執行階段需求文件的相關變更。
修正根本原因
現在我們已收集程式碼並找出潛在根本原因,可以採取步驟修正問題。
檢查服務是否可在本機運作,並提供
NAME環境:在本機執行容器,並加入環境變數:
PORT=8080 && docker run --rm -e PORT=$PORT -p 9000:$PORT \ -e NAME="Local World!" \ gcr.io/PROJECT_ID/hello-service
在瀏覽器中前往 http://localhost:9000
頁面上會顯示「Hello Local World!」
修改執行中的 Cloud Run 服務環境,加入以下變數:
執行服務更新指令,新增環境變數:
gcloud run services update hello-service \ --set-env-vars NAME=OverrideCloud Run 會根據先前的修訂版本建立新的修訂版本,並加入新的環境變數,請等待幾秒鐘。
確認服務已修正:
- 在瀏覽器中前往 Cloud Run 服務網址。
- 頁面上會顯示「Hello Override!」。
- 確認 Cloud Logging 或 Error Reporting 中未出現非預期的訊息或錯誤。
加快日後疑難排解的速度
在這個正式環境問題範例中,錯誤與作業設定有關。我們已修改程式碼,盡可能降低日後發生這個問題的影響。
- 改善錯誤記錄,納入更具體的詳細資料。
- 請讓服務改用安全的預設值,而非傳回錯誤。如果使用預設值會改變正常功能,請使用警告訊息進行監控。
接下來,我們將逐步移除 NAME 環境變數,不再將其視為硬性依附元件。
移除現有的
NAME處理程式碼:Node.js
Python
Go
Java
新增程式碼來設定備用值:
Node.js
Python
Go
Java
透過受影響的設定案例,在本機重新建構及執行容器,藉此測試:
Node.js
docker build --tag gcr.io/PROJECT_ID/hello-service .
Python
docker build --tag gcr.io/PROJECT_ID/hello-service .
Go
docker build --tag gcr.io/PROJECT_ID/hello-service .
Java
mvn compile jib:build
確認
NAME環境變數仍可運作:PORT=8080 && docker run --rm -e PORT=$PORT -p 9000:$PORT \ -e NAME="Robust World" \ gcr.io/PROJECT_ID/hello-service
確認服務在沒有
NAME變數的情況下運作:PORT=8080 && docker run --rm -e PORT=$PORT -p 9000:$PORT \ gcr.io/PROJECT_ID/hello-service
如果服務未傳回結果,請確認在第一個步驟中移除程式碼時,沒有移除額外的程式碼行,例如用於寫入回應的程式碼行。
請返回「部署程式碼」一節,部署這項變更。
每次部署服務都會建立新的修訂版本,並在準備就緒時自動開始提供流量。
如要清除先前設定的環境變數,請執行下列指令:
gcloud run services update hello-service --clear-env-vars
將預設值的新功能新增至服務的自動化測試涵蓋範圍。
在記錄中找出其他問題
您可能會在記錄檢視器中看到這項服務的其他問題。舉例來說,不支援的系統呼叫會在記錄中顯示為「Container Sandbox Limitation」。
舉例來說,Node.js 服務有時會產生下列記錄訊息:
Container Sandbox Limitation: Unsupported syscall statx(0xffffff9c,0x3e1ba8e86d88,0x0,0xfff,0x3e1ba8e86970,0x3e1ba8e86a90). Please, refer to https://gvisor.dev/c/linux/amd64/statx for more information.
在這種情況下,不支援這項功能並不會影響 hello-service 範例服務。
Terraform 疑難排解
如需 Terraform 相關疑難排解資訊或有任何問題,請參閱「Terraform 政策驗證疑難排解」或與 Terraform 支援團隊聯絡。
清除所用資源
為避免系統向您的 Google Cloud 帳戶收取額外費用,請刪除您在本教學課程中部署的所有資源。
刪除專案
如果您是為了這個教學課程建立新專案,請刪除專案。如果您使用現有專案,並想保留專案,但不要本教學課程新增的變更,請刪除為本教學課程建立的資源。
如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。
刪除專案的方法如下:
- 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。
- 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)。
- 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。
刪除教學課程資源
刪除您在本教學課程中部署的 Cloud Run 服務。Cloud Run 服務在收到要求前不會產生費用。
如要刪除 Cloud Run 服務,請執行下列指令:
gcloud run services delete SERVICE-NAME
將 SERVICE-NAME 改為您的服務名稱。
您也可以從Google Cloud 控制台刪除 Cloud Run 服務。
移除您在教學課程設定期間新增的
gcloud預設區域設定:gcloud config unset run/region移除專案設定:
gcloud config unset project刪除在本教學課程中建立的其他 Google Cloud 資源:
- 從 Container Registry 刪除容器映像檔
gcr.io/<var>PROJECT_ID</var>/hello-service。
- 從 Container Registry 刪除容器映像檔
後續步驟
- 進一步瞭解如何使用 Cloud Logging 和 Error Reporting,深入分析正式環境行為。
- 如要進一步瞭解 Cloud Run 疑難排解,請參閱疑難排解指南。
- 查看 Google Cloud 的參考架構、圖表和最佳做法。歡迎瀏覽 Cloud Architecture Center。