使用 Nginx 進行前端 Proxy

本頁說明如何將 Nginx 做為應用程式容器的前端 Proxy。如果您想處理要求或回應,這項功能就非常實用。您可以新增 gzip 壓縮,或將 HTTP/2 轉譯為 HTTP/1 (如果應用程式容器僅支援 HTTP/1,且您基於效能考量需要端對端使用 HTTP/2)。

在本頁提供的範例中,Nginx 容器會在每個 Cloud Run 執行個體上執行,做為主要服務容器,並設定為將要求轉送至以邊車容器形式執行的應用程式容器,如以下圖表所示:

Cloud Run mc hello nginx 1

在 Cloud Run 中執行前端 Proxy 最有效的方式,是將 Nginx 伺服器 Proxy 伺服器容器和網頁應用程式容器,部署為單一 Cloud Run 服務:

Cloud Run mc hello nginx 2

這個單一 Cloud Run 服務會接受要求,並將要求傳送至 Ingress (服務) 容器,在本例中為 Proxy 伺服器。接著,Proxy 伺服器會透過 localhost 網路介面將要求傳送至網頁應用程式,避免使用任何外部網路。

以單一 Cloud Run 服務的形式部署,可減少延遲、服務管理負擔,並避免暴露於外部網路。除了在服務啟動或停止時啟動或停止側車容器外,Cloud Run 不會直接與側車容器互動。

網頁應用程式容器和任何附屬容器都可以使用不同的程式設計語言編寫。如需以 PHP 編寫的範例,請參閱 GitHub 的 PHP nginx 範例

事前準備

  1. 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 the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

  3. 啟用 Cloud Run 和 Secret Manager API。

    啟用 API 時所需的角色

    如要啟用 API,您必須具備 serviceusage.services.enable 權限。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

    啟用 API

  4. 安裝並初始化 gcloud CLI
  5. 更新 Google Cloud CLI:gcloud components update
  6. 設定 Google Cloud CLI:gcloud init
  7. 使用 Google Cloud CLI 進行驗證:gcloud auth login

部署時需要的權限

您必須具備下列其中一項:

  • 「Cloud Run 管理員」和「服務帳戶使用者」角色
  • 包含特定權限清單的任何自訂角色

設定總覽

這些操作說明使用預先建構的容器映像檔,因此前端 Proxy 只需要設定容器和服務本身。

設定 Nginx 輸入容器

容器映像檔nginx 可在 Docker Hub 取得。 除了需要設定為 Proxy 服務,並將 Proxy 要求傳送至邊車容器接聽的通訊埠 localhost 外,這個容器大多可直接使用。本頁面的範例也會為要求和回應啟用 gzip 壓縮。

設定是透過掛接在 /etc/nginx/conf.d/nginx.conf 的文字檔提供。由於您無法直接編輯容器中的檔案,因此必須在 /etc/nginx/conf.d/ 掛接包含設定檔的磁碟區。如要在 Cloud Run 上執行的容器中,將檔案掛接至特定位置,其中一種方法是將檔案內容儲存在 Secret Manager Secret 中,然後將該 Secret 掛接至所選位置。

將下列內容複製到本機電腦目前目錄中名為 nginx.conf 的檔案。


server {
    # Listen at port 8080
    listen 8080; 
    # Server at localhost
    server_name _;
    # Enables gzip compression to make our app faster
    gzip on;

    location / {
        # Passes initial requests to port 8080 to `hello` container at port 8888
        proxy_pass   http://127.0.0.1:8888;
    }
}

在設定中,執行下列操作:

  • 指派 nginx 在相同的 Cloud Run 預設通訊埠 8080 (位於 localhost) 監聽。
  • 套用 gzip 壓縮,提升效能。
  • 指示 proxy_pass 將所有對這個 Ingress 容器的要求,傳送至本機通訊埠 8888 的網頁應用程式邊車容器。

使用 nginx.conf 檔案的內容建立 Secret。

控制台

  1. 前往 Google Cloud 控制台的「Secret Manager」頁面:

    前往 Secret Manager

  2. 點選「建立密鑰」

  3. name 表單欄位中,輸入 nginx_config

  4. 上傳位於 multi-container/hello-nginx-sample/nginx.confnginx.conf 檔案做為密鑰值。

  5. 保留預設值 (Google-owned and Google-managed encryption key, etc)。

  6. 點選「建立密鑰」

  7. 將這個新密鑰的存取權授予專案運算服務帳戶。如要執行這項操作,請前往 Google Cloud 控制台的「IAM」頁面:

    前往「IAM」頁面

  8. 找出主體服務帳戶 (名稱為 Compute Engine default service account),然後按一下「編輯主體」

  9. 按一下「Add another role」(新增其他角色),然後選取「Secret Manager Secret Accessor」(Secret Manager 密鑰存取者)

  10. 按一下 [儲存]

gcloud

  1. 在終端機中,使用下列指令在 Secret Manager 中建立新的 nginx_config 密鑰:

    gcloud secrets create nginx_config --replication-policy='automatic' --data-file='./nginx.conf'

  2. 使用下列指令,將這個新密鑰的存取權授予專案運算服務帳戶:

    export PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')
    gcloud secrets add-iam-policy-binding nginx_config --member=serviceAccount:$PROJECT_NUMBER-compute@ --role='roles/secretmanager.secretAccessor'

  3. 執行 gcloud secrets list,確認密鑰是否已建立。

關於網頁應用程式 Sidecar 範例圖片

這些操作說明使用 us-docker.pkg.dev/cloudrun/container/hello 的範例容器映像檔。您需要指定容器要監聽的通訊埠編號,並將 localhost 設為主機,詳情請參閱「指定邊車容器設定」一節。

設定多容器服務

您可以使用 Google Cloud 控制台或 Cloud Run YAML 檔案,設定具有多個容器的 Cloud Run 服務。

在服務設定中,將 Nginx Proxy 伺服器指定為輸入 (服務) 容器、要接聽的通訊埠、是否接受 HTTP 1 或 HTTP 2 要求,以及容器啟動順序。Ingress 容器 (Proxy 伺服器) 依附於網頁應用程式 Sidecar,因此必須先啟動網頁應用程式 Sidecar。

接下來幾節將說明這些設定。

新增 YAML 中繼資料

控制台

如需完整的控制台操作說明,請參閱「部署服務」。

YAML

  1. 如要建立新服務,請略過這個步驟。 如要更新現有服務,請下載其 YAML 設定

    gcloud run services describe SERVICE --format export > service.yaml
  2. service.yaml 中新增下列內容:

    metadata:
      name: "MC_SERVICE_NAME"
      labels:
        cloud.googleapis.com/location: "REGION"
      annotations:
        # Required to use Cloud Run multi-containers (preview feature)
        run.googleapis.com/launch-stage: BETA
        run.googleapis.com/description: sample tutorial service
        # Externally available
        run.googleapis.com/ingress: all

本節說明服務的修訂版本,包括可能因修訂版本而異的屬性。

指定容器啟動順序

控制台

如需完整的控制台操作說明,請參閱「部署服務」。

YAML

service.yaml 中附加下列內容:

spec:
  template:
    metadata:
      annotations:
        # Defines container startup order within multi-container service.
        # Below requires hello container to spin up before nginx container,
        # which depends on the hello container.
        # https://cloud.google.com/run/docs/configuring/containers#container-ordering
        run.googleapis.com/container-dependencies: "{nginx: [hello]}"

請注意 container-dependencies 註解,這個註解會告知 Cloud Run 等待 hello 容器啟動,再啟動 nginx 容器。否則,如果 nginx 容器先啟動,可能會嘗試將網頁要求 Proxy 至尚未準備就緒的網頁應用程式容器,進而產生網路錯誤回應。

每個容器都可以選擇定義名稱屬性,以便在其他指令中參照。服務容器會執行名為 nginx 的 Proxy 伺服器。Cloud Run 會將傳入要求傳送至這個容器,因此您必須指定 HTTP 版本和容器通訊埠,以便傳送要求。

指定供應容器設定

控制台

如需完整的控制台操作說明,請參閱「部署服務」。

YAML

service.yaml 檔案中,附加下列內容:

spec:
  containers:
    # A) Serving ingress container "nginx" listening at PORT 8080
    # Main entrypoint of multi-container service.
    # Source is stored in nginx_config secret in Secret Manager.
    # Any pings to this container will proxy over to hello container at PORT 8888.
    # https://cloud.google.com/run/docs/container-contract#port
    - image: nginx
      name: nginx
      ports:
        - name: http1
          containerPort: 8080
      resources:
        limits:
          cpu: 500m
          memory: 256Mi
      # Referencing declared volume below,
      # Declaring volume to mount in current ingress container's filesystem
      # https://cloud.google.com/run/docs/reference/rest/v2/Container#volumemount
      volumeMounts:
        - name: nginx-conf-secret
          readOnly: true
          mountPath: /etc/nginx/conf.d/
      startupProbe:
        timeoutSeconds: 240
        periodSeconds: 240
        failureThreshold: 1
        tcpSocket:
          port: 8080

nginx 伺服器需要 /etc/nginx/conf.d/ 目錄中的設定檔。如要這麼做,請在該位置掛接含有檔案的磁碟區。volumeMount 區段會指定要放置在該處的磁碟區,名為 configuration。磁碟區本身會在檔案稍後的專屬區段中定義。

指定邊車容器設定

控制台

如需完整的控制台操作說明,請參閱「部署服務」。

YAML

service.yaml 中附加下列內容:

- image: us-docker.pkg.dev/cloudrun/container/hello
  name: hello
  env:
    - name: PORT
      value: "8888"
  resources:
    limits:
      cpu: 1000m
      memory: 512Mi
  startupProbe:
    timeoutSeconds: 240
    periodSeconds: 240
    failureThreshold: 1
    tcpSocket:
      port: 8888

hello 應用程式也需要設定資訊。並在 PORT 環境變數指定的通訊埠監聽傳入要求。該名稱和值是在 env 區段中指定。

指定密鑰磁碟區

控制台

如需完整的控制台操作說明,請參閱「部署服務」。

YAML

service.yaml 檔案中,附加下列內容:

volumes:
  - name: nginx-conf-secret
    secret:
      secretName: nginx_config
      items:
        - key: latest
          path: default.conf

volumeMount 區段中指定已掛接的設定 volume。內含名為 nginx.conf 的單一檔案,其內容定義為名為 nginx-conf-secret 的密鑰值。

部署服務

控制台

  1. 前往 Google Cloud 控制台的「Cloud Run」頁面:

    前往 Cloud Run

  2. 從選單中選取「服務」,然後按一下「部署容器」,顯示「建立服務」表單。

    1. 選取「透過現有的容器映像檔部署單一修訂版本」,然後輸入 nginx 做為「容器映像檔網址」
    2. 在「Service name」(服務名稱) 欄位中,提供服務名稱,例如 hello-mc
    3. 從「Region」(區域) 清單中,選取要部署的目標位置,例如「us-west1」。
    4. 在「Authentication」(驗證) 下方,選取「Allow public access」(允許公開存取)。 如果沒有權限 (Cloud Run 管理員角色) 可選取這個選項,服務會部署並要求驗證。
  3. 按一下「Containers, Networking, Security」(容器、網路、安全性),展開設定表單。

    1. 按一下「Volumes」(磁碟區) 分頁標籤。
    2. 按一下「新增磁碟區」
    3. 在「Volume type」清單中選取「Secret」
    4. 在「Volume name」(磁碟區名稱) 欄位中輸入 nginx-conf-secret
    5. 在「Secret」欄位中輸入「nginx_config」
    6. 在「密鑰版本的指定路徑」下方,將路徑指定為 default.conf,版本指定為 latest
    7. 按一下「建立」來建立密鑰磁碟區。
  4. 按一下「容器」分頁標籤,顯示「編輯容器」表單。

    1. 按一下「設定」,然後在「資源」下方,將記憶體變更為「256MiB」,CPU 變更為「1 CPU」
    2. 按一下「Volume mounts」(磁碟區掛接)
    3. 按一下「掛接磁碟區」
    4. 從名稱清單中選取「nginx-conf-secret」
    5. 在「掛接路徑」中輸入 etc/nginx/conf.d
    6. 按一下「完成」,完成第一個容器的設定。
  5. 按一下「新增容器」,新增 Sidecar 容器並顯示「新增容器」表單。

    1. 選取預設容器映像檔網址 us-docker.pkg.dev/cloudrun/container/hello
    2. 按一下「設定」分頁,然後在「資源」下方,將記憶體變更為「256MiB」,CPU 變更為「1 CPU」
    3. 按一下「變數與密鑰」
    4. 按一下「新增變數」
    5. 輸入 PORT 做為新的環境變數名稱,並輸入 8888 做為值。
    6. 按一下「完成」
  6. 前往第一個容器的「編輯容器」表單 (nginx)。

    1. 按一下 [設定] 標籤。
    2. 在「Container start up order」(容器啟動順序) 下方,從「Depends on」(依據) 清單中選取 nginx。也就是說,只有在 hello 容器成功啟動後,nginx 容器才會啟動。
    3. 按一下「建立」,然後等待服務部署完成。

YAML

如要將 Proxy 伺服器容器和網頁應用程式容器部署為單一服務,請按照下列步驟操作:

gcloud run services replace service.yaml

驗證部署的服務

如要確認部署是否成功,請複製產生的 Cloud Run 網址並在瀏覽器中開啟,或使用下列指令傳送已驗證的要求:

curl --header "Authorization: Bearer $(gcloud auth print-identity-token)" SERVICE_URL

您應該會看到 nginx Proxy,該 Proxy 已成功移植至 hello 邊車容器,並顯示 200 回應狀態。

親自試試

如要跟著本教學課程操作,請先完成下列事項:

gcloud

  1. 在終端機中,將範例應用程式存放區複製到本機電腦:

    git clone https://github.com/GoogleCloudPlatform/cloud-run-samples

  2. 變更為包含 Cloud Run 程式碼範例的目錄:

    cd cloud-run-samples/multi-container/hello-nginx-sample/

後續步驟

如要進一步瞭解如何在 Cloud Run 服務中使用 Sidecar,請參閱: