應用程式翻新研討會

1. 簡介

上次更新時間:2024 年 11 月 1 日

如何將舊的 PHP 應用程式翻新至 Google Cloud?

(📽?️ 觀看本程式碼研究室的 7 分鐘簡介影片 )

通常,在內部執行的舊版應用程式都需要進行現代化。這表示這些應用程式可在不同環境中部署,且具備可擴充性和安全性。

本工作坊涵蓋下列主題:

  1. 將 PHP 應用程式容器化
  2. 遷移至代管的 資料庫服務 ( Cloud SQL)。
  3. 部署至 Cloud Run (這是 GKE/Kubernetes 的零運算替代方案)。
  4. 使用 Identity and Access Management (IAM) 和 Secret Manager 保護應用程式。
  5. 透過 Cloud Build 定義 CI/CD 管道。Cloud Build 可連結至託管於熱門 Git 供應商 (例如 GitHub 或 GitLab) 的 Git 存放區,並在任何推送至主分支時觸發。
  6. 將應用程式相片代管在 Cloud Storage 中。這項功能是透過掛載完成,無須使用程式碼即可變更應用程式。
  7. 透過 Gemini 引入生成式 AI 功能,並透過 Cloud Functions (無伺服器) 進行調度。
  8. 熟悉SLOs,並操作您新刷新的應用程式。

只要按照下列步驟,即可逐步翻新 PHP 應用程式,提高擴充性、安全性和部署彈性。此外,您還可以透過遷移至 Google Cloud,運用其強大的基礎架構和服務,確保應用程式在雲端原生環境中順利執行。

我們相信,您在完成這些簡單步驟後所學到的知識,可以應用於自己的應用程式和機構,並支援不同的語言/程式庫和用途。

關於應用程式

您將分支使用的應用程式 ( 程式碼,依據 MIT 授權定義),是採用 MySQL 驗證的基本 PHP 5.7 應用程式。這款應用程式的主要概念是提供平台,讓使用者上傳相片,管理員則可標記不當圖片。應用程式有兩個資料表:

  • 使用者。已預先編譯並提供給管理員。新使用者可以註冊。
  • 圖片:附帶幾張範例圖片。登入的使用者可以上傳新相片。我們會在這裡施展一些魔法。

您的目標

我們希望翻新舊應用程式,以便在 Google Cloud 中使用。我們將利用其工具和服務來提升可擴充性、強化安全性、自動化基礎架構管理,並整合圖像處理、監控和資料儲存等進階功能,使用 Cloud SQL、Cloud Run、Cloud Build、Secret Manager 等服務。

445f7a9ae37e9b4d.png

更重要的是,我們希望逐步進行,讓您學習每個步驟背後的思考過程,而且通常每個步驟都會為後續步驟開啟新的可能性 (例如:單元 2 -> 3,以及 6 -> 7)。

還不相信嗎?請在 YouTube 上查看這部 7 分鐘的影片

軟硬體需求

  • 裝有瀏覽器並連上網際網路的電腦。
  • 部分 GCP 抵免額。詢問當地的 Google 愛好者 ;)
  • gcloud 指令運作正常。
  • 您是否在本地工作?請按這裡下載。您也需要一些不錯的編輯器 (例如 vscode 或 intellij)。
  • 想在「雲端」中完成所有工作嗎?屆時您可以使用 Cloud Shell
  • GitHub 使用者。您需要這項工具,才能使用自己的 Git 存放區分支原始程式碼 🧑🏻‍💻 gdgpescara/app-mod-workshop。您必須建立自己的 CI/CD 管道 (自動修訂版本 -> 建構 -> 部署)

解決方案範例如下:

您可以透過本機電腦使用這門工作坊,也可以完全在瀏覽器上完成。

2. 設定功勞和分支

6dafc658860c0ce5.png

兌換 GCP 抵免額,並設定 GCP 環境 [選用]

如要參加這項工作坊,您需要擁有結算帳戶並有一定金額的信用額度。如果您已擁有自己的帳單,可以略過這個步驟。

建立全新的 Google Gmail 帳戶 (*),以便連結 GCP 信貸。請向老師索取 GCP 抵免額兌換連結,或使用這裡的抵免額:bit.ly/PHP-Amarcord-credits

使用新建立的帳戶登入,並按照指示操作。

ff739240dbd84a30.png

(

) 為什麼我需要全新的 Gmail 帳戶?*

我們發現有些人無法完成程式碼研究室,因為他們的帳戶 (尤其是工作或學生電子郵件) 曾接觸過 GCP,且有 機構政策 限制他們執行程式碼研究室。建議您建立新的 Gmail 帳戶,或使用未曾接觸 GCP 的現有 Gmail 帳戶 (gmail.com)。

按一下按鈕即可兌換抵免額。

331658dc50213403.png

請在以下表單中填寫您的姓名和姓氏,並同意《條款及細則》。

您可能需要等待幾秒,帳單帳戶才會顯示在以下位置:https://console.cloud.google.com/billing

完成後,請開啟 Google Cloud 控制台,然後按一下左上方下拉式選單中的「Project Selector」,建立新專案,其中會顯示「No organization」。詳情請見下方

bd7548f78689db0b.png

如果您還沒有專案,請建立新專案,如下方螢幕截圖所示。右上角有「NEW PROJECT」選項。

6c82aebcb9f5cd47.png

請務必將新專案連結至 GCP 試用帳單帳戶,步驟如下:

f202527d254893fb.png

您現在可以開始使用 Google Cloud Platform。如果您是初學者,或是只想在 Cloud 環境中執行所有操作,可以透過左上角的按鈕存取 Cloud Shell 和編輯器,如下圖所示。

7d732d7bf0deb12e.png

確認已選取左上方的新專案:

未選取 (錯誤):

c2ffd36a781b276a.png

已選取 (良好):

594563c158f4f590.png

從 GitHub 建立應用程式分支

  1. 前往試用版應用程式:https://github.com/gdgpescara/app-mod-workshop
  2. 按一下「分支」圖示 🍴?。
  3. 如果您沒有 GitHub 帳戶,請建立一個。
  4. 您可以隨意編輯內容。

734e51bfc29ee5df.png

  1. 使用 git clone 複製應用程式程式碼:https://github.com/<YOUR-GITHUB-USER>/<YOUR-REPO-NAME>
  1. 使用您偏好的編輯器開啟複製的專案資料夾。如果選擇 Cloud Shell,請按一下「Open Editor」(開啟編輯器),如下所示。

40f5977ea4c1d1cb.png

使用 Google Cloud Shell 編輯器所需的各項功能如下圖所示

a4e5ffb3e9a35e84.png

3. 單元 1:建立 SQL 執行個體

645902e511a432a6.png

建立 Google Cloud SQL 執行個體

我們的 PHP 應用程式會連線至 MySQL 資料庫,因此我們需要將資料庫複製到 Google Cloud,以便輕鬆遷移。Cloud SQL 是完美的選擇,因為您可以在雲端中執行全代管 MySQL 資料庫。步驟如下:

  1. 前往 Cloud SQL 頁面:https://console.cloud.google.com/sql/instances
  2. 按一下「建立執行個體」
  3. 啟用 API (如有需要)。這可能需要幾秒鐘。
  4. 選擇「MySQL」。
  5. (我們會盡量為你提供最便宜的版本,以延長使用壽命):
  • 版本:Enterprise
  • 預設值:development (我們嘗試使用沙箱,但無法正常運作)
  • Mysql 版本:5.7 (哇,這真是回憶殺!)
  1. 執行個體 ID:選擇 appmod-phpapp (如果變更這項設定,日後請記得一併變更指令碼和解決方案)。
  2. 密碼:您可以輸入任何名稱,但請記下 CLOUDSQL_INSTANCE_PASSWORD
  3. 區域:保留與您為應用程式其他部分選擇的相同區域 (例如米蘭 = europe-west8)
  4. 可用區可用性:單一可用區 (我們要節省示範的費用)

按一下「Create Instance」(建立執行個體) 按鈕,部署 Cloud SQL 資料庫;⌛這項作業需要約 10 分鐘才能完成⌛。在此期間,請繼續閱讀文件;您也可以開始解決下一個模組 (「將 PHP 應用程式容器化」),因為它與第一部分的這個模組沒有任何依附元件 (直到您修正資料庫連線為止)。

注意:這個執行個體的費用約為 $7 美元/天。請務必在工作坊結束後關閉。

在 Cloud SQL 中建立 image_catalog 資料庫和使用者

應用程式專案隨附 db/ 資料夾,其中包含兩個 SQL 檔案:

  1. 01_schema.sql:包含 SQL 程式碼,可建立兩個包含使用者和圖片資料的表格。
  2. 02_seed.sql:包含 SQL 程式碼,以便查看先前建立的資料表中種子資料。

