使用 Nginx 進行前端 Proxy

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

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

Cloud Run mc hello nginx 1

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

Cloud Run mc hello nginx 2

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

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

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

事前準備

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the Cloud Run and Secret Manager APIs.

    Enable the APIs

  7. 安裝並初始化 gcloud CLI
  8. 更新 Google Cloud CLI:gcloud components update
  9. 設定 Google Cloud CLI:gcloud init
  10. 使用 Google Cloud CLI 進行驗證:gcloud auth login
  11. 部署時需要的權限

    您必須具備下列任一條件:

    • 同時具備 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 機密中,然後在所選位置掛載該機密。

    在本機電腦的目前目錄中,將以下內容複製到名為 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 以聆聽位於 localhost 的相同 Cloud Run 預設通訊埠 8080
    • 套用 gzip 壓縮功能來提升效能。
    • 指示 proxy_pass 將任何對此 ingress 容器的要求,傳送至 localhost 通訊埠 8888 的網路應用程式附屬容器。

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

    控制台

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

      前往 Secret Manager

    2. 按一下「Create secret」

    3. name 表單欄位中輸入 nginx_config

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

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

    6. 按一下「Create secret」

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

      前往「IAM」頁面

    8. 找出名稱為 Compute Engine default service account 的主體服務帳戶,然後按一下「Edit principal」

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

    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@developer.gserviceaccount.com --role='roles/secretmanager.secretAccessor'

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

    關於網路應用程式附加元件範例圖片

    這些操作說明會使用 us-docker.pkg.dev/cloudrun/container/hello 中的範例容器映像檔。您需要指定容器要監聽的通訊埠編號,並將 localhost 設為主機,如「指定附屬容器設定」一節所述。

    設定多容器服務

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

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

    這些設定會在接下來的幾個章節中顯示。

    新增 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 在啟動 nginx 容器之前,等待 hello 容器啟動。否則,如果 nginx 容器先啟動,可能會嘗試將網路要求代理至尚未就緒的網頁應用程式容器,進而產生網路錯誤回應。

    每個容器都可以選擇為其定義名稱屬性,用於在其他指令中參照該容器。服務容器會執行名為 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. 從選單中選取「Services」,然後按一下「Deploy container」,顯示「Create service」表單。

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

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

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

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

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

    YAML

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

    gcloud run services replace service.yaml

    驗證已部署的服務

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

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

    您應該會看到 nginx 代理程式,該代理程式已成功移植至 hello sidecar 容器,並顯示回應狀態 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,請參閱以下資源: