コンテナ化されたウェブ アプリケーションのデプロイ


このチュートリアルでは、ウェブ アプリケーションを Docker コンテナ イメージにパッケージ化し、そのコンテナ イメージを Google Kubernetes Engine(GKE)クラスタで実行する方法について説明します。ウェブ アプリケーションは、ユーザーのニーズに合わせてスケーリングできる負荷分散されたレプリカのセットとしてデプロイします。

目標

  • サンプル ウェブ アプリケーションを Docker イメージにパッケージ化する。
  • Docker イメージを Artifact Registry にアップロードする。
  • GKE クラスタを作成する。
  • サンプルアプリをクラスタにデプロイする。
  • デプロイの自動スケーリングを管理する。
  • サンプルアプリをインターネットに公開する。
  • サンプルアプリの新しいバージョンをデプロイする。

料金

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

  1. Google Cloud アカウントにログインします。Google Cloud を初めて使用する場合は、アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

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

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

  4. Compute Engine, Artifact Registry, and Google Kubernetes Engine API を有効にします。

    API を有効にする

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

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

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

  7. Compute Engine, Artifact Registry, and Google Kubernetes Engine API を有効にします。

    API を有効にする

Cloud Shell をアクティブにする

Cloud Shell には、このチュートリアルで使用する gclouddockerkubectl コマンドライン ツールがプリインストールされています。

  1. Google Cloud コンソールに移動します。
  2. Google Cloud コンソール ウィンドウの上部にある「Cloud Shell をアクティブにする」ボタン Shell をアクティブにするボタン をクリックします。

    Google Cloud コンソールの一番下にある新しいフレームの中で Cloud Shell セッションが開き、コマンドライン プロンプトが表示されます。

    Cloud Shell セッション

リポジトリを作成する

このチュートリアルでは、Artifact Registry にイメージを保存し、そのイメージをレジストリからデプロイします。このクイックスタートでは、hello-repo という名前のリポジトリを作成します。

  1. 環境変数 PROJECT_IDGoogle Cloud プロジェクト IDPROJECT_ID)を設定します。この環境変数は、コンテナ イメージをビルドしてリポジトリに push するときに使用します。

    export PROJECT_ID=PROJECT_ID
    
  2. PROJECT_ID 環境変数の値が正しいことを確認します。

    echo $PROJECT_ID
    
  3. Google Cloud CLI のプロジェクト ID を設定します。

    gcloud config set project $PROJECT_ID
    

    出力:

    Updated property [core/project].
    
  4. 次のコマンドを使用して hello-repo リポジトリを作成します。

    gcloud artifacts repositories create hello-repo \
       --repository-format=docker \
       --location=REGION \
       --description="Docker repository"
    

    REGION は、リポジトリのリージョン(us-west1 など)で置き換えます。使用可能なロケーションのリストを表示するには、次のコマンドを実行します。

     gcloud artifacts locations list
    

コンテナ イメージのビルド

このチュートリアルでは、hello-app という名前のサンプル ウェブ アプリケーションをデプロイします。このウェブ アプリケーションは Go で作成されたウェブサーバーで、ポート 8080 のすべてのリクエストに対して「Hello, World!」というメッセージを返します。

GKE は、Docker イメージをアプリケーション デプロイ形式として受け入れます。hello-app を GKE にデプロイする前に、hello-app ソースコードを Docker イメージとしてパッケージ化する必要があります。

Docker イメージを作成するには、ソースコードと Dockerfile が必要です。Dockerfile には、イメージの作成方法に関する手順が含まれています。

  1. 次のコマンドを実行して、hello-app ソースコードと Dockerfile をダウンロードします。

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/quickstarts/hello-app
    
  2. hello-app の Docker イメージをビルドしてタグ付けします。

    docker build -t REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1 .
    

    このコマンドを実行すると、Docker は現在のディレクトリにある Dockerfile を使用してイメージをビルドし、ローカル環境に保存します。また、us-west1-docker.pkg.dev/my-project/hello-repo/hello-app:v1 などの名前を使用してイメージにタグを設定します。次のセクションで、このイメージを Artifact Registry に push します。

    • PROJECT_ID 変数は、コンテナ イメージを Google Cloud プロジェクトの hello-repo リポジトリに関連付けます。
    • us-west1-docker.pkg.dev 接頭辞は、リポジトリのリージョン ホストである Artifact Registry を表します。
  3. docker images コマンドを実行して、ビルドが成功したことを確認します。

    docker images
    

    出力:

    REPOSITORY                                                 TAG     IMAGE ID       CREATED          SIZE
    us-west1-docker.pkg.dev/my-project/hello-repo/hello-app    v1      25cfadb1bf28   10 seconds ago   54 MB
    
  4. サービス アカウントに IAM ポリシー バインディングを追加します。

    gcloud artifacts repositories add-iam-policy-binding hello-repo \
        --location=REGION \
        --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \
        --role="roles/artifactregistry.reader"
    

    PROJECT_NUMBER は、プロジェクトのプロジェクト番号に置き換えます。

コンテナをローカルで実行する(省略可)

  1. ローカル Docker エンジンを使用してコンテナ イメージをテストします。

    docker run --rm -p 8080:8080 REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1
    
  2. [ウェブでプレビュー] ボタン [ウェブでプレビュー] ボタン をクリックしてから、8080 ポート番号を選択します。GKE でプロキシ サービスのプレビュー用 URL が新しいブラウザ ウィンドウで開きます。

Docker イメージを Artifact Registry に push します。

GKE クラスタがコンテナ イメージをダウンロードして実行できるように、コンテナ イメージをレジストリにアップロードする必要があります。このチュートリアルでは、コンテナを Artifact Registry に保存します。

  1. Docker コマンドライン ツールから Artifact Registry への認証を構成します。

    gcloud auth configure-docker REGION-docker.pkg.dev
    
  2. ビルドした Docker イメージをリポジトリに push します。

    docker push REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1
    

GKE クラスタの作成

Docker イメージが Artifact Registry に保存されたので、GKE クラスタを作成して hello-app を実行します。GKE クラスタは Kubernetes(GKE を強化するオープンソースのクラスタ オーケストレーション システム)を実行している Compute Engine VM インスタンスのプールで構成されます。

Cloud Shell

  1. Compute Engine のリージョンを設定します。

     gcloud config set compute/region REGION
    

    Standard ゾーンクラスタの場合は、Artifact Registry リポジトリに最も近い Compute Engine ゾーンを設定します。

  2. hello-cluster という名前のクラスタを作成します。

     gcloud container clusters create-auto hello-cluster
    

    GKE クラスタの作成とヘルスチェックには数分を要します。このチュートリアルを GKE Standard クラスタで実行するには、代わりに gcloud container clusters create コマンドを使用します。

コンソール

  1. Google Cloud コンソールで Google Kubernetes Engine のページに移動します。

    Google Kubernetes Engine に移動

  2. [ 作成] をクリックします。

  3. [GKE Autopilot] で [構成] をクリックします。

  4. [名前] フィールドに、名前「hello-cluster」を入力します。

  5. [リージョン] プルダウン リストから us-west1 などの Compute Engine リージョンを選択します。

  6. [作成] をクリックします。

  7. クラスタが作成されるまで待ちます。クラスタの準備ができると、クラスタ名の横にチェックマークが表示されます。

サンプルアプリを GKE にデプロイする

これで、ビルドした Docker イメージを GKE クラスタにデプロイする準備が整いました。

Kubernetes ではアプリケーションを Pod として表します。Pod とは、1 つ以上のコンテナを保有するスケーラブルなユニットのことです。Pod は、Kubernetes でデプロイ可能な最小単位です。通常は、Pod をレプリカのセットとしてデプロイし、クラスタ全体で一緒にスケーリングと分散を行えます。レプリカのセットをデプロイする 1 つの方法は、Kubernetes の Deployment を使用することです。

このセクションでは、クラスタで hello-app を実行する Kubernetes Deployment を作成します。この Deployment にはレプリカ(Pod)があります。1 つの Deployment Pod には 1 つのコンテナ(ここでは hello-app Docker イメージ)のみが含まれます。また、CPU 負荷に基づいて、Pod の数を 3 から 1~5 の数値にスケーリングする HorizontalPodAutoscaler リソースを作成します。

Cloud Shell

  1. GKE クラスタに接続していることを確認します。

    gcloud container clusters get-credentials hello-cluster --region REGION
    
  2. hello-app Docker イメージの Kubernetes Deployment を作成します。

    kubectl create deployment hello-app --image=REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1
    
  3. Deployment レプリカのベースライン数を 3 に設定します。

    kubectl scale deployment hello-app --replicas=3
    
  4. Deployment の HorizontalPodAutoscaler リソースを作成します。

    kubectl autoscale deployment hello-app --cpu-percent=80 --min=1 --max=5
    
  5. 作成した Pod を表示するには、次のコマンドを実行します。

    kubectl get pods
    

    出力:

    NAME                         READY   STATUS    RESTARTS   AGE
    hello-app-784d7569bc-hgmpx   1/1     Running   0          90s
    hello-app-784d7569bc-jfkz5   1/1     Running   0          90s
    hello-app-784d7569bc-mnrrl   1/1     Running   0          95s
    

コンソール

  1. Google Cloud コンソールの [ワークロード] ページに移動します。

    [ワークロード] に移動

  2. [ デプロイ] をクリックします。

  3. [コンテナの指定] セクションで、[既存のコンテナ イメージ] を選択します。

  4. [イメージパス] フィールドで [選択] をクリックします。

  5. [コンテナ イメージの選択] ペインで、Artifact Registry に push した hello-app イメージを選択して、[選択] をクリックします。

  6. [コンテナ] セクションで、[完了] をクリックしてから、[続行] をクリックします。

  7. [構成] セクションの [ラベル] で、[キー] に app、[] に hello-app を入力します。

  8. [構成 YAML] で、[YAML を表示] をクリックします。これにより、クラスタにデプロイしようとしている 2 つの Kubernetes API リソース(1 つの Deployment とその Deployment の 1 つの HorizontalPodAutoscaler)を定義する YAML 構成ファイルが開きます。

  9. [閉じる] をクリックし、[デプロイ] をクリックします。

  10. Deployment Pod の準備が整うと、[デプロイの詳細] ページが開きます。

  11. [マネージド Pod] で、hello-app Deployment の 3 つの実行中の Pod をメモします。

サンプルアプリをインターネットに公開する

Pod には個別に割り当てられた IP アドレスがありますが、これらの IP にはクラスタ内からしかアクセスできません。また、GKE Pod はエフェメラルで、スケーリングの必要性に応じて開始または停止するように設計されています。また、エラーのために Pod がクラッシュした場合、GKE でその Pod が自動的に再デプロイされ、新しい Pod IP アドレスが割り当てられます。

つまり、どの Deployment でも、アクティブな Pod のセットに対応する IP アドレスのセットが動的になります。1)Pod を 1 つの静的ホスト名にグループ化し、2)Pod のグループをクラスタ外のインターネット上に公開する方法が必要です。

Kubernetes Service で、この両方の問題を解決します。Service により、クラスタ内の任意の Pod から到達可能な 1 つの静的 IP アドレスに Pod がグループ化されます。また、GKE はその静的 IP に DNS ホスト名を割り当てます。例: hello-app.default.svc.cluster.local

GKE のデフォルトの Service タイプは ClusterIP で、クラスタ内からのみ到達可能な IP アドレスを取得します。クラスタ外部に Kubernetes Service を公開するには、タイプ LoadBalancer の Service を作成します。このタイプの Service では、インターネット経由で到達可能な一連の Pod の外部ロードバランサ IP が生成されます。

このセクションでは、LoadBalancer タイプの Service を使用して hello-app Deployment をインターネットに公開します。

Cloud Shell

  1. kubectl expose コマンドを使用して、hello-app デプロイ用の Kubernetes Service を生成します。

    kubectl expose deployment hello-app --name=hello-app-service --type=LoadBalancer --port 80 --target-port 8080
    

    ここで、--port フラグはロードバランサ上で構成されたポート番号を指定し、--target-port フラグは hello-app コンテナがリッスンするポート番号を指定します。

  2. 次のコマンドを実行して、hello-app-service の Service の詳細を取得します。

    kubectl get service
    

    出力:

    NAME                 CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
    hello-app-service    10.3.251.122    203.0.113.0     80:30877/TCP     10s
    
  3. EXTERNAL_IP アドレスをクリップボードにコピーします(例: 203.0.113.0)。

コンソール

  1. Google Cloud コンソールの [ワークロード] ページに移動します。

    [ワークロード] に移動

  2. hello-app をクリックします。

  3. [デプロイの詳細] ページで [アクション] > [公開] の順にクリックします。

  4. [公開] ダイアログで、[ターゲット ポート] を 8080 に設定します。これは、hello-app コンテナがリッスンするポートです。

  5. [Service のタイプ] プルダウン リストから、[ロードバランサ] を選択します。

  6. [公開] をクリックして、hello-app の Kubernetes Service を作成します。

  7. ロードバランサの準備が整うと、[サービスの詳細] ページが開きます。

  8. [外部エンドポイント] フィールドまでスクロールし、IP アドレスをコピーします。

これで hello-app Pod が Kubernetes Service を介してインターネットに公開されたので、新しいブラウザタブを開き、クリップボードにコピーした Service の IP アドレスに移動します。Hello, World! メッセージと Hostname フィールドが表示されます。Hostname は、HTTP リクエストをブラウザに提供する 3 つの hello-app Pod のいずれかに対応します。

サンプルアプリの新しいバージョンをデプロイする

このセクションでは、新しい Docker イメージをビルドして GKE クラスタにデプロイし、hello-app を新しいバージョンにアップグレードします。

GKE のローリング アップデート機能を使用すると、ダウンタイムなしで Deployment を更新できます。ローリング アップデート中に、GKE クラスタによって既存の hello-app Pod が、新しいバージョンの Docker イメージを含む Pod に段階的に置き換えられます。このアップデート中、ロードバランサ サービスは使用可能な Pod にのみトラフィックをルーティングします。

  1. hello アプリのソースコードと Dockerfile のクローンを作成した Cloud Shell に戻ります。main.go ファイルの関数 hello() を更新して、新しいバージョン 2.0.0 を報告します。

  2. 新しい hello-app Docker イメージをビルドしてタグを付けます。

    docker build -t REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2 .
    
  3. イメージを Artifact Registry に push します。

    docker push REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2
    

これで、新しい Docker イメージを使用するように hello-app Kubernetes Deployment を更新する準備が整いました。

Cloud Shell

  1. kubectl set image コマンドを使用して、イメージを更新して既存の hello-app Deployment にローリング アップデートを適用します。

    kubectl set image deployment/hello-app hello-app=REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2
    
  2. v1 イメージを実行している実行中の Pod が停止し、v2 イメージを実行している新しい Pod が起動するのを確認します。

    watch kubectl get pods
    

    出力:

    NAME                        READY   STATUS    RESTARTS   AGE
    hello-app-89dc45f48-5bzqp   1/1     Running   0          2m42s
    hello-app-89dc45f48-scm66   1/1     Running   0          2m40s
    
  3. 別のタブで、hello-app-service 外部 IP に再度移動します。Version2.0.0. に設定されています。

コンソール

  1. Google Cloud コンソールの [ワークロード] ページに移動します。

    [ワークロード] に移動

  2. hello-app をクリックします。

  3. [デプロイの詳細] ページで、 [アクション] > [ローリング アップデート] の順にクリックします。

  4. [ローリング アップデート] ダイアログで、[Image of hello-app] フィールドを REGION-docker.pkg.dev/PROJECT_ID/hello-repo/hello-app:v2 に設定します。

  5. [更新] をクリックします。

  6. [デプロイの詳細] ページで、[アクティブなリビジョン] セクションを確認します。1 と 2 の 2 つのリビジョンが表示されます。リビジョン 1 は、以前に作成した最初の Deployment に対応します。リビジョン 2 は、開始したばかりのローリング アップデートです。

  7. しばらくしてからページを更新します。[マネージド Pod] で、hello-app のすべてのレプリカがリビジョン 2 に対応します。

  8. 別のタブで、コピーした Service IP アドレスにもう一度移動します。Version2.0.0. になっているはずです。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

  1. Service を削除する: Service に作成した Cloud Load Balancer の割り当てを解除します。

    kubectl delete service hello-app-service
    
  2. クラスタを削除する: クラスタを構成するリソース(コンピューティング インスタンス、ディスク、ネットワーク リソースなど)を削除します。

    gcloud container clusters delete hello-cluster --region REGION
    
  3. コンテナ イメージを削除する: Artifact Registry に push した Docker イメージを削除します。

    gcloud artifacts docker images delete \
        REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1 \
        --delete-tags --quiet
    gcloud artifacts docker images delete \
        REGION-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v2 \
        --delete-tags --quiet
    

次のステップ

使ってみる

Google Cloud を初めて使用する場合は、アカウントを作成して、実際のシナリオで GKE のパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。

GKE の無料トライアル