Nginx を使用したフロントエンド プロキシ

このページでは、NGINX をアプリケーション コンテナのフロントエンド プロキシとして使用する方法について説明します。これは、リクエストやレスポンスを処理する場合に便利です。アプリケーション コンテナが HTTP/1 のみをサポートしており、パフォーマンス上の理由でエンドツーエンドで HTTP/2 を使用する必要がある場合は、gzip 圧縮を追加するか、HTTP/2 を HTTP/1 に変換できます。

このページの例では、Nginx コンテナがすべての Cloud Run インスタンス上で、メインのサービング コンテナとして実行され、アプリケーション コンテナにリクエストを転送するように構成されています。この図のように、サイドカー コンテナとして動作します。

Cloud Run mc hello nginx 1

Cloud Run でフロントエンド プロキシを効果的に行うためには、Nginx サーバー プロキシ サーバー コンテナとウェブアプリ コンテナを単一の Cloud Run サービスとしてデプロイします。

Cloud Run mc hello nginx 2

この単一の Cloud Run サービスは、リクエストを受け入れ、Ingress(サービング)コンテナ(この場合はプロキシ サーバー)に配信します。次に、プロキシ サーバーは、localhost ネットワーク インターフェースを介してウェブアプリにリクエストを送信します。これにより、外部ネットワークを回避できます。

単一の Cloud Run サービスとしてデプロイすることでレイテンシとサービス管理のオーバーヘッドが削減され、外部ネットワークへの露出がなくなります。なお、Cloud Run は、サービスの開始時または停止時にサイドカー コンテナを起動または停止する場合を除き、サイドカー コンテナを直接操作しません。

ウェブアプリ コンテナやすべてのサイドカー コンテナは、さまざまなプログラミング言語で記述できます。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. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  3. Google Cloud プロジェクトで課金が有効になっていることを確認します

  4. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  5. Google Cloud プロジェクトで課金が有効になっていることを確認します

  6. Cloud Run and Secret Manager API を有効にします。

    API を有効にする

  7. gcloud CLI をインストールして初期化します
  8. gcloud components update で Google Cloud CLI を更新します。
  9. gcloud init で Google Cloud CLI を構成します。
  10. gcloud auth login を使用して Google Cloud CLI で認証を行います。

デプロイに必要な権限

次のいずれかが必要です。

  • オーナー
  • 編集者
  • Cloud Run 管理者ロールとサービス アカウント ユーザー ロールの両方
  • この権限のリストを含むカスタムロール

構成の概要

以下の手順では事前にビルドされたコンテナ イメージを使用するため、フロントエンド プロキシに必要な作業はコンテナとサービス自体の構成だけです。

Nginx Ingress コンテナを構成する

コンテナ イメージは nginx で、Docker Hub で入手できます。ほぼそのままで使用できますが、プロキシ サービスとして実行するように構成し、サイドカー コンテナが localhost でリッスンするポートにプロキシ リクエストを配信する必要があります。このページの例では、リクエストとレスポンスで gzip 圧縮も有効になっています。

この構成は、/etc/nginx/conf.d/nginx.conf にマウントされたテキスト ファイルを使用して提供されます。コンテナ内のファイルは直接編集できないため、構成ファイルを含む /etc/nginx/conf.d/ にボリュームをマウントする必要があります。Cloud Run で実行されているコンテナ内の特定の場所にファイルをマウントする方法の 1 つは、ファイルの内容を 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;
    }
}

構成で、次の操作を行います。

  • localhost にある同じ Cloud Run デフォルト ポート 8080 をリッスンするように nginx を割り当てます。
  • gzip 圧縮を適用してパフォーマンスを高めます。
  • proxy_pass を介して、この Ingress コンテナへのリクエストをウェブアプリ サイドカー コンテナ(localhost ポート 8888)に配信するように指示します。

nginx.conf ファイルの内容に基づいてシークレットを作成します。

コンソール

  1. Google Cloud コンソールの [Secret Manager] ページに移動します。

    Secret Manager に移動

  2. [シークレットを作成] をクリックします。

  3. name フォーム フィールドに「nginx_config」と入力します。

  4. multi-container/hello-nginx-sample/nginx.conf にある nginx.conf ファイルをシークレット値としてアップロードします。

  5. デフォルト(Google-managed encryption key, etc)のままにします。

  6. [シークレットを作成] をクリックします。

  7. プロジェクトのコンピューティング サービス アカウントに、この新しいシークレットへのアクセス権を付与します。これを行うには、Google Cloud コンソールの [IAM] ページに移動します。

    [IAM] に移動

  8. Compute Engine default service account という名前のプリンシパル サービス アカウントを見つけて、[プリンシパルの編集] をクリックします。

  9. [別のロールを追加] をクリックし、[Secret Manager のシークレット アクセサー] を選択します。

  10. [保存] をクリックします。

コマンドライン

  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 プロキシ サーバーを Ingress(サービング)コンテナとして指定し、リッスンするポート、HTTP 1 リクエストまたは HTTP 2 リクエストを受け入れるかどうか、コンテナの開始順序を指定します。Ingress コンテナ(プロキシ サーバー)はウェブアプリ サイドカーに依存するため、ウェブアプリ サイドカーを最初に開始する必要があります。

これらの構成について、以降のセクションで説明します。

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 アノテーションが、nginx コンテナを起動する前に hello コンテナの起動を待つように Cloud Run に指示している点に注意してください。これを行わずに nginx コンテナが最初に起動した場合、準備ができていないウェブアプリ コンテナにウェブ リクエストをプロキシしようとし、ウェブエラー レスポンスが生成されます。

各コンテナには、他のディレクティブでも参照できる name プロパティを任意で定義できます。サービング コンテナは nginx というプロキシ サーバーを実行します。このコンテナは、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. [既存のコンテナ イメージから 1 つのリビジョンをデプロイする] を選択し、[コンテナ イメージの URL] に「nginx」と入力します。
    2. [サービス名] フィールドに、サービスの名前(例: hello-mc)を入力します。
    3. [リージョン] リストから、デプロイ先のロケーション(us-west1 など)を選択します。
    4. [認証] で [Allow unauthenticated invocations] を選択します。
  3. [コンテナ、ボリューム、ネットワーキング、セキュリティ] をクリックして、構成フォームを開きます。

    1. [ボリューム] タブをクリックします。
    2. [ボリュームを追加] をクリックします。
    3. [ボリュームのタイプ] リストから、[シークレット] を選択します。
    4. [ボリューム名] フィールドに「nginx-conf-secret」と入力します。
    5. [シークレット] フィールドに「nginx_config」と入力します。
    6. [シークレット バージョンに指定されているパス] で、パスとして default.conf を指定し、バージョンとして latest を指定します。
    7. [作成] をクリックして、シークレット ボリュームを作成します。
  4. [コンテナ] タブをクリックして、[コンテナの編集] フォームを表示します。

    1. [設定] をクリックし、[リソース] でメモリを 256MiB に、CPU を 1 CPU に変更します。
    2. [ボリュームのマウント] をクリックします。
    3. [ボリュームをマウント] をクリックします。
    4. 名前のリストから nginx-conf-secret を選択します。
    5. [マウントパス] に「etc/nginx/conf.d」と入力します。
    6. [完了] をクリックして、最初のコンテナの構成を完了します。
  5. [コンテナを追加] をクリックしてサイドカー コンテナを追加し、[新しいコンテナ] フォームを表示します。

    1. デフォルトのコンテナ イメージ URL us-docker.pkg.dev/cloudrun/container/hello を選択します。
    2. [設定] タブをクリックし、[リソース] で、メモリを 256MiB に、CPU を 1 CPU に変更します。
    3. [変数とシークレット] をクリックします。
    4. [変数を追加] をクリックします。
    5. 新しい環境変数名として「PORT」と入力し、値として「8888」と入力します。
    6. [完了] をクリックします。
  6. 最初のコンテナ(nginx)の [コンテナの編集] フォームに移動します。

    1. [設定] タブをクリックします。
    2. [コンテナの起動順序] で、[以下のコンテナに依存] リストから nginx を選択します。nginx コンテナは、hello コンテナが正常に起動した後にのみ起動します。
    3. [作成] をクリックし、サービスがデプロイされるのを待ちます。

コマンドライン

プロキシ サーバー コンテナとウェブアプリ コンテナを単一のサービスとしてデプロイするには、以下を行います。

gcloud run services replace service.yaml

デプロイされたサービスを確認する

コマンドライン

デプロイが成功したことを確認するには、生成された Cloud Run URL をコピーしてブラウザで開くか、次のコマンドを使用して認証済みリクエストを送信します。

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

レスポンス ステータスに、200 の hello サイドカー コンテナに正常に移行された nginx プロキシが示されます。

試してみる

このチュートリアルの手順は次のとおりです。

コマンドライン

  1. ターミナルで、ローカルマシンにサンプルアプリ リポジトリのクローンを作成します。

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

  2. Cloud Run のサンプルコードが含まれているディレクトリに移動します。

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

次のステップ

Cloud Run サービスでサイドカーを使用する方法の詳細については、以下をご覧ください。