1. 簡介
上次更新時間:2024 年 11 月 1 日
如何將舊的 PHP 應用程式翻新至 Google Cloud?
(📽?️ 觀看 7 分鐘的程式碼研究室入門影片 )
通常,在內部執行的舊版應用程式都需要進行現代化。這表示這些應用程式可在不同環境中部署,且具備可擴充性和安全性。
在本工作坊中,您將:
- 將 PHP 應用程式容器化。
- 遷移至代管的 資料庫服務 ( Cloud SQL)。
- 部署至 Cloud Run (這是 GKE/Kubernetes 的零運算替代方案)。
- 使用 Identity and Access Management (IAM) 和 Secret Manager 保護應用程式。
- 透過 Cloud Build 定義 CI/CD 管道。Cloud Build 可連結至託管在熱門 Git 供應商 (例如 GitHub 或 GitLab) 的 Git 存放區,並在任何推送至主分支時觸發。
- 將應用程式相片代管在 Cloud Storage 中。這項功能是透過掛載完成,無須使用程式碼即可變更應用程式。
- 透過 Gemini 引入生成式 AI 功能,並透過 Cloud Functions (無伺服器) 進行調度。
- 熟悉SLOs,並操作您新刷新的應用程式。
只要按照這些步驟操作,就能逐步翻新 PHP 應用程式,提升其可擴充性、安全性和部署彈性。此外,您還可以透過遷移至 Google Cloud,運用其強大的基礎架構和服務,確保應用程式在雲端原生環境中順利執行。
我們相信,您在執行這些簡單步驟時所學到的知識,可以應用於自己的應用程式和機構,並支援不同的語言/堆疊和用途。
關於應用程式
您要分支的應用程式 ( 程式碼,受 MIT 授權約束) 是具備 MySQL 驗證功能的基本 PHP 5.7 應用程式。應用程式的主要概念是提供一個平台,讓使用者上傳相片,管理員則可標記不當圖片。應用程式有兩個資料表:
- 使用者。已預先編譯並提供給管理員。新使用者可以註冊。
- 圖片:附帶幾張範例圖片。登入的使用者可以上傳新相片。我們會在此施展一些魔法。
您的目標
我們希望翻新舊應用程式,以便在 Google Cloud 中使用。我們將運用其工具和服務來改善可擴充性、強化安全性、自動化基礎架構管理,並整合圖像處理、監控和資料儲存等進階功能,使用 Cloud SQL、Cloud Run、Cloud Build、Secret Manager 等服務。
更重要的是,我們希望逐步進行,讓您學習每個步驟背後的思考過程,而且通常每個步驟都會為後續步驟開啟新的可能性 (例如:模組 2 -> 3,以及 6 -> 7)。
還不相信嗎?請在 YouTube 上查看這部 7 分鐘的影片。
軟硬體需求
- 裝有瀏覽器並連上網際網路的電腦。
- 部分 GCP 抵免額。請向當地的 Google 愛好者詢問 ;)
gcloud
指令運作正常。- 您是否在本地工作?請按這裡下載。您也需要一些不錯的編輯器 (例如 vscode 或 intellij)。
- 想在「雲端」中完成所有工作嗎?屆時您可以使用 Cloud Shell。
- GitHub 使用者。您需要這項工具,才能使用自己的 Git 存放區分支原始程式碼 🧑?🏻?💻? gdgpescara/app-mod-workshop。您必須擁有自己的 CI/CD 管道 (自動提交 -> 建構 -> 部署)
如需解決方案範例,請參閱:
- 作者存放區:https://github.com/Friends-of-Ricc/app-mod-workshop
- 每個章節的
.solutions/
資料夾下,原始工作坊存放區。
您可以透過本機電腦使用這門工作坊,也可以完全在瀏覽器上完成。
2. 設定功勞和分支
兌換 GCP 抵免額並設定 GCP 環境 (選用)
如要參加這項工作坊,您需要擁有結算帳戶並有一定金額的信用額度。如果您已自行設定結帳資訊,可以略過這個步驟。
建立全新的 Google Gmail 帳戶 (*),以便連結 GCP 信貸。請向老師索取 GCP 抵免額兌換連結,或使用這裡的抵免額:bit.ly/PHP-Amarcord-credits。
使用新建立的帳戶登入,然後按照操作說明操作。
(
) 為什麼我需要全新的 Gmail 帳戶?*
我們發現有些人無法完成程式碼研究室,因為他們的帳戶 (尤其是工作或學生電子郵件) 曾接觸 GCP,且有 機構政策 限制他們的操作權限。建議您建立新的 Gmail 帳戶,或使用未曾與 GCP 連結的現有 Gmail 帳戶 (gmail.com)。
點選按鈕即可兌換優待。
請在下列表單中填入您的姓名和姓氏,並同意條款及細則。
您可能需要等待幾秒,帳單帳戶才會顯示在以下位置:https://console.cloud.google.com/billing
完成後,請開啟 Google Cloud 控制台,然後按一下左上方下拉式選單中的「Project Selector」,建立新專案,其中會顯示「No organization」。詳情請見下方
如果您還沒有專案,請建立新專案,如下方螢幕截圖所示。右上角有「NEW PROJECT」選項。
請務必將新專案連結至 GCP 試用帳單帳戶,步驟如下:
您現在可以開始使用 Google Cloud Platform。如果您是初學者,或是只想在 Cloud 環境中執行所有操作,可以透過左上角的按鈕存取 Cloud Shell 和編輯器,如下圖所示。
確認已選取左上方的新專案:
未選取 (不良):
已選取 (良好):
從 GitHub 分支應用程式
- 前往試用版應用程式:https://github.com/gdgpescara/app-mod-workshop
- 按一下「分支」圖示 🍴?。
- 如果您沒有 GitHub 帳戶,請建立一個。
- 您可以隨意編輯內容。
- 使用以下指令複製應用程式程式碼:
git clone
https://github.com/
YOUR-GITHUB-USER/YOUR-REPO-NAME
- 使用您偏好的編輯器開啟複製的專案資料夾。如果您選擇使用 Cloud Shell,請按一下「Open Editor」(開啟編輯器),如以下所示。
您可以使用 Google Cloud Shell 編輯器執行所有操作,如以下圖片所示
如要確認這項設定,請按一下「Open Folder」(開啟資料夾),然後選取資料夾,例如主資料夾中的 app-mod-workshop
。
3. 單元 1:建立 SQL 執行個體
建立 Google Cloud SQL 執行個體
我們的 PHP 應用程式會連線至 MySQL 資料庫,因此我們需要將資料庫複製到 Google Cloud,以便輕鬆遷移。Cloud SQL 可讓您在雲端中執行全代管 MySQL 資料庫,是您理想的選擇。步驟如下:
- 前往 Cloud SQL 頁面:https://console.cloud.google.com/sql/instances
- 按一下「建立執行個體」
- 啟用 API (如有需要)。這可能需要幾秒鐘的時間。
- 選擇 MySQL。
- (我們會盡量為你提供最便宜的版本,以延長使用壽命):
- 版本:Enterprise
- 預設值:development (我們嘗試使用沙箱,但無法正常運作)
- Mysql 版本:5.7 (哇,這真是回憶殺啊!)
- 執行個體 ID:選擇
appmod-phpapp
(如果變更這個值,請記得也要相應變更日後的指令碼和解決方案)。 - 密碼:請輸入任何你想要的字串,但請記下為 CLOUDSQL_INSTANCE_PASSWORD
- 區域:請與應用程式其他部分選擇的區域相同 (例如,米蘭 =
europe-west8
) - 可用區可用性:單一可用區 (我們要節省示範的費用)
按一下「Create Instance」(建立執行個體) 按鈕,即可部署 Cloud SQL 資料庫;⌛這項作業大約需要 10 分鐘才能完成⌛。在此同時,請繼續閱讀文件;您也可以開始解決下一個模組 (「將 PHP 應用程式容器化」),因為它與第一部分的這個模組沒有任何依附元件 (直到您修正資料庫連線為止)。
注意:這個執行個體的費用約為 $7 美元/天。請務必在工作坊結束後關閉。
在 Cloud SQL 中建立 image_catalog 資料庫和使用者
應用程式專案隨附 db/
資料夾,其中包含兩個 SQL 檔案:
- 01_schema.sql:包含 SQL 程式碼,可建立兩個包含使用者和圖片資料的表格。
- 02_seed.sql:包含 SQL 程式碼,可將資料填入先前建立的資料表。
這些檔案會在稍後建立 image_catalog
資料庫時使用。如要執行這項操作,請按照下列步驟操作:
- 開啟執行個體,然後按一下「資料庫」分頁:
- 按一下「建立資料庫」
- 將其稱為
image_catalog
(如 PHP 應用程式設定中所示)。
接著,我們會建立資料庫使用者。這樣我們就能驗證是否有權存取 image_catalog 資料庫。
- 接著按一下「使用者」分頁標籤
- 按一下「新增使用者帳戶」。
- 使用者:我們來建立一個:
- 使用者名稱:
appmod-phpapp-user
- 密碼:選擇好記的密碼,或點選「產生」
- 保留「允許任何主機 (%)」設定。
- 按一下「新增」。
將資料庫開放給已知的 IP。
請注意,Cloud SQL 中的所有資料庫都是「隔離」的。您必須明確設定可存取的網路。
- 按一下執行個體
- 開啟「連線」選單
- 按一下「網路」分頁標籤。
- 按一下「已授權的網路」下方的連結。接著新增網路 (也就是子網路)。
- 我們先選擇快速但不安全的設定,讓應用程式運作。您之後可以將 IP 限制為您信任的 IP:
- 名稱:「Everyone in the world - INSECURE」
- 網路:"
0.0.0.0/0"
" (注意:這是不安全的部分!) - 按一下「完成」
- 按一下 [Save] (儲存)。
畫面應如下所示:
注意:這個解決方案是完成工作坊的理想折衷,可在 O(小時) 內完成。不過,請參閱「安全性」文件,瞭解如何保護實際工作環境的解決方案!
現在是測試資料庫連線的時候了!
我們來看看先前建立的 image_catalog
使用者是否有效。
在執行個體中存取「Cloud SQL Studio」,然後輸入要驗證的資料庫、使用者和密碼,如下所示:
進入後,您可以開啟 SQL 編輯器,然後繼續閱讀下一節。
從程式碼集匯入資料庫
使用 SQL 編輯器匯入 image_catalog
資料表及其資料。請從存放區的檔案 ( 01_schema.sql 和 02_seed.sql) 複製 SQL 程式碼,並依序逐一執行。
完成後,image_catalog 中應會出現兩個資料表,分別是 users 和 images,如下所示:
如要測試,請在編輯器中執行下列指令:select * from images;
另外,請務必記下 Cloud SQL 執行個體的公開 IP 位址,後續步驟會用到。如要取得 IP,請前往「總覽」頁面下方的 Cloud SQL 執行個體主頁面。(總覽 > 連線至這個執行個體 > 公開 IP 位址)。
4. 模組 2:將 PHP 應用程式容器化
我們想為雲端建構這個應用程式。
也就是說,您需要將程式碼打包成某種 ZIP 檔案,其中包含在雲端執行程式碼所需的所有資訊。
您可以透過以下幾種方式封裝:
- Docker。非常熱門,但設定方式相當複雜。
- Buildpack。較不常使用,但會「自動判斷」要建構和執行哪些項目。通常都能正常運作!
在本講習課程的範疇中,我們假設您使用 Docker。
如果您選擇使用 Cloud Shell,請重新開啟 (按一下雲端控制台右上方)。
這應該會在頁面底部開啟方便使用的 Shell,您應該已在設定步驟中分支程式碼。
Docker
如果您想自行掌控,這就是適合您的解決方案。當您需要設定特定程式庫,並注入特定不明顯的行為 (上傳內容中的 chmod、應用程式中的非標準可執行檔等) 時,這就很有用。
由於我們最終希望將容器化應用程式部署至 Cloud Run,請參閱以下說明文件。如何將其從 PHP 8 回移至 PHP 5.7?或許你可以使用 Gemini 來處理這類問題。或者,您也可以使用這個預先處理版本:
最新的 Dockerfile
版本可在這裡取得。
為了在本機測試應用程式,我們需要變更 config.php 檔案,讓 PHP 應用程式連結至 Google CloudSQL 上的 MYSQL 資料庫。根據您先前設定的內容,填入空格:
<?php
// Database configuration
$db_host = '____________';
$db_name = '____________';
$db_user = '____________';
$db_pass = '____________';
try {
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Errore di connessione: " . $e->getMessage());
}
session_start();
?>
DB_HOST
是 Cloud SQL 公開 IP 位址,您可以在 SQL 主控台中找到這個位址:
DB_NAME
應保持不變:image_catalog
DB_USER
應為appmod-phpapp-user
DB_PASS
是您選擇的項目。請使用單引號設定,並視需要加上轉義字元。
此外,你也可以使用 Gemini 將少數 🇮?🇹? 義大利文作品翻譯成英文!
好,現在您已取得 Dockerfile
,並設定 PHP 應用程式連線至資料庫,讓我們試試看吧!
如果您尚未安裝 Docker,請先安裝 ( 連結)。如果您使用 Cloud Shell,則不需要這項工具 (這真是太棒了)。
接著,請嘗試使用適當的 Docker 建構和執行指令,建構及執行容器化 PHP 應用程式。
# Build command - don't forget the final . This works if Dockerfile is inside the code folder:
$ docker build -t my-php-app-docker .
# Local Run command: most likely ports will be 8080:8080
$ docker run -it -p <CONTAINER_PORT>:<LOCAL_MACHINE_PORT> my-php-app-docker
如果一切正常運作,連線至本機主機後,您應該會看到以下網頁!應用程式現在會在通訊埠 8080 上執行,請按一下「網頁預覽」圖示 (瀏覽器上有眼睛圖示),然後點選「透過以下通訊埠預覽:8080」 (或「變更通訊埠」以使用其他通訊埠)
在瀏覽器中測試結果
應用程式現在應如下所示:
如果您使用 Admin/admin123 登入,應該會看到類似以下的畫面。
太好了!除了義大利文之外,其他都正常運作!🎉🎉🎉
如果 Docker 化作業正常,但資料庫憑證錯誤,您可能會看到類似以下的訊息:
再試一次,你已經很接近了!
儲存至 Artifact Registry (選用)
到目前為止,您應該已準備好容器化 PHP 應用程式,可部署至雲端。接下來,我們需要在雲端中儲存 Docker 映像檔,並讓該映像檔可供部署至 Cloud Run 等 Google Cloud 服務。這個儲存空間解決方案稱為 Artifact Registry,是專為儲存應用程式構件 (包括 Docker 容器映像檔、Maven 套件、npm 模組等) 而設計的全代管 Google Cloud 服務。
請使用適當的按鈕,在 Google Cloud Artifact Registry 中建立存放區。
選擇有效的名稱、格式和適合儲存構件的位置。
返回本機開發環境標記,並將應用程式容器映像檔推送至剛建立的 Artifact Registry 存放區。請執行下列指令來完成這項操作。
- docker tag 來源映像檔 [:TAG] 目標映像檔 [:TAG]
- docker push TARGET_IMAGE[:TAG]
結果應如下圖所示。
萬歲!🎉?🎉?🎉?您可以晉升到下一級。在此之前,請花 2 分鐘嘗試上傳/登入/登出,並熟悉應用程式端點。您稍後會用到這些資訊。
可能發生的錯誤
如果發生容器化錯誤,請嘗試使用 Gemini 說明並修正錯誤,並提供以下資訊:
- 目前的 Dockerfile
- 收到的錯誤
- [如有需要] 要執行的 PHP 程式碼。
上傳權限。請嘗試使用 /upload.php
端點,並嘗試上傳相片。您可能會收到下列錯誤訊息。如果是這樣,您需要在 Dockerfile
中進行一些 chmod/chown
修正。
警告:move_uploaded_file(uploads/image (3).png):無法開啟串流:/var/www/html/upload.php 中的行 11 拒絕權限
PDOException「找不到驅動程式」 (或「Errore di connessione: 找不到驅動程式」)。請確認 Dockerfile 有適當的 MySQL (pdo_mysql
) PDO 程式庫,以便連線至資料庫。請參閱這個頁面的解決方案,尋找靈感。
無法將要求轉送至後端。無法連線至通訊埠 8080 的伺服器。這表示您可能公開了錯誤的連接埠。請確認您公開的端口是 Apache/Nginx 實際提供服務的端口。這並非小事。盡可能將該連接埠設為 8080 (可讓 Cloud Run 更容易運作)。如果您想保留 80 通訊埠 (例如,因為 Apache 需要這樣做),請使用其他指令執行:
$ docker run -it -p 8080:80 # force 80
# Use the PORT environment variable in Apache configuration files.
# https://cloud.google.com/run/docs/reference/container-contract#port
RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf
5. 單元 3:將應用程式部署至 Cloud Run
為何選用 Cloud Run?
這是個好問題!幾年前,您肯定會選擇 Google App Engine。
簡單來說,Cloud Run 目前採用較新的技術堆疊,因此部署作業更容易、成本更低,且在未使用時可調降至 0。由於可靈活執行任何無狀態容器,並可與各種 Google Cloud 服務整合,因此非常適合用於部署微服務和現代化應用程式,可降低額外負擔並提高效率。
具體來說,Cloud Run 是 Google Cloud 提供的全代管平台,可讓您在無伺服器環境中執行無狀態容器化應用程式。這項服務會自動處理所有基礎架構,從零開始擴充,以符合入站流量需求,並在閒置時縮減,因此可節省成本且提高效率。Cloud Run 支援任何語言或程式庫,只要是封裝在容器中即可,可提供極高的開發彈性。這項服務可與其他 Google Cloud 服務完美整合,適合用於建構微服務、API、網站和事件驅動應用程式,且無需管理伺服器基礎架構。
必要條件
如要完成這項工作,您必須在本機電腦中安裝 gcloud
。如未顯示,請參閱這裡的操作說明。不過,如果您使用的是 Google Cloud Shell,則不必採取任何行動。
部署前...
如果您在本機環境中工作,請使用下列指令向 Google Cloud 進行驗證
$ gcloud auth login –update-adc # not needed in Cloud Shell
這應該會透過瀏覽器上的 OAuth 登入程序驗證您的身分。請確認您透過 Chrome 登入的使用者 (例如 vattelapesca@gmail.com) 與已啟用 Google Cloud 付款功能的使用者相同。
使用下列指令啟用 Cloud Run API:
$ gcloud services enable run.googleapis.com cloudbuild.googleapis.com
到目前為止,一切都已準備就緒,可以部署至 Cloud Run。
透過 gcloud 將應用程式部署至 Cloud Run
您可以使用 gcloud run deploy
指令,在 Cloud Run 上部署應用程式。您可以設定多種選項來達成目標。以下是最低選項集合 (可透過指令列提供,或由工具透過互動式提示詢問):
- 您要為應用程式部署的 Cloud Run 服務名稱。Cloud Run 服務會傳回一個網址,為應用程式提供端點。
- 應用程式執行的 Google Cloud 區域。(
--region
REGION) - 包裝應用程式的容器映像檔。
- 應用程式在執行期間需要使用的環境變數。
- Allow-Unauthenticated 旗標:允許所有使用者在未經進一步驗證的情況下存取您的應用程式。
請參閱說明文件 (或向下捲動查看可能的解決方案),瞭解如何將此選項套用至指令列。
部署作業需要幾分鐘才能完成。如果一切正確無誤,Google Cloud 控制台應會顯示類似以下的畫面。
按一下 Cloud Run 提供的網址,並測試應用程式。驗證完成後,畫面應會顯示類似下方的畫面。
不含引數的「gcloud run deploy」
您可能已經注意到,gcloud run deploy
會問對問題,並填入您留下的空白。真是太棒了!
不過,在某些模組中,我們會將這項指令新增至 Cloud Build 觸發事件,因此無法提供互動式問題。我們需要填入指令中的每個選項。所以你想製作金色 gcloud run deploy --option1 blah --foo bar --region your-fav-region
。該如何進行?
- 重複執行步驟 2-3-4,直到 gcloud 停止詢問問題:
- [LOOP]
gcloud run deploy
與目前找到的選項 - [LOOP] 系統要求選項 X
- [LOOP] 在公開文件中搜尋如何透過 CLI 新增選項
--my-option [my-value]
來設定 X。 - 除非 gcloud 完成執行,且沒有其他問題,否則請返回步驟 2。
- 這個 gcloud run deploy BLAH BLAH BLAH 很棒!請將指令儲存在某處,後續在 Cloud Build 步驟中會用到!
太棒了 🎉?🎉?🎉?您已成功在 Google Cloud 中部署應用程式,完成了翻新計畫的第一步。
6. 單元 4:使用 Secret Manager 清除密碼
在前一個步驟中,我們已成功在 Cloud Run 中部署及執行應用程式。不過,我們採用了一種安全性不良做法:以明文提供部分機密資訊。
第一個版本:更新 config.php 以使用 ENV
您可能已經注意到,我們直接將資料庫密碼放入 config.php 檔案中的程式碼。這麼做沒問題,您可以用於測試,並確認應用程式是否正常運作。但您無法在正式環境中提交/使用這類程式碼。密碼 (以及其他資料庫連線參數) 應以動態方式讀取,並在執行階段提供給應用程式。變更 config.php 檔案,讓檔案從 ENV 變數讀取資料庫參數。如果失敗,建議您考慮設定預設值。這在您無法載入 ENV 時很有幫助,因為網頁輸出內容會告訴您是否使用預設值。填入空白,並替換 config.php 中的程式碼。
<?php
// Database configuration with ENV variables. Set default values as well
$db_host = getenv('DB_HOST') ?: 'localhost';
$db_name = getenv('DB_NAME') ?: 'image_catalog';
$db_user = getenv('DB_USER') ?: 'appmod-phpapp-user';
$db_pass = getenv('DB_PASS') ?: 'wrong_password';
// Note getenv() is PHP 5.3 compatible
try {
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Errore di connessione: " . $e->getMessage());
}
session_start();
?>
由於應用程式已完成容器化,您需要提供一種方法,將 ENV 變數提供給應用程式。這可以透過幾種方式完成:
- 在建構時,在 Dockerfile 上。使用 ENV DB_VAR=ENV_VAR_VALUE 語法,在先前的 Dockerfile 中新增 4 個參數。這會設定預設值,可在執行階段覆寫。舉例來說,您可以在這裡設定「DB_NAME」和「DB_USER」,但不能在其他地方設定。
- 在執行時。您可以透過 CLI 或 UI 設定 Cloud Run 的這些變數。這是放置所有 4 個變數的正確位置 (除非您想保留 Dockerfile 中的預設值)。
在 localhost 中,您可能會將 ENV 變數放在 .env
檔案中 (請查看 solutions 資料夾)。
另外,請確認 .env 已新增至 .gitignore
:您不應將機密資料推送至 GitHub!
echo .env >> .gitignore
完成後,您可以在本機測試執行個體:
docker run -it -p 8080:8080 --env-file .env my-php-app-docker
您現在已完成以下操作:
- 應用程式會動態讀取 ENV 中的變數
- 您已從程式碼中移除資料庫密碼,因此安全性已提升)
您現在可以將新的修訂版本部署至 Cloud Run。讓我們直接進入使用者介面,手動設定環境變數:
- 前往 https://console.cloud.google.com/run
- 按一下應用程式
- 按一下「編輯及部署新的修訂版本」
- 在第一個「容器」分頁中,按一下下方的「變數與密鑰」分頁
- 按一下「+ 新增變數」,然後新增所有必要的變數。最終畫面應如下所示:
這樣就沒問題了嗎?否。大部分的作業系統仍可看到你的 PASS。您可以使用 Google Cloud Secret Manager 減輕這類風險。
第二次迭代:Secret Manager
您的密碼已從自己的程式碼中移除:勝利!等等,我們安全了嗎?
凡是可以存取 Google Cloud 控制台的使用者,仍可查看您的密碼。事實上,只要您存取 Cloud Run YAML 部署檔案,就能擷取該檔案。或者,如果您嘗試編輯或部署新的 Cloud Run 修訂版本,密碼會顯示在「變數與機密資料」部分,如以下螢幕截圖所示。
Google Cloud Secret Manager 是安全的集中式服務,可用於管理機密資訊,例如 API 金鑰、密碼、憑證和其他機密資訊。
您可以使用精細的權限和強大的加密功能,儲存、管理及存取密鑰。透過與 Google Cloud 的 Identity and Access Management (IAM) 整合,Secret Manager 可讓您控管哪些使用者可以存取特定機密金鑰,確保資料安全和法規遵循。
它也支援自動機密金鑰輪替和版本管理功能,可簡化機密金鑰生命週期管理,並強化 Google Cloud 服務中應用程式的安全性。
如要存取 Secret Manager,請從漢堡選單前往「安全性」服務,然後在「資料保護」專區下方找到該服務,如以下螢幕截圖所示。
請按照下圖所示,在該頁面中啟用 Secret Manager API。
- 接著按一下「Create a secret」:請理性地命名:
- 名稱:
php-amarcord-db-pass
- 密鑰值:你的資料庫密碼 (請忽略「上傳檔案」部分)。
- 註解這個密鑰連結,應該會像
projects/123456789012/secrets/php-amarcord-db-pass
這是指向機密金鑰的專屬指標 (適用於 Terraform、Cloud Run 和其他服務)。這個號碼是專屬專案編號。
提示:請盡量使用一致的命名慣例命名機密,並從左到右進行專屬命名,例如:cloud-devrel-phpamarcord-dbpass
- 機構 (包含公司)
- 團隊 (機構內)
- 申請 (團隊內)
- 變數名稱 (在應用程式中)
這樣一來,您就能輕鬆使用規則運算式,找出單一應用程式的所有機密資料。
建立新的 Cloud Run 修訂版本
有了新的 Secret 後,我們需要移除 DB_PASS ENV 變數,並用新的 Secret 取代。舉例來說:
- 使用 Google Cloud 控制台存取 Cloud Run
- 選擇應用程式。
- 按一下「Edit & Deploy a New Revision」(編輯及部署新的修訂版本)
- 找到「變數與密鑰」分頁。
- 使用「+ 參照機密金鑰」按鈕重設 DB_PASS ENV 變數。
- 請為參照的密鑰使用相同的「DB_PASS」,並使用最新版本。
完成後,您應該會收到以下錯誤訊息
嘗試瞭解如何修正問題。如要解決這個問題,您必須前往「IAM 與管理員」專區,變更授予的權限。祝您偵錯愉快!
找出問題後,請返回 Cloud Run 並重新部署新修訂版本。結果應如下圖所示:
提示:開發人員控制台 (UI) 可指出權限問題。請花點時間瀏覽雲端實體的所有連結!
7. 單元 5:使用 Cloud Build 設定 CI/CD
為何要使用 CI/CD 管道?
到目前為止,您應該已經輸入 gcloud run deploy
幾次,也許還反覆回答同一個問題。
您是否厭倦了使用 gcloud run deploy 手動部署應用程式?如果每次將新的變更內容推送至 Git 存放區時,應用程式就能自動部署,那該有多好!
如要使用 CI/CD 管道,您需要具備下列兩項條件:
- 個人 Git 存放區:幸運的是,您應該已在步驟 2 中將工作坊存放區分支至 GitHub 帳戶。如果沒有,請返回並完成該步驟。分支的存放區應如下所示:
https://github.com/<YOUR_GITHUB_USER>/app-mod-workshop
- Cloud Build。這項服務價格實惠,且功能強大,價格實惠,可讓您為幾乎所有項目設定建構自動化作業,包括 Terraform、Docker 應用程式等。
本節將著重說明如何設定 Cloud Build。
歡迎使用 Cloud Build!
我們將使用 Cloud Build 執行以下操作:
- 使用 Dockerfile 建構來源。您可以將這個檔案視為「大型 .zip 檔案」,其中包含建構及執行這個檔案所需的所有內容 (也就是「建構成果物」)。
- 將這個構件推送至 Artifact Registry (AR)。
- 然後針對應用程式「php-amarcord」發出從 AR 到 Cloud Run 的部署作業
- 這麼做會建立現有應用程式的新版本 (「修訂版」) (請想像一個含有新程式碼的層),如果推送成功,我們會將其設為將流量轉送至新版本。
以下是 php-amarcord
應用程式的一些版本範例:
我們如何做到這一切?
- 製作一個完美的 YAML 檔案:
cloudbuild.yaml
- 建立 Cloud Build 觸發條件。
- 透過 Cloud Build UI 連結至 GitHub 存放區。
建立觸發條件 (以及連結存放區)
- 前往 https://console.cloud.google.com/cloud-build/triggers
- 按一下「建立觸發條件」。
- 編譯:
- 名稱:
on-git-commit-build-php-app
之類有意義的名稱 - 事件:推送至分支版本
- 來源:「Connect new repository」
- 系統會在右側開啟「連結存放區」視窗
- 來源供應者:「GitHub」(第一個)
- 「Continue」
- 驗證功能會在 GitHub 上開啟視窗,進行交叉驗證。請耐心等候,如果您有許多儲存庫,可能需要一段時間才能完成。
- 「Select repo」:選取帳戶/repo,並勾選「I understand...」部分。
- 如果您收到錯誤:您的所有存放區均未安裝 GitHub 應用程式,請按一下「Install Google Cloud Build」(安裝 Google Cloud Build),然後按照操作說明操作。
按一下「連線」
- 沒錯!您的存放區現已連結。
- 回到「觸發條件」部分。
- 設定:自動偵測 (*)
- 進階:選取服務帳戶「[PROJECT_NUMBER]-compute@developer.gserviceaccount.com」
- xxxxx 是您的專案 ID
- 預設運算服務帳戶適合實驗室方法,請勿在實際工作環境中使用!( 瞭解詳情)。
- 將其他所有設定保留原樣。
- 按一下「建立」按鈕。
(*) 這是最簡單的方法,因為它會檢查 Dockerfile 或 cloudbuild.yaml。不過,cloudbuild.yaml
可讓您決定在哪個步驟執行哪些操作。
我有力量了!
除非您將 Cloud Build 服務帳戶 (服務帳戶是什麼?代表您執行任務的「機器人」電子郵件地址,在本例中是指在雲端建構內容。
除非您授權,否則 SA 無法建構及部署。所幸這很簡單!
- 依序前往「Cloud Build」>「設定」。
- 「[PROJECT_NUMBER]-compute@developer.gserviceaccount.com」服務帳戶
- 勾選下列方塊:
- Cloud Run
- Secret Manager
- 服務帳戶
- Cloud Build
- 並勾選「設為偏好的服務帳戶」
Cloud Build YAML 檔案在哪裡?
我們強烈建議您花點時間自行建立 Cloud Build YAML。
不過,如果您沒有時間或不想花時間,可以前往這個解決方案資料夾尋找靈感:.solutions
您現在可以將變更推送至 GitHub,並觀察 Cloud Build 的部分。
設定 Cloud Build 可能會有些複雜。請注意,我們可能會進行多次來回確認:
- 在 https://console.cloud.google.com/cloud-build/builds;region=global 中查看記錄
- 找出錯誤。
- 修正程式碼,並重新發出 Git 提交 / Git 推送。
- 有時錯誤並非出在程式碼中,而是出在某些設定中。在這種情況下,您可以透過 UI 發布新的版本 (依序點選「Cloud Build」>「Triggers」>「Run」)
請注意,如果您使用這個解決方案,仍須完成一些工作。舉例來說,您需要為新建立的開發/生產端點設定 ENV 變數:
您可以透過兩種方法來選擇刊登位置:
- 透過 UI - 再次設定 ENV 變數
- 透過 CLI 為您編寫「完美」的腳本。如需範例,請參閱 gcloud-run-deploy.sh。您需要調整一些項目,例如端點和專案編號。您可以在 Cloud 總覽中找到專案編號。
如何將程式碼提交至 GitHub?
本講習課程不涵蓋將 git push
提交至 GitHub 的最佳方法。不過,如果您在 Cloud Shell 中遇到問題,可以透過以下兩種方式解決:
- CLI。在本機新增 SSH 金鑰,並使用 git@github.com:YOUR_USER/app-mod-workshop.git (而非 http) 新增遠端存放區
- VSCode。如果您使用 Cloud Shell 編輯器,可以使用「來源控制項」(ctrl-shift-G) 分頁,按一下「同步處理變更」,然後按照操作說明操作。您應該可以將 GitHub 帳戶驗證至 VS Code,從那裡進行提取/推送作業也變得輕鬆簡單。
請記得在其他檔案中 git add clodubuild.yaml
,否則無法運作。
深層與淺層「開發/產品相容性」[選填]
如果您從這裡複製模型版本,就會擁有兩個相同的 DEV 和 PROD 版本。這很棒,而且符合「The Twelve-Factor App」的規則 10。
不過,我們使用兩個不同的網頁端點,讓應用程式指向相同的資料庫。這對於工作坊來說已經足夠,但在實際情況下,您需要花點時間建立適當的正式版環境。這表示您需要兩個資料庫 (一個用於開發,另一個用於實際作業),並選擇災難復原 / 高可用性的資料庫位置。這超出本工作坊的範疇,但值得您思考。
如果您有時間製作「深度」版本,請務必記得複製所有需要的資源,例如:
- Cloud SQL 資料庫 (可能還有 SQL 執行個體)。
- GCS 值區
- Cloud Function。
- 您可以將 Gemini 1.5 Flash 用於開發中的模型 (更便宜、更快速),以及 Gemini 1.5 Pro (更強大)。
一般來說,每次對應用程式進行操作時,請務必仔細思考:實際工作環境是否應採用相同的值?如果沒有,請複製你的努力。當然,使用 Terraform 這麼做會簡單許多,您可以將環境 (-dev、-prod) 做為資源的後置字串插入。
8. 單元 6:遷移至 Google Cloud Storage
儲存空間
目前應用程式會將狀態儲存在 Docker 容器中。如果機器發生故障、應用程式發生異常,或是您只是推送新的修訂版本,系統就會排定新的修訂版本,並使用新的空白儲存空間:
修正方法有許多種。
- 將圖片儲存在資料庫中。我先前在 PHP 應用程式中採用了這種做法,這是最簡單的解決方案,因為不會增加複雜性。但這麼做肯定會增加資料庫的延遲和負載!
- 將 Cloud Run 應用程式遷移至儲存空間友善的解決方案:GCE + 永久磁碟?或許是 GKE 和儲存空間?注意:控制越多,靈活性就越低。
- 移至 GCS。Google Cloud Storage 為整個 Google Cloud 提供同級最佳的儲存空間,也是最符合雲端語法的解決方案。不過,這需要我們使用 PHP 程式庫。我們是否有 適用於 GCS 的 PHP 5.7 程式庫?
PHP 5.7
是否支援Composer
(Composer 支援的PHP 最早版本為 5.3.2)? - 或許可以使用 docker sidecar?
- 或者,您也可以使用 GCS Cloud Run 掛載磁碟區。聽起來很棒。
🤔? 遷移儲存空間 (開放式)
[開放式] 在本練習中,我們希望您能找到解決方案,以某種方式移動圖片,並保留圖片。
驗收測試
我不想告訴你解決方案,但我希望發生以下情況:
- 您上傳
newpic.jpg
。您可以在應用程式中查看。 - 將應用程式升級至新版本。
newpic.jpg
仍在其中,可供查看。
💡? 可能的解決方案 (GCS Cloud Run 掛載磁碟空間)
這是非常優雅的解決方案,可讓我們在不觸及程式碼的情況下,執行有狀態的檔案上傳作業 (除了顯示圖片說明,但這項操作很簡單,只是為了讓畫面看起來更美觀)。
這樣一來,您就能將 Cloud Run 中的資料夾掛載至 GCS,如下所示:
- 所有上傳至 GCS 的內容都會顯示在應用程式中。
- 應用程式收到的所有上傳內容都會上傳至 GCS
- 上傳至 GCS 的物件會發生神奇變化 (第 7 章)。
注意:請詳閱 FUSE 的詳細說明。如果效能有問題,這麼做是不行的。
建立 GCS 值區
GCS 是 Google Cloud 的無所不在儲存服務。這項服務經過實戰測試,所有需要儲存空間的 GCP 服務都會使用。
請注意,Cloud Shell 會將 PROJECT_ID 匯出為 GOOGLE_CLOUD_PROJECT:
$ export PROJECT_ID=$GOOGLE_CLOUD_PROJECT
#!/bin/bash
set -euo pipefail
# Your Cloud Run Service Name, eg php-amarcord-dev
SERVICE_NAME='php-amarcord-dev'
BUCKET="${PROJECT_ID}-public-images"
GS_BUCKET="gs://${BUCKET}"
# Create bucket
gsutil mb -l "$GCP_REGION" -p "$PROJECT_ID" "$GS_BUCKET/"
# Copy original pictures there - better if you add an image of YOURS before.
gsutil cp ./uploads/*.png "$GS_BUCKET/"
設定 Cloud Run 在 /uploads/ 資料夾中掛載值區
接下來,我們來看看精簡版。我們會建立磁碟區 php_uploads
,並指示 Cloud Run 在 MOUNT_PATH
(例如 /var/www/html/uploads/
) 上執行 FUSE 掛載作業:
#!/bin/bash
set -euo pipefail
# .. keep variables from previous script..
# Uploads folder within your docker container.
# Tweak it for your app code.
MOUNT_PATH='/var/www/html/uploads/'
# Inject a volume mount to your GCS bucket in the right folder.
gcloud --project "$PROJECT_ID" beta run services update "$SERVICE_NAME" \
--region $GCP_REGION \
--execution-environment gen2 \
--add-volume=name=php_uploads,type=cloud-storage,bucket="$BUCKET" \
--add-volume-mount=volume=php_uploads,mount-path="$MOUNT_PATH"
接著,針對要指向 Cloud Storage 的所有端點重複執行這個步驟。
您也可以透過 UI 達成相同的效果
- 在「磁碟區」分頁下方,建立指向值區的磁碟區掛載點,類型為「Cloud Storage 值區」,例如名稱為「php_uploads」。
- 在「容器」>「磁碟區掛接點」下方,將您剛剛建立的磁碟區掛接至應用程式要求的磁碟區點。這取決於 Dockerfile,但可能會類似
var/www/html/uploads/
。
無論如何,如果運作正常,編輯新的 Cloud Run 修訂版本時,畫面應會顯示類似下列的畫面:
接下來,請測試新應用程式是否能將一張新圖片上傳至 /upload.php
端點。
圖片應可在 GCS 上順暢流動,而無需編寫任何 PHP 程式碼:
發生什麼事了?
發生了非常神奇的事情。
舊版應用程式仍可正常運作,有了全新的現代化堆疊,應用程式中的所有圖片/圖片都能輕鬆放置於具狀態的 Cloud 值區。你現在可以盡情發揮:
- 如要每次偵測到含有「危險」或「裸露」圖片時都傳送電子郵件,您可以不修改 PHP 程式碼即可執行這項操作。
- 您是否想在每次收到圖片時,使用 Gemini 多模態模型來描述圖片,並上傳含有說明的資料庫?您可以不必修改 PHP 程式碼即可執行這項操作。你不相信我嗎?請繼續閱讀第 7 章。
我們剛剛開啟了一個巨大的商機空間。
9. 單元 7:運用 Google Gemini 強化應用程式
您現在擁有了使用 Cloudified Storage 的全新 PHP 應用程式 (例如 2024 Fiat 126
)。
你可以如何運用?
必要條件
在上一章中,我們使用了模型解決方案,在 GCS 上掛載圖片 /uploads/
,實際上將應用程式邏輯與圖片儲存空間分開。
這項練習要求您:
- 已順利完成第 6 章 (儲存空間) 的練習。
- 建立 GCS 值區來處理圖片上傳作業,使用者可在您的應用程式上傳相片,而相片會流向您的值區。
設定 Cloud 函式 (在 Python 中)
您是否曾想過如何實作事件驅動應用程式?例如:
- 發生 <event> 時 => 傳送電子郵件
- 發生 <event> 時 => 如果 <condition> 為 true,則更新資料庫。
事件可以是任何內容,包括 BigQuery 中的新記錄、GCS 中資料夾中的新物件變更,或是 Pub/Sub 佇列中等待處理的新訊息。
Google Cloud 支援多種模式來達成這項目標。最值得注意的是:
- EventArc。請參閱接收 GCS 事件的相關說明。很棒,您可以根據 if-then-else 在雲端建立 DAG 並協調動作。
- Cloud Scheduler。例如,非常適合用於雲端中的午夜 cron 工作。
- Cloud Workflows。與事件弧線類似,可讓您:
- Cloud Run functions (俗稱
lambdas
)。 - Cloud Composer:基本上是 Google 版的 Apache Airflow,也非常適合用於DAG。
在本練習中,我們將深入探討 Cloud 函式,以取得相當出色的結果。我們會提供額外的練習題。
請注意,程式碼範例位於 .solutions/
下方
設定 Cloud 函式 (🐍? python)
我們正致力於打造一項雄心勃勃的 GCF。
- 在 GCS 上建立新映像檔時。(可能是有人已在應用程式中上傳,但不限於此)
- .. 呼叫 Gemini 來描述圖片,並取得圖片的文字說明 .. (建議您檢查 MIME 類型,確保圖片不是 PDF、MP3 或文字檔案)
- .. 並更新含有此說明的資料庫。(這可能需要修補資料庫,才能將
description
欄新增至images
表格)。
修補資料庫,將 description
新增至圖片
- 開啟 Cloud SQL Studio:
- 輸入圖片資料庫的使用者和密碼
- 請插入以下 SQL,為圖片說明新增資料欄:
ALTER TABLE images ADD COLUMN description TEXT;
binggo!立即嘗試看看是否正常運作:
SELECT * FROM images;
你應該會看到新的說明欄:
編寫 Gemini f(x)
注意:這個函式實際上是使用 Gemini Code Assist 輔助功能建立。
注意:建立這個函式時,可能會發生 IAM 權限錯誤。其中一些錯誤已在下方「可能的錯誤」段落中說明。
- 啟用 API
- 前往 https://console.cloud.google.com/functions/list
- 按一下「建立函式」
- 透過 API 精靈啟用 API:
您可以透過使用者介面或指令列建立 GCF。我們會使用指令列。
您可以在 .solutions/
下找到可能的代碼
- 建立資料夾來託管程式碼,例如「gcf/」。進入資料夾。
- 建立
requirements.txt
檔案:
google-cloud-storage
google-cloud-aiplatform
pymysql
- 建立 Python 函式。範例程式碼:gcf/main.py。
#!/usr/bin/env python
"""Complete this"""
from google.cloud import storage
from google.cloud import aiplatform
import vertexai
from vertexai.generative_models import GenerativeModel, Part
import os
import pymysql
import pymysql.cursors
# Replace with your project ID
PROJECT_ID = "your-project-id"
GEMINI_MODEL = "gemini-1.5-pro-002"
DEFAULT_PROMPT = "Generate a caption for this image: "
def gemini_describe_image_from_gcs(gcs_url, image_prompt=DEFAULT_PROMPT):
pass
def update_db_with_description(image_filename, caption, db_user, db_pass, db_host, db_name):
pass
def generate_caption(event, context):
"""
Cloud Function triggered by a GCS event.
Args:
event (dict): The dictionary with data specific to this type of event.
context (google.cloud.functions.Context): The context parameter contains
event metadata such as event ID
and timestamp.
"""
pass
- 推送函式。您可以使用類似以下的指令碼:gcf/push-to-gcf.sh。
附註 1:請務必使用正確的值來源 ENV,或直接在頂端新增 (GS_BUCKET=blah
, ..):
附註 2:這會推送所有本機程式碼 (.
),因此請務必將程式碼放在特定資料夾中,並以專業的方式使用 .gcloudignore
,以免推送龐大的程式庫。( 範例)。
#!/bin/bash
set -euo pipefail
# add your logic here, for instance:
source .env || exit 2
echo "Pushing ☁️ f(x)☁ to 🪣 $GS_BUCKET, along with DB config.. (DB_PASS=$DB_PASS)"
gcloud --project "$PROJECT_ID" functions deploy php_amarcord_generate_caption \
--runtime python310 \
--region "$GCP_REGION" \
--trigger-event google.cloud.storage.object.v1.finalized \
--trigger-resource "$BUCKET" \
--set-env-vars "DB_HOST=$DB_HOST,DB_NAME=$DB_NAME,DB_PASS=$DB_PASS,DB_USER=$DB_USER" \
--source . \
--entry-point generate_caption \
--gen2
注意:在本例中,generate_caption
會是叫用的函式,而 Cloud Function 會將 GCS 事件連同所有相關資訊 (值區名稱、物件名稱等) 傳遞給該函式。請花點時間對該事件的 Python 字典進行偵錯。
測試函式
單元測試
這個函式包含許多變動因素。您可能會想測試所有單一測試。
範例位於 gcf/test.py 中。
Cloud Functions UI
另外,請花點時間在 UI 上探索函式。每個分頁都值得探索,尤其是 Source
(我最喜歡的)、Variables
、Trigger
和 Logs
。您會花費大量時間在 Logs
中排解錯誤 (請參閱本頁底部的可能錯誤)。此外,請務必檢查 Permissions
。
E2E 測試
是時候手動測試函式了!
- 前往應用程式並登入
- 上傳圖片 (請勿上傳過大的圖片,我們曾遇到大型圖片的問題)
- 檢查使用者介面上已上傳的圖片。
- 在 Cloud SQL Studio 中確認說明已更新。登入並執行這項查詢:
SELECT * FROM images
。
而且真的有效!我們也許也想更新前端,以便顯示該說明。
更新 PHP 以顯示 [選用]
我們已證明應用程式可正常運作。不過,如果使用者也能看到該說明,那就太好了。
我們不需要是 PHP 專家,就能在 index.php
中加入說明。這個程式碼應該可以解決問題 (沒錯,Gemini 也幫我寫了這個程式碼!):
<?php if (!empty($image['description'])): ?>
<p class="font-bold">Gemini Caption:</p>
<p class="italic"><?php echo $image['description']; ?></p>
<?php endif; ?>
您可以自行決定這段程式碼在 foreach
中的位置。
在後續步驟中,我們也會看到更精美的 UI 版本,這要歸功於 Gemini Code Assist。經過美化後的版本可能會像這樣:
結論
您會在 GCS 中收到新物件觸發的 Cloud Function,這項功能可像人類一樣標註圖片內容,並自動更新資料庫。太厲害了!
接下來,您可以按照相同的推理方式,實現兩項絕佳功能。
[選用] 新增其他 Cloud Functions [不限]
我想到幾個額外的功能。
📩? 電子郵件觸發條件
電子郵件觸發條件:每當有人傳送相片時,就會傳送電子郵件給你。
- 是否太頻繁?加入其他限制條件:大圖片,或 Gemini 內容含有「裸露/裸露/暴力」字詞的圖片。
- 建議您查看
EventArc
。
🚫? 自動審核不當圖片
目前,人工管理員會將圖片標示為「不當」。不如讓 Gemini 負責管理聊天室,以便您專心處理其他工作。新增測試,標示不當的觸發內容並更新資料庫,就像我們在前一個函式中所學到的一樣。這表示您基本上會使用先前的函式、變更提示,並根據答案更新資料庫。
注意事項:生成式 AI 的輸出內容難以預測。請確認 Gemini 的「廣告素材輸出」已「上線」。您可以要求確定性的答案,例如 0 到 1 的信心分數、JSON 等。您可以透過多種方式達成這點,例如:* 使用 Python 程式庫 pydantic
、langchain
等。 * 使用 Gemini 結構化輸出結果。
提示:您可以使用多個函式,也可以使用單一提示來強制提供 JSON 答案 (如上所述,與「Gemini 結構化輸出」搭配使用效果最佳),例如:
請問要如何產生這類內容?
{
"description": "This is the picture of an arrosticino",
"suitable": TRUE
}
您可以新增提示中的其他欄位,以便取得洞察資料,例如「是否有任何優點?」不好嗎?你認得這個地方嗎?是否有文字 (光學字元辨識功能簡單易用):
goods
:「看起來很美味」bads
:「看起來像是不健康的食物」OCR
:「Da consumare preferibilmente prima del 10 Novembre 2024」location
:「Pescara, Lungomare」
雖然通常建議為 N 結果建立 N 函式,但如果能讓一個函式執行 10 項工作,效果會非常出色。請參閱 Riccardo 撰寫的文章,瞭解如何操作。
可能的錯誤 (大多是 IAM / 權限)
我第一次開發這個解決方案時,遇到了一些 IAM 權限問題。我會將這些問題加入這裡,以便你瞭解狀況並瞭解如何修正。
錯誤:服務帳戶權限不足
- 請注意,如要部署會監聽 GCS 值區的 GCF 函式,您需要為用於該工作的服務帳戶設定適當權限,如下圖所示:
您可能還需要啟用 EventArc API,這可能需要幾分鐘的時間才能完全啟用。
錯誤:缺少 Cloud Run 叫用器
- 另一個 GCF 權限 UI 的註解如下 ( Cloud Run 叫用者角色):
您可以執行圖像中的指令來修正這項錯誤,這類似於 fix-permissions.sh
請參閱以下說明:https://cloud.google.com/functions/docs/securing/authenticating
錯誤:已超出記憶體上限
第一次執行時,記錄會顯示以下訊息:「記憶體限制為 244 MiB,但已使用 270 MiB。建議您提高記憶體限制,請參閱「https://cloud.google.com/functions/docs/configuring/memory」。再次為 GCF 新增 RAM。在使用者介面中,這項操作非常簡單。以下是可能的異動:
或者,您也可以修正 Cloud Run 部署指令碼,以便提高 MEM/CPU。這需要較長的時間。
錯誤:PubSub 已發布
使用 GCF 1.0 建立觸發條件時,曾經發生以下錯誤:
同樣地,您可以前往 IAM,為服務帳戶授予「Pub/Sub 發布者」角色,輕鬆解決這個問題。
錯誤:未使用 Vertex AI
如果收到這則錯誤訊息:
權限遭拒:403 專案「YOUR_PROJECT」先前未曾使用或已停用 Vertex AI API。請前往 https://console.developers.google.com/apis/api/aiplatform.googleapis.com/overview?project=YOR_PROJECT 啟用。
您只需啟用 Vertex AI API。如要啟用所有必要的 API,最簡單的方法如下:
- https://console.cloud.google.com/vertex-ai
- 按一下「啟用所有建議的 API」。
錯誤:找不到 Eventarc 觸發條件。
如果收到這則訊息,請重新部署函式。
錯誤:正在為 400 個服務代理程式進行佈建
系統正在佈建 400 個服務代理程式 ( https://cloud.google.com/vertex-ai/docs/general/access-control#service-agents)。服務代理程式需要讀取提供的 Cloud Storage 檔案。因此,請過幾分鐘後再試一次。
如果發生這種情況,請稍待片刻或向 Google 員工尋求協助。
10. 單元 8:建立可用性服務等級目標
本章節將說明如何達成以下目標:
- 建立 SLI
- 根據 SLI 建立服務等級目標
- 根據服務等級目標建立快訊
這對作者來說是相當重要的主題,因為 Riccardo 在 Google Cloud 的 SRE / DevOps 領域工作。
(開放式) 為這個應用程式建立服務水準指標和服務等級目標
如果無法得知應用程式何時發生問題,那麼應用程式還算好用嗎?
什麼是 SLO?
喔,Google 發明瞭服務等級目標!如要進一步瞭解這項功能,建議您:
- SRE 書籍 - 第 2 章 - 實作 SLO。( 👉? 更多 SRE 書籍)
- 服務等級目標的藝術 ( 精彩影片)。這堂課程非常實用,可進一步瞭解如何為服務建立完美的 SLO。
- Coursera 的 SRE 課程。我有參與編輯!
步驟 1:建立可用性 SLI/SLO
我們從可用性 SLO 開始,因為這是您要評估的最簡單且可能最重要的指標。
幸運的是,Cloud Run 內建 Istio,因此支援 SLO。
應用程式在 Cloud Run 上執行後,這項操作非常簡單,我只花了 30 秒就完成。
- 前往 Cloud Run 頁面。
- 按一下/選取應用程式。
- 選取「
SLOs
」分頁。 - 按一下「+ 建立 SLO」。
- 供應情形,根據要求
- 繼續
- 日曆月份 / 99%。
- 按一下「建立 SLO」。
步驟 2:為這項 SLO 設定警示
建議建立 2 個快訊:
- 一個消耗率低的帳戶 (「Slowburn」),透過電子郵件傳送快訊 (模擬低優先順序的支援單)。
- 一個具有高耗損率 (「Fastburn」) 的用戶,透過簡訊發出警報 (模擬高優先順序的支援單 / 傳呼器)
前往先前的 SLO tab
。
重複執行這項操作兩次:
- 按一下「建立服務水準目標快訊」(右側有加號的 🔔? 按鈕)
- 回溯時間長度、消耗率門檻:
- [FAST]。第一個:
60
分鐘 /10
x - [慢速]。秒數:
720
分鐘 /2
x - 通知管道:按一下「管理通知管道」
- 首先,點選「電子郵件」->「新增」->
- 第二種方法是點選「簡訊」->「新增」->「在手機上驗證」。
- 提示:我喜歡在名稱中使用表情符號!這麼做很有趣。
- 完成後,按一下右上方的大 X 圖示。
- 請先選取電話 (速度快),再選取電子郵件 (速度慢)。
- 新增一些範例文件,例如:
[PHP Amarcord] Riccardo told me to type sudo reboot or to check documentation in http://example.com/playbooks/1.php but I guess he was joking
。
賓果!
最終結果
當您設定 1 個可運作的 SLO 和 2 個可用性快訊,並且已在電子郵件和手機上收到快訊時,我們就會視為完成這項練習。
您可以視需要新增 Latency (強烈建議您這麼做),甚至是更複雜的 Latency。針對延遲時間,請選擇您認為合理的延遲時間;如果不確定,請選擇「200 毫秒」。
11. 後續步驟
你已完成所有步驟,還缺少什麼嗎?
以下提供一些思考方向:
與 Gemini 互動
Gemini 有兩種版本:
- Vertex AI。「企業級方式」與 GCP 密切相關,我們已在第 7 章 (GCF+Gemini) 介紹這項做法。所有驗證都能正常運作,服務之間也能完美連結。
- Google AI。「消費者方式」。您可以從這裡取得 Gemini API 金鑰,然後開始建構小型指令碼,並將其連結至您現有的任何工作負載 (專屬工作、其他雲端、本機...)。只要替換 API 金鑰,程式碼就會神奇地開始運作。
建議您嘗試在自己的專案中探索 (2)。
UI 提取
我對使用者介面不熟悉。但 Gemini 是!您可以只使用單一 PHP 頁面,並說出類似以下的內容:
I have a VERY old PHP application. I want to touch it as little as possible. Can you help me:
1. add some nice CSS to it, a single static include for tailwind or similar, whatever you prefer
2. Transform the image print with description into cards, which fit 4 per line in the canvas?
Here's the code:
-----------------------------------
[Paste your PHP page, for instance index.php - mind the token limit!]
您可以在不到 5 分鐘內輕鬆完成這項操作,只需執行一個 Cloud Build 即可!:)
Gemini 的回覆非常完美 (也就是說,我不需要做任何變更):
以下是作者個人應用程式中的新版面配置:
注意:我們將程式碼貼上為圖片,因為我們不鼓勵您採用程式碼,而是建議您使用 Gemini 為您編寫程式碼,並套用您自己的廣告素材 UI/前端限制。請放心,您之後只需進行非常少量的變更。
安全性
這個 4 小時工作坊的目標並非讓您瞭解如何妥善保護這個應用程式,因為這會讓工作坊的完成時間增加 1 到 2 個數量級。
不過,這個主題非常重要!我們在 SECURITY
中收集了一些想法。
12. 恭喜!
恭喜🎉?🎉?🎉?,您已成功使用 Google Cloud 改良舊版 PHP 應用程式。
以下是本程式碼研究室的重點摘要:
- 如何在 Google Cloud SQL 中部署資料庫,以及如何將現有資料庫遷移至該資料庫。
- 如何使用 Docker 和 Buildpack 將 PHP 應用程式容器化,並將映像檔儲存至 Google Cloud Artifact Registry
- 如何將容器化應用程式部署至 Cloud Run,並透過 Cloud SQL 執行
- 如何使用 Google Secret Manager 秘密儲存/使用機密設定參數 (例如資料庫密碼)
- 如何使用 Google Cloud Build 設定 CI/CD 管道,以便在任何程式碼推送至 GitHub 存放區時,自動建構及部署 PHP 應用程式。
- 如何使用 Cloud Storage 將應用程式資源「雲端化」
- 如何運用無伺服器技術,在 Google Cloud 上建構出色的工作流程,而無須修改應用程式程式碼。
- 根據適當的用途使用 Gemini 多模態功能。
- 在 Google Cloud 中實作 SRE 原則
這是您透過 Google Cloud 翻新應用程式的絕佳起點!
🔁? 意見回饋
如要分享您參加工作坊的體驗,歡迎填寫這份意見回饋表單。
歡迎您提供意見回饋,以及PR,針對您特別自豪的程式碼片段提出建議。
🙏? 感謝
作者要感謝 Datatonic 的 Mirko Gilioli 和 Maurizio Ipsale,感謝他們協助撰寫文章並測試解決方案。