這些檔案會在稍後建立 image_catalog 資料庫時使用。如要執行這項操作,請按照下列步驟操作:

  1. 開啟執行個體,然後按一下「資料庫」分頁:
  2. 按一下 [建立資料庫]
  3. 將其稱為 image_catalog (如 PHP 應用程式設定中所示)。

997ef853e5ebd857.png

接著,我們要建立資料庫使用者。這樣我們就能驗證 image_catalog 資料庫。

  1. 接著按一下「使用者」分頁標籤
  2. 按一下「新增使用者帳戶」。
  3. 使用者:開始建立一個:
  • 使用者名稱:appmod-phpapp-user
  • 密碼:選擇您記得的密碼,或按一下 [產生]
  • 保留「允許任何主機 (%)」設定。
  1. 按一下「新增」。

將資料庫開放給已知的 IP。

請注意,Cloud SQL 中的所有資料庫都採用「隔離」架構。您必須明確設定可存取的網路。

  1. 按一下執行個體
  2. 開啟「連線」選單
  3. 按一下「網路」分頁標籤。
  4. 點選「已授權的網路」下方的接著新增子網路。
  • 為了讓應用程式運作,我們現在就讓它處於不安全的狀態:
  • 名稱:「Everyone in the world - INSECURE」(提醒自己,這個便宜的解決方案也不安全)。
  • 網路:"0.0.0.0/0" (注意:這不安全!)

按一下 [Save] (儲存)。

畫面應如下所示:

5ccb9062a7071964.png

注意:這個解決方案是完成工作坊的理想折衷做法,所需時間為 O(小時)。不過,請參閱「安全性」文件,瞭解如何保護實際工作環境的解決方案!

現在是測試資料庫連線的時候了!

接著來看看之前建立的 image_catalog 使用者是否在工作前建立。在執行個體中存取 Cloud SQL Studio,然後輸入要驗證的資料庫、使用者和密碼,如下所示:

d56765c6154c11a4.png

完成上述步驟後,請開啟 SQL 編輯器並繼續下個部分。

從程式碼集匯入資料庫

使用 SQL 編輯器匯入 image_catalog 資料表和其資料。從存放區中的 SQL 檔案取得 SQL 程式碼,然後依序執行其中一個程式碼。01_schema.sql,然後再執行 02_seed.sql

完成後,image_catalog 中應會出現兩個資料表,分別是 usersimages,如下所示:

65ba01e4c6c2dac0.png

如要測試,請在編輯器中執行下列指令:select * from images;

另外,請務必記下公開 IP 位址,後續步驟會用到。

4. 模組 2:將 PHP 應用程式容器化

e7f0e9979d8805f5.png

我們想為雲端建構這個應用程式。

也就是說,您需要將程式碼打包成某種 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 位址,您可以在控制台中找到這個位址:

bd27071bf450a8d0.png

  • 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」 (或「變更通訊埠」以查看其他通訊埠)

33a24673f4550454.png

在瀏覽器中測試結果

現在,應用程式應如下所示:

2718ece96b1f18b6.png

如果您使用 Admin/admin123 登入,應該會看到類似以下的畫面。

68b62048c2e86aea.png

太好了!可以了 🎉🎉🎉

如果 Docker 化作業正常,但資料庫憑證錯誤,您可能會看到類似以下的訊息:

e22f45b79bab86e1.png

再試一次,就在手邊!

建築包 [選用]

有了 Buildpacks,應用程式就會自動建構。很抱歉,您無法完全控制,因此可能會導致意外的設定。

本機環境中應有新的 Docker 映像檔。您可以嘗試為其執行容器,但由於我們無法完全控制映像檔的建構方式,因此應用程式可能無法運作。無論如何,我們都歡迎你進行實驗,如果成功分享你的看法,謝謝!

儲存至 Artifact Registry [選用]

到目前為止,您應該已準備好容器化 PHP 應用程式,可部署至雲端。接下來,我們需要在雲端中儲存 Docker 映像檔,並讓它可供部署至 Cloud Run 等 Google Cloud 服務。這個儲存空間解決方案稱為 Artifact Registry,是專為儲存應用程式構件 (包括 Docker 容器映像檔、Maven 套件、npm 模組等) 而設計的全代管 Google Cloud 服務。

使用相應按鈕,在 Google Cloud Artifact Registry 中建立存放區。

e1123f0c924022e6.png

選擇有效的名稱、格式和適合儲存構件的位置。

4e516ed209c470ee.png

回到本機開發環境標記,並將應用程式容器映像檔推送至剛建立的 Artifact Registry 存放區。請執行下列指令來完成這項操作。

  • docker 標記 SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
  • docker push TARGET_IMAGE[:TAG]

結果應如下螢幕截圖所示。

1e498feb4e88be9f.png

萬歲!🎉?🎉?🎉?你可以晉升到下一級。

注意事項:請嘗試使用 /upload.php 端點,並嘗試上傳相片。您可能會收到「Permission denied」(權限遭拒) 的訊息。如果是的話,請修正 Dockerfile 中的 chmod/chown

5. 單元 3:將應用程式部署至 Cloud Run

9ffca42774f6c5d1.png

為何選用 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 上部署應用程式。您可以設定多種選項來達成目標。最低設定值如下:

  1. 您要為應用程式部署的 Cloud Run 服務名稱。Cloud Run 服務會傳回一個網址,為您的應用程式提供端點。
  2. 應用程式執行的 Google Cloud 區域
  3. 包裝應用程式的容器映像檔
  4. 應用程式在執行期間需要使用的環境變數
  5. Allow-Unauthenticated 旗標:允許所有使用者在不經過進一步驗證的情況下存取應用程式

請參閱說明文件,瞭解如何將這個選項套用至指令。部署作業會在幾分鐘內完成。如果一切正確無誤,您應該會在 Google Cloud 控制台中看到類似下方的結果。

ef1029fb62f8de81.png

f7191d579c21ca3e.png

按一下 Cloud Run 提供的網址,並測試應用程式。通過驗證後,畫面應如下所示。

d571a90cd5a373f9.png

「gcloud run deploy」加上「no questions」

您可能已經注意到,gcloud run deploy 會詢問正確的問題,並填入您留下的空白。真是太棒了!

不過,我們會在幾個模組中新增這項指令至 Cloud Build 觸發條件,這樣我們沒辦法得到問題。我們需要在指令中填入所有選項。因此,你想製作金色 gcloud run deploy --option1 blah --foo bar --region your-fav-region。該如何進行?

  1. 重複執行步驟 2-3-4,直到 gcloud 停止詢問問題:
  2. [LOOP] 目前已找到選項的 gcloud run deploy
  3. [LOOP] 系統要求選項 X
  4. [LOOP] 在公開文件中搜尋如何透過 CLI 設定 X 的選項 --my-option [my-value]
  5. 除非 gcloud 完成執行而沒有其他問題,否則請返回步驟 2。
  6. 這個 gcloud run deploy BLAH BLAH BLAH 岩石!請將指令儲存在某處,後續在 Cloud Build 步驟中會用到!

請參閱這篇文章瞭解可能的解決方法。

太棒了!🎉🎉🎉您已成功在 Google Cloud 中部署應用程式,完成了翻新計畫的第一步。

6. 單元 4:使用 Secret Manager 清除密碼

95cd57b03b4e3c73.png

在先前的步驟中,我們成功在 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

您現在已完成以下操作:

  1. 應用程式會動態讀取 ENV 中的變數
  2. 您從程式碼中移除了資料庫密碼,因此安全性有所提升

您現在可以將新的修訂版本部署至 Cloud Run。讓我們跳到使用者介面,手動設定環境變數:

  • 前往 https://console.cloud.google.com/run
  • 按一下應用程式
  • 按一下「編輯及部署新的修訂版本」
  • 在第一個「容器」分頁中,按一下下方的「變數與密鑰」分頁
  • 按一下「+ 新增變數」,然後新增所有必要的變數。最終畫面應如下所示:

7a5fbfa448544d3.png

f2780c35585388ca.png

這樣就沒問題了嗎?不會,大部分的電信業者仍能看到你的票證。您可以使用 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」(安全性) 服務,並在「資料保護」部分下方找到這個選項 (如下方螢幕截圖所示)。

6df83a1c3cb757f6.png

請按照下圖所示,在該頁面中啟用 Secret Manager API。

a96c312e2c098db1.png

  • 接著按一下「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」,並使用最新版本。

9ed4e35be7654dcb.png

完成後,您應該會收到下列錯誤

da0ccd7af39b04ed.png

嘗試瞭解如何修正問題。如要解決這個問題,您必須前往「IAM 與管理員」專區,變更授予的權限。祝您偵錯愉快!

解決問題後,請返回 Cloud Run 並重新部署新修訂版本。結果應如下圖所示:

e89f9ca780169b6b.png

提示:開發人員控制台 (UI) 可指出權限問題。請花點時間瀏覽雲端實體的所有連結!

7. 單元 5:使用 Cloud Build 設定 CI/CD

ba49b033c11be94c.png

為何要使用 CI/CD 管道?

到目前為止,您應該已經輸入 gcloud run deploy 幾次,也許還反覆回答同一個問題。

您是否厭倦了使用 gcloud run deploy 手動部署應用程式?如果每次將新的變更推送至 Git 存放區時,應用程式都能自動部署,那不是很棒嗎?

如要使用 CI/CD 管道,您需要具備下列兩項條件:

  1. 個人 Git 存放區:幸運的是,您應該已在步驟 2 中將工作坊存放區分支至 GitHub 帳戶。如果不能,請返回上一步完成該步驟。分支的存放區應如下所示:https://github.com/<YOUR_GITHUB_USER>/app-mod-workshop
  2. Cloud Build。這項服務價格實惠,且功能強大,價格實惠,可讓您為幾乎所有項目設定建構自動化作業,包括 Terraform、Docker 應用程式等。

本節的重點在於設定 Cloud Build。

歡迎使用 Cloud Build!

我們將使用 Cloud Build 執行以下操作:

  • 使用 Dockerfile 建構來源。您可以將這個檔案視為「大型 .zip 檔案」,其中包含建構及執行這個檔案所需的所有內容 (也就是「建構構件」)。
  • 將這個構件推送至 Artifact Registry (AR)。
  • 然後針對應用程式「php-amarcord」發出從 AR 到 Cloud Run 的部署作業
  • 這麼做會建立現有應用程式的新版本 (「修訂版」) (請想像一個含有新程式碼的層),如果推送成功,我們會將其設為將流量轉送至新版本。

以下是部分 php-amarcord 應用程式版本的範例:

f30f42d4571ad5e2.png

我們如何做到這一點?

  1. 製作一個完美的 YAML 檔案:cloudbuild.yaml
  2. 建立 Cloud Build 觸發條件。
  3. 透過 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),然後按照操作說明操作。
  • 23e0e0f1219afea3.png按一下「連線」
  • bafd904ec07122d2.png
  • 沒錯!您的存放區現已連結。
  • 回到「觸發條件」部分。
  • 設定:自動偵測 (*)
  • 進階:選取服務帳戶「[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
  • 並勾選「設為偏好的服務帳戶」

8715acca72286a46.png

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」>「觸發條件」>「執行」)

97acd16980a144ab.png

請注意,使用這個解決方案後,您仍需完成一些工作。例如,必須為新建立的開發/實際工作環境端點設定 ENV 變數:

3da8723e4ff80c0a.png

您可以透過兩種方法來選擇刊登位置:

  • 透過 UI - 再次設定 ENV 變數
  • 透過 CLI 為您編寫「完美」的腳本。如需範例,請參閱 gcloud-run-deploy.sh。您必須調整一些內容,例如端點和專案編號;您可以在 Cloud 總覽中找到專案編號。

如何將程式碼提交至 GitHub?

本講習課程不涵蓋將 git push 提交至 GitHub 的最佳方法。不過,如果您在 Cloud Shell 中遇到問題,可以透過以下兩種方式解決:

  1. CLI。在本機新增 SSH 金鑰,並使用 git@github.com:YOUR_USER/app-mod-workshop.git (而非 http) 新增遠端存放區
  2. VSCode。如果您使用 Cloud Shell 編輯器,可以使用「來源控制項」(ctrl-shift-G) 分頁,按一下「同步處理變更」,然後按照操作說明進行操作。您應能驗證 GitHub 帳戶以對抗對抗程式碼,而其提取/推送變得輕而易舉。

f0d53f839c7fa3b6.png

請記得使用其他檔案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

a680e0f287dd2dfb.png

儲存空間

目前應用程式會將狀態儲存在 Docker 容器中。如果機器損壞、應用程式發生爆炸,或是您推送新修訂版本,系統會安排新的儲存空間重設 (=> 清空)。🙈

該如何修正?有多種方法。

  1. 將圖片儲存在資料庫中。我先前在 PHP 應用程式中採用的就是這種做法。這是最簡單的解決方案,因為不會增加複雜性。但這麼做肯定會增加資料庫的延遲和負載!
  2. 將 Cloud Run 應用程式遷移至儲存空間友善的解決方案:GCE + 永久磁碟?或許是 GKE + 儲存空間
  3. 移至 GCS。Google Cloud Storage 是整體 Google Cloud 中最優質的儲存空間,也是最雲端慣用的解決方案。但必須要透過 PHP 程式庫取得不利。我們是否有 適用於 GCS 的 PHP 5.7 程式庫PHP 5.7 是否支援 Composer (Composer 支援的PHP 最早版本為 5.3.2)?
  4. 或許可以使用 docker sidecar
  5. 或是使用 GCS Cloud Run 磁碟區掛接。聽起來很棒。

🤔 遷移儲存空間 (開放式)

[開放式問題] 在本練習中,我們希望使用者能找到方法,讓圖片移動時能維持某種程度。

驗收測試

我不想告訴你解決方案,但我希望發生以下情況:

  1. 你上傳了 newpic.jpg,您可以在應用程式中查看。
  2. 將應用程式升級至新版本。
  3. newpic.jpg 仍在其中,可供查看。

💡 可能的解決方案 (GCS Cloud Run 掛載磁碟空間)

這是非常優雅的解決方案,可讓我們在不觸及程式碼的情況下,完成有狀態檔案上傳作業 (除了顯示圖片說明,但這項操作很簡單,只是為了讓畫面看起來更美觀)。

這應該能讓您將資料夾從 Cloud Run 掛接到 GCS,因此:

  1. 所有上傳至 GCS 的內容都會顯示在應用程式中。
  2. 應用程式收到的所有上傳內容都會上傳至 GCS
  3. 上傳至 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 達成相同目的

  1. 在「磁碟區」分頁下方,建立指向值區的磁碟區掛載點,類型為「Cloud Storage 值區」,例如名稱為「php_uploads」。
  2. 在「容器」>「磁碟區掛接」下,您剛剛在應用程式要求的磁碟區點上掛接了您建立的磁碟區。磁碟取決於 dockerfile,但可能看起來像 var/www/html/uploads/

無論如何,如果運作正常,編輯新的 Cloud Run 修訂版本時,畫面應會顯示類似下列的畫面:

6c2bb98fc1b0e077.png

接下來,請測試新應用程式是否能將一張新圖片上傳至 /upload.php 端點。

圖片應可在 GCS 上流暢傳輸,不必編寫任何 PHP 程式碼:

70032b216afee2d7.png

發生什麼事了?

發生了非常神奇的事情。

含有舊程式碼的舊應用程式仍在執行工作,有了全新的現代化堆疊,我們就能輕鬆將應用程式中的所有圖片/相片放在具狀態的 Cloud 值區中。你現在可以盡情發揮:

  • 如要每次偵測到含有「危險」或「裸露」圖片時都傳送電子郵件,您可以不必修改 PHP 程式碼即可執行這項操作。
  • 您是否想在每次收到圖片時,使用 Gemini 多模態模型來描述圖片,並上傳含有說明的資料庫?您可以不修改 PHP 程式碼就完成這項操作。你不相信我嗎?請繼續閱讀第 7 章。

我們剛剛開啟了一個大好的商機。

9. 單元 7:運用 Google Gemini 強化應用程式

c00425f0ad83b32c.png

現在,您有了雲端化儲存空間,打造出全新且優質的新 PHP 應用程式 (例如 2024 年的 Fiat 126)。

你可以如何運用?

必要條件

在上一章中,我們使用了模型解決方案,在 GCS 上掛載圖片 /uploads/實際上將應用程式邏輯與圖片儲存空間分開。

這項練習要求您:

  • 已順利完成第 6 章 (儲存空間) 的練習。
  • 建立 GCS 值區來處理圖片上傳作業,讓使用者在應用程式上傳相片,並將相片流入您的值區。

設定 Cloud 函式 (在 Python 中)

您是否曾想過如何實作事件驅動應用程式?例如:

  • &lt;event&gt; 發生 => 傳送電子郵件時
  • 發生 <event> 時 => 如果 <condition> 為 true,則更新資料庫。

事件可以是任何內容,例如 BigQuery 中的新記錄、GCS 資料夾中有新物件已變更,或是 Pub/Sub 佇列中的新訊息。

Google Cloud 支援多種模式來達成這項目標。最值得注意的是:

在本練習中,我們將深入探討 Cloud 函式,以取得相當出色的結果。我們會提供額外的練習題。

請注意,程式碼範例位於 .solutions/ 下方

設定 Cloud 函式 (🐍 python)

我們正致力於打造一項雄心勃勃的 GCF。

  1. 在 GCS 中建立新映像檔時。(也許有人透過應用程式上傳了該內容,但不只是)
  2. .. 呼叫 Gemini 來描述圖片,並取得圖片的文字說明 .. (建議檢查 MIME 並確認圖片不是 PDF、MP3 或文字)
  3. .. 並更新含有此說明的資料庫。(這可能需要修補資料庫,才能將 description 欄新增至 images 資料表)。

修補資料庫以將 description 新增至映像檔

  1. 開啟 Cloud SQL Studio:

b92b07c4cba658ef.png

  1. 輸入圖片資料庫的使用者和密碼
  2. 請插入以下 SQL,為圖片說明新增資料欄:

ALTER TABLE images ADD COLUMN description TEXT;

3691aced78a6389.png

binggo!請立即嘗試看看是否有效:

SELECT * FROM images;

您應該會看到新的說明欄:

bed69d6ad0263114.png

編寫 Gemini f(x)

注意:這個函式實際上是使用 Gemini Code Assist 輔助功能建立。

注意:建立這個函式時,可能會發生 IAM 權限錯誤。其中一些錯誤已在下方「可能的錯誤」段落中列出。

  1. 啟用 API
  2. 前往 https://console.cloud.google.com/functions/list
  3. 按一下「建立函式」
  4. 透過 API 精靈啟用 API:

d22b82658cfd4c48.png

您可以透過使用者介面或指令列建立 GCF。我們會使用指令列。

您可以在 .solutions/ 下方找到可能的程式碼

  1. 建立資料夾來託管程式碼,例如「gcf/」。進入資料夾。
  2. 建立 requirements.txt 檔案:
google-cloud-storage
google-cloud-aiplatform
pymysql
  1. 建立 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
  1. 推送函式。您可以使用類似以下的指令碼: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 (我最喜歡的)、VariablesTriggerLogs。您會花費大量時間在 Logs 中排解錯誤 (請參閱本頁底部的可能錯誤)。此外,請務必檢查 Permissions

cf3ded30d532a2c7.png

E2E 測試

是時候手動測試函式了!

  1. 前往應用程式並登入
  2. 上傳圖片 (請勿上傳過大的圖片,我們曾遇到大型圖片的問題)
  3. 然後在使用者介面上查看相片上傳完成
  4. Cloud SQL Studio 中確認說明已更新。登入並執行這項查詢:SELECT * FROM images

43a680b12dbbdda0.png

而且真的有效!我們也許也想更新前端,以便顯示該說明。

更新 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 版本。經過美化後的版本可能會像這樣:

fdc12de0c88c4464.png

結論

您會在 GCS 上收到新物件觸發的 Cloud Function,該函式可像人類一樣標註圖片內容,並自動更新資料庫。太厲害了!

接下來,您可以按照相同的推理方式,實現兩項絕佳功能。

[選用] 新增其他 Cloud Functions [不限]

還有一些其他功能。

📩 電子郵件觸發條件

電子郵件觸發條件,會在每次有人傳送圖片時傳送電子郵件給您。

  • 頻率過高?加入其他限制條件:大圖片,或 Gemini 內容含有「裸露/裸露/暴力」字詞的圖片。
  • 請考慮使用 EventArc 來執行這項操作。

🚫? 自動審核不當圖片

目前,人工管理員會將圖片標示為「不當」。想讓 Gemini 代勞並審核空間嗎?新增測試,標示不當的觸發內容並更新資料庫,就像我們在先前的函式中所學到的一樣。這表示您基本上會使用先前的函式、變更提示,並根據答案更新資料庫。

注意事項:生成式 AI 的輸出內容無法預測。請確認 Gemini 的「廣告素材輸出」已「上線」。你可以透過多種方式提出確定性答案,例如 0 到 1 的可信度分數、JSON 等。你可以透過多種方式達成這個目標,例如:* 使用 Python 程式庫 pydanticlangchain、.. * 使用 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 權限問題。我會將這些資訊新增到這裡,以便你瞭解情況,並提供一些解決方法。

錯誤:服務帳戶權限不足

  1. 請注意,如要部署監聽 GCS 值區的 GCF 函式,您必須針對要用於工作的服務帳戶設定適當權限,如下圖所示:

22f51012fa6b4a24.png

您可能還需要啟用 EventArc API,這可能需要幾分鐘的時間才能完全啟用。

錯誤:缺少 Cloud Run 叫用器

  1. 另一個 GCF 權限 UI 的註解如下 ( Cloud Run 叫用者角色):

be72e17294f2d3f3.png

您可以執行圖像中的指令來修正這項錯誤,這類似於 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。在使用者介面中,這項操作非常簡單。可能的突出:

bed69d6ad0263114.png

您也可以修正 Cloud Run 部署指令碼,以達到高用量的 MEM/CPU。這需要較長的時間。

錯誤:PubSub 已發布

使用 GCF 1.0 建立觸發條件時,會出現以下錯誤:

e5c338ee35ad4c24.png

同樣地,您可以前往 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,最簡單的方法如下:

  1. https://console.cloud.google.com/vertex-ai
  2. 按一下「啟用所有建議的 API」。

492f05ac377f3630.png

錯誤:找不到 EventArc 觸發條件。

如果收到這則訊息,請重新部署函式。

8ec4fc11833d7420.png

錯誤:正在為 400 個服務代理程式進行佈建

正在佈建 400 個服務代理 ( https://cloud.google.com/vertex-ai/docs/general/access-control#service-agents),需要服務代理才能讀取您提供的 Cloud Storage 檔案。請過幾分鐘後再試一次。

如果發生這種情況,請稍待片刻或向 Google 員工尋求協助。

10. 單元 8:建立可用性服務等級目標

本章節的目標如下:

  1. 建立 SLI
  2. 根據 SLI 建立服務等級目標
  3. 根據服務等級目標建立快訊

f63426182c052123.png

這對作者來說是個相當親切的話題,因為 Riccardo 任職於 Google Cloud 的 SRE / 開發運作領域。

(開放式) 建立這個應用程式的 SLI 和服務等級目標

如果無法得知應用程式何時發生問題,那麼應用程式還算好用嗎?

什麼是 SLO?

喔,Google 發明瞭服務等級目標!如要進一步瞭解這項功能,建議您:

步驟 1:建立可用性 SLI/SLO

首先從可用性服務等級目標著手,這是最簡單且最需要評估的要素。

幸運的是,Cloud Run 已預先內建 SLO 支援功能,這要歸功於 Istio

您的應用程式在 Cloud Run 中運作後,整個過程非常簡單,我只需要 30 秒就能完成。

  • 前往 Cloud Run 頁面。
  • 按一下/選取應用程式。
  • 選取「SLOs」分頁。
  • 按一下「+ 建立 SLO」。
  • 供應情形 (以要求為依據)
  • 繼續
  • 日曆月份 / 99%。
  • 按一下「建立 SLO」。

e471c7ebdc56cdf6.png

步驟 2:為這項 SLO 設定警示

建議建立 2 個快訊:

  1. 一個消耗率低的帳戶 (「Slowburn」),透過電子郵件通知您 (模擬低優先順序的支援單)。
  2. 一個具有高耗損率 (「Fastburn」) 的票據,可透過簡訊發出警報 (模擬高優先順序票據 / 尋呼機)

前往先前的 SLO tab

重複上述動作:

314bfd6b9ef0a260.png

  • 按一下「建立服務水準目標快訊」(右側有加號的 🔔? 按鈕)
  • 回溯時間長度、消耗率門檻:
  • [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 有兩種用途:

  1. Vertex AI。我們在第 7 章 (GCF + Gemini) 中介紹了「企業方式」,這與 GCP 密切相關。所有驗證都能正常運作,服務之間也能完美連結。
  2. 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 的回覆非常完美 (也就是說,我不需要做任何變更):

8a3d5fe37ec40bf8.png

以下是作者個人應用程式中的新版面配置:

81620eb90ae3229a.png

注意:我們將程式碼貼上為圖片,因為我們不鼓勵您採用程式碼,而是建議您使用 Gemini 為您編寫程式碼,並套用您自己的廣告素材 UI/前端限制。請放心,您之後只需進行非常少量的變更。

安全性

這個 4 小時工作坊的目標並非要讓您瞭解如何妥善保護這個應用程式。

如需相關靈感,請參閱 SECURITY doc

12. 恭喜!

恭喜🎉?🎉?🎉?,您已成功使用 Google Cloud 改良舊版 PHP 應用程式。

24cb9a39b1841fbd.png

以下是本程式碼研究室的重點摘要:

  • 如何在 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 致敬,感謝協助撰寫及測試解決方案。