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 編輯器所需的各項功能如下圖所示
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 中的所有資料庫都採用「隔離」架構。您必須明確設定可存取的網路。
- 按一下執行個體
- 開啟「連線」選單
- 按一下「網路」分頁標籤。
- 點選「已授權的網路」下方的接著新增子網路。
- 為了讓應用程式運作,我們現在就讓它處於不安全的狀態:
- 名稱:「Everyone in the world - INSECURE」(提醒自己,這個便宜的解決方案也不安全)。
- 網路:"0.0.0.0/0" (注意:這不安全!)
按一下 [Save] (儲存)。
畫面應如下所示:
注意:這個解決方案是完成工作坊的理想折衷做法,所需時間為 O(小時)。不過,請參閱「安全性」文件,瞭解如何保護實際工作環境的解決方案!
現在是測試資料庫連線的時候了!
接著來看看之前建立的 image_catalog
使用者是否在工作前建立。在執行個體中存取 Cloud SQL Studio,然後輸入要驗證的資料庫、使用者和密碼,如下所示:
完成上述步驟後,請開啟 SQL 編輯器並繼續下個部分。
從程式碼集匯入資料庫
使用 SQL 編輯器匯入 image_catalog 資料表和其資料。從存放區中的 SQL 檔案取得 SQL 程式碼,然後依序執行其中一個程式碼。01_schema.sql,然後再執行 02_seed.sql。
完成後,image_catalog 中應會出現兩個資料表,分別是 users 和 images,如下所示:
如要測試,請在編輯器中執行下列指令:select * from images;
另外,請務必記下公開 IP 位址,後續步驟會用到。
4. 模組 2:將 PHP 應用程式容器化
我們想為雲端建構這個應用程式。
也就是說,您需要將程式碼打包成某種 ZIP 檔案,其中包含在雲端執行程式碼所需的所有資訊。
您可以透過以下幾種方式封裝:
- Docker。非常熱門,但設定方式相當複雜。
- Buildpack。較不常使用,但會「自動判斷」要建構和執行哪些項目。通常都能正常運作!
在本講習課程的範疇內,我們假設您使用 Docker。
Docker
如果您希望自己掌控,這是適合您的解決方案。當您需要設定特定程式庫,並注入特定不明顯的行為 (上傳內容中的 chmod、應用程式中的非標準可執行檔等) 時,這就很有用。
最後,我們想要將容器化應用程式部署至 Cloud Run,請查看下方的說明文件,並嘗試填空題。我們目前只提供必要的資訊,以便簡化操作。最終 Dockerfile 會類似如下:
# Use an official PHP image with Apache
# Pull a suitable php image
FROM __________# Define the env variable for the Apache listening port 8080
ENV __________
# Set working directory inside the container
WORKDIR __________
# Install required PHP extensions: PDO, MySQL, and other dependencies
RUN __________
# Copy all application files into the container
COPY __________
# Configure Apache to listen on port 8080. Use ‘sed' command to change the default listening port.
RUN __________
# When in doubt, always expose to port 8080
EXPOSE __________
# Start Apache in the foreground
CMD __________
此外,為了在本機測試應用程式,我們需要變更 config.php 檔案,讓 PHP 應用程式連線至 Google CloudSQL 上的 MYSQL 資料庫。根據您先前的設定,填寫空白欄位。
- DBM_host 是 Cloud SQL 公開 IP 位址,您可以在控制台中找到這個位址:
- Db_name 應保持不變:
image_catalog
- Db_user 應為
appmod-phpapp-user
- DBM_pass 是您選擇的項目。請設定成單引號,並視需要逸出。
<?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();
?>
此外,您也可以使用 Gemini 將少數義大利文內容翻譯成英文!
好,現在您已取得 Dockerfile,並設定 PHP 應用程式連線至資料庫,讓我們試試看吧!
如果您尚未安裝 Docker,請先安裝 (連結)。如果您使用 Cloud Shell,則不需要。
接著,請嘗試使用適當的 Docker 建構和執行指令,建構及執行容器化 PHP 應用程式。
- docker build -t <IMAGE_TAG_NAME> .
- docker run -it -p <CONTAINER PORT>:<LOCAL MACHINE PORT> <IMAGE_TAG_NAME>
如果一切正常運作,連線至本機主機後,您應該會看到下列網頁。
如果您是使用 Cloud Shell,也可以將本機通訊埠 (例如 8080) 匯出至瀏覽器,如下所示:
docker build -t my-php-app-docker app-mod-workshop/ -f Dockerfile
docker run -it -p 8080:8080 my-php-app-docker
您現在知道應用程式在通訊埠 8080 上執行,請按一下「網頁預覽」圖示 (瀏覽器上有眼睛圖示),然後點選「透過以下通訊埠預覽:8080」 (或「變更通訊埠」以查看其他通訊埠)
在瀏覽器中測試結果
現在,應用程式應如下所示:
如果您使用 Admin/admin123 登入,應該會看到類似以下的畫面。
太好了!可以了 🎉🎉🎉
如果 Docker 化作業正常,但資料庫憑證錯誤,您可能會看到類似以下的訊息:
再試一次,就在手邊!
建築包 [選用]
有了 Buildpacks,應用程式就會自動建構。很抱歉,您無法完全控制,因此可能會導致意外的設定。
- 請參閱 GCP 中的 BuildPacks:https://cloud.google.com/docs/buildpacks/build-application 和這裡
- 安裝
pack
:https://buildpacks.io/docs/for-platform-operators/how-to/integrate-ci/pack/ - 以 PHP 編寫的 buildpacks:https://cloud.google.com/docs/buildpacks/php (其中會說明如何設定 PHP 版本)
- 請嘗試下列操作,自動建構容器映像檔。
pack build --builder=gcr.io/buildpacks/builder my-app-with-buildpacks
本機環境中應有新的 Docker 映像檔。您可以嘗試為其執行容器,但由於我們無法完全控制映像檔的建構方式,因此應用程式可能無法運作。無論如何,我們都歡迎你進行實驗,如果成功分享你的看法,謝謝!
儲存至 Artifact Registry [選用]
到目前為止,您應該已準備好容器化 PHP 應用程式,可部署至雲端。接下來,我們需要在雲端中儲存 Docker 映像檔,並讓它可供部署至 Cloud Run 等 Google Cloud 服務。這個儲存空間解決方案稱為 Artifact Registry,是專為儲存應用程式構件 (包括 Docker 容器映像檔、Maven 套件、npm 模組等) 而設計的全代管 Google Cloud 服務。
使用相應按鈕,在 Google Cloud Artifact Registry 中建立存放區。
選擇有效的名稱、格式和適合儲存構件的位置。
回到本機開發環境標記,並將應用程式容器映像檔推送至剛建立的 Artifact Registry 存放區。請執行下列指令來完成這項操作。
- docker 標記 SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
- docker push TARGET_IMAGE[:TAG]
結果應如下螢幕截圖所示。
萬歲!🎉?🎉?🎉?你可以晉升到下一級。
注意事項:請嘗試使用 /upload.php
端點,並嘗試上傳相片。您可能會收到「Permission denied」(權限遭拒) 的訊息。如果是的話,請修正 Dockerfile
中的 chmod/chown
。
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
到目前為止,一切都已準備就緒,可以部署至 Cloud Run。
透過 gcloud 將應用程式部署至 Cloud Run
您可以使用 gcloud run deploy
指令,在 Cloud Run 上部署應用程式。您可以設定多種選項來達成目標。最低設定值如下:
- 您要為應用程式部署的 Cloud Run 服務名稱。Cloud Run 服務會傳回一個網址,為您的應用程式提供端點。
- 應用程式執行的 Google Cloud 區域。
- 包裝應用程式的容器映像檔。
- 應用程式在執行期間需要使用的環境變數。
- Allow-Unauthenticated 旗標:允許所有使用者在不經過進一步驗證的情況下存取應用程式
請參閱說明文件,瞭解如何將這個選項套用至指令。部署作業會在幾分鐘內完成。如果一切正確無誤,您應該會在 Google Cloud 控制台中看到類似下方的結果。
按一下 Cloud Run 提供的網址,並測試應用程式。通過驗證後,畫面應如下所示。
「gcloud run deploy」加上「no questions」
您可能已經注意到,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 設定 X 的選項
--my-option [my-value]
。 - 除非 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 變數中讀取 db 參數。如果失敗,建議您考慮設定預設值。這在您無法載入 ENV 時很有幫助,因為網頁輸出內容會告訴您是否使用預設值。填入空格並替換 config.php 中的程式碼。
<?php
// Database configuration with ENV variables. Set default values as well
$db_host = getenv('DB_HOST') ?: _______;
$db_name = getenv('DB_NAME') ?: 'image_catalog';
$db_user = getenv('DB_USER') ?: 'appmod-phpapp-user';
$db_pass = getenv('DB_PASS') ?: _______;
// 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
- 按一下應用程式
- 按一下「編輯及部署新的修訂版本」
- 在第一個「容器」分頁中,按一下下方的「變數與密鑰」分頁
- 按一下「+ 新增變數」,然後新增所有必要的變數。最終畫面應如下所示:
這樣就沒問題了嗎?不會,大部分的電信業者仍能看到你的票證。您可以使用 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,請從漢堡選單前往「Security」(安全性) 服務,並在「資料保護」部分下方找到這個選項 (如下方螢幕截圖所示)。
請按照下圖所示,在該頁面中啟用 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」>「Settings」(設定)。
- 「[PROJECT_NUMBER]- compute@developer.gserviceaccount.com」服務帳戶
- 勾選下列方塊:
- Cloud Run
- Secret Manager
- 服務帳戶
- Cloud Build
- 並勾選「設為偏好的服務帳戶」
Cloud Buld 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」>「觸發條件」>「執行」)
請注意,使用這個解決方案後,您仍需完成一些工作。例如,必須為新建立的開發/實際工作環境端點設定 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 帳戶以對抗對抗程式碼,而其提取/推送變得輕而易舉。
請記得使用其他檔案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
上執行 FUSE 掛接 (類似於 /var/www/html/uploads/
):
#!/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 強化應用程式
現在,您有了雲端化儲存空間,打造出全新且優質的新 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 函式 (舊稱
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
中的位置。
Gemini Code Assist 有助於在後續步驟中,看到更精美的 UI 版本。經過美化後的版本可能會像這樣:
結論
您會在 GCS 上收到新物件觸發的 Cloud Function,該函式可像人類一樣標註圖片內容,並自動更新資料庫。太厲害了!
接下來,您可以按照相同的推理方式,實現兩項絕佳功能。
[選用] 新增其他 Cloud Functions [不限]
還有一些其他功能。
📩 電子郵件觸發條件
電子郵件觸發條件,會在每次有人傳送圖片時傳送電子郵件給您。
- 頻率過高?加入其他限制條件:大圖片,或 Gemini 內容含有「裸露/裸露/暴力」字詞的圖片。
- 請考慮使用
EventArc
來執行這項操作。
🚫? 自動審核不當圖片
目前,人工管理員會將圖片標示為「不當」。想讓 Gemini 代勞並審核空間嗎?新增測試,標示不當的觸發內容並更新資料庫,就像我們在先前的函式中所學到的一樣。這表示您基本上會使用先前的函式、變更提示,並根據答案更新資料庫。
注意事項:生成式 AI 的輸出內容無法預測。請確認 Gemini 的「廣告素材輸出」已「上線」。你可以透過多種方式提出確定性答案,例如 0 到 1 的可信度分數、JSON 等。你可以透過多種方式達成這個目標,例如:* 使用 Python 程式庫 pydantic
、langchain
、.. * 使用 Gemini 結構化輸出內容。
提示:您可能有 MULTIPLE 函式,或使用單一提示強制執行 JSON 答案 (使用 greta 搭配「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 Vertex AI API 先前未在專案 YOUR_PROJECT 中使用或已停用。請前往 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 / 開發運作領域。
(開放式) 建立這個應用程式的 SLI 和服務等級目標
如果無法得知應用程式何時發生問題,那麼應用程式還算好用嗎?
什麼是 SLO?
喔,Google 發明瞭服務等級目標!如要進一步瞭解這項功能,建議您:
- SRE 書籍 - 第 2 章 - 實作 SLO。( 👉?更多 SREbooks)
- Google 服務等級目標 ( 很棒影片)。這堂課程非常實用,可以進一步瞭解如何為服務建立完美的 SLO。
- Coursera 上的 SRE 課程。我有參與這項計畫!
步驟 1:建立可用性 SLI/SLO
首先從可用性服務等級目標著手,這是最簡單且最需要評估的要素。
幸運的是,Cloud Run 已預先內建 SLO 支援功能,這要歸功於 Istio。
您的應用程式在 Cloud Run 中運作後,整個過程非常簡單,我只需要 30 秒就能完成。
- 前往 Cloud Run 頁面。
- 按一下/選取應用程式。
- 選取「
SLOs
」分頁。 - 按一下「+ 建立 SLO」。
- 供應情形 (以要求為依據)
- 繼續
- 日曆月份 / 99%。
- 按一下「建立 SLO」。
步驟 2:為這項 SLO 設定警示
建議建立 2 個快訊:
- 一個消耗率低的帳戶 (「Slowburn」),透過電子郵件通知您 (模擬低優先順序的支援單)。
- 一個具有高耗損率 (「Fastburn」) 的票據,可透過簡訊發出警報 (模擬高優先順序票據 / 尋呼機)
前往先前的 SLO tab
。
重複上述動作:
- 按一下「建立服務水準目標快訊」(右側有加號的 🔔? 按鈕)
- 回溯時間長度、消耗率門檻:
- [FAST]。第一步:
60
分鐘 /10
x - [慢速]。秒數:
720
分鐘 /2
x - 通知管道:按一下「管理通知管道」
- 首先,依序按一下「Email」->「Add new」->。
- 接著,依序前往「SMS」->「Add new」-> 在手機上驗證。
- 提示:我喜歡在名稱中使用表情符號!這麼做很有趣。
- 完成後,按一下右上方的大 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。我們在第 7 章 (GCF + Gemini) 中介紹了「企業方式」,這與 GCP 密切相關。所有驗證都能正常運作,服務之間也能完美連結。
- 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 小時工作坊的目標並非要讓您瞭解如何妥善保護這個應用程式。
如需相關靈感,請參閱 SECURITY
doc
。
12. 恭喜!
恭喜🎉?🎉?🎉?,您已成功使用 Google Cloud 改良舊版 PHP 應用程式。
以下是本程式碼研究室的重點摘要:
- 如何在 Google Cloud SQL 中部署 MYSQL 資料庫,以及如何將現有資料庫遷移至該資料庫。
- 如何使用 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 翻新應用程式的絕佳起點!
🔁 意見回饋
如要分享您參加工作坊的體驗,歡迎填寫這份意見回饋表單。
歡迎您提供意見回饋,以及PR,針對您特別自豪的程式碼片段提出建議。
🙏? 謝謝
作者向 Datatonic 提供的 Mirko Gilioli 和 Maurizio Ipsale 致敬,感謝協助撰寫及測試解決方案。