学習プログラム: スケーラブルなアプリケーション - クラスタを作成する

このチュートリアルは、Google Kubernetes Engine(GKE)で実行される最新のアプリケーション環境をデプロイ、実行、管理することを目的とする IT 管理者とオペレーターを対象としています。このチュートリアルでは、Cymbal Bank サンプル マイクロサービス アプリケーションを使用して、モニタリングとアラートの構成、ワークロードのスケーリング、障害のシミュレーションの方法を学習します。

  1. クラスタを作成し、サンプル アプリケーションをデプロイする(このチュートリアル)
  2. Google Cloud Managed Service for Prometheus でモニタリングする
  3. ワークロードをスケーリングする
  4. 障害をシミュレートする
  5. チェンジ マネジメントを一元化する

概要と目的

Cymbal Bank は、Python と Java を使用してさまざまなサービスを実行し、PostgreSQL バックエンドを備えています。Cymbal Bank は、GKE がビジネスのニーズをどのようにサポートできるかを示したサンプル アプリケーションであるため、これらの言語やデータベース プラットフォームの経験がなくても、一連のチュートリアルを完了できます。

このチュートリアルでは、単一の GKE クラスタを作成し、Cymbal Bank という名前のマイクロサービス ベースのサンプル アプリケーションを GKE クラスタにデプロイする方法を学習します。次のタスクを完了する方法を学習します。

  • Autopilot を使用する GKE クラスタを作成します。

  • Cymbal Bank という名前のマイクロサービス ベースのサンプル アプリケーションをデプロイします。

  • Google Cloud コンソールを使用して、Cymbal Bank サンプル アプリケーションで使用される GKE リソースを確認します。

クラスタの作成

前のセクションのすべての前提条件の手順が完了したら、GKE クラスタの作成とサンプル アプリケーションのデプロイを開始できます。

GKE は、コンテナ化されたアプリケーションのデプロイと運用に使用できるマネージド Kubernetes サービスです。GKE 環境はノードで構成されます。ノードは Compute Engine 仮想マシン(VM)であり、グループ化されてクラスタを形成します。

  • このシリーズの残りのチュートリアルで使用する GKE クラスタを作成します。

    gcloud container clusters create-auto scalable-apps \
      --project=PROJECT_ID \
      --location=CONTROL_PLANE_LOCATION
    

    次のように置き換えます。

    • PROJECT_ID は、前のセクションで作成したプロジェクトの自動生成された ID に置き換えます。プロジェクト ID は、多くの場合、プロジェクト名とは異なります。たとえば、プロジェクト名は scalable-apps で、プロジェクト ID は scalable-apps-567123 となります。
    • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンの Compute Engine の リージョン。リージョンを指定します(us-central1 など)。

    クラスタを作成して、すべてが正しく動作することを確認するまで数分ほどかかります。

このチュートリアルでは、クラスタを作成するときに Autopilot モードのクラスタとデフォルトの IP アドレス範囲を使用します。独自のアプリケーションの本番環境のデプロイでは、IP アドレスを慎重に計画する必要があります。Autopilot モードでは、自動スケーリング、セキュリティなどの事前構成済みの設定を含むクラスタの構成が Google によって管理されます。Autopilot モードのクラスタは、ほとんどの本番環境ワークロードを実行するように最適化されており、Kubernetes マニフェストに基づいてコンピューティング リソースをプロビジョニングします。

Cymbal Bank をデプロイする

アプリ(ワークロードとも呼ばれます)をコンテナにパッケージ化します。コンテナのセットを Pod としてノードにデプロイします。

このチュートリアル シリーズでは、Cymbal Bank という名前のマイクロサービス ベースのサンプル アプリケーションを 1 つ以上の GKE クラスタにデプロイします。Cymbal Bank は、Python と Java を使用してさまざまなサービスを実行し、PostgreSQL バックエンドを備えています。これらの言語やデータベース プラットフォームの経験がなくても、一連のチュートリアルを完了できます。Cymbal Bank は、GKE がビジネスのニーズをどのようにサポートできるかを示したサンプル アプリケーションにすぎません。

このチュートリアル セットの一部として Cymbal Bank を使用すると、次のサービスが GKE クラスタにデプロイされます。

サービス 言語 説明
frontend Python ウェブサイトを提供するための HTTP サーバーを公開します。ログインページ、登録ページ、ホームページが含まれています。
ledger-writer Java 受信トランザクションを受け入れて妥当性を確認した後、台帳に書き込みます。
balance-reader Java ledger-db から読み取られたユーザーの残高を効率的に読み取るためのキャッシュを提供します。
transaction-history Java ledger-db から読み取られた過去のトランザクションを効率的に読み取りためのキャッシュを提供します。
ledger-db PostgreSQL すべてのトランザクションの台帳。デモユーザーのトランザクションを事前入力するオプション。
user-service Python ユーザー アカウントと認証を管理します。他のサービスによる認証に使用される JWT に署名します。
contacts Python ユーザーに関連付けられている他のアカウントのリストを保存します。[Send Payment] フォームと [Deposit] フォームのプルダウンに使用されます。
accounts-db PostgreSQL ユーザー アカウントと関連データ用のデータベース。デモユーザーを事前入力するオプション。
loadgenerator Python / Locust ユーザーを模倣したリクエストをフロントエンドに継続的に送信します。定期的に新しいアカウントを作成し、それらのアカウント間のトランザクションをシミュレートします。

Cymbal Bank を GKE クラスタにデプロイする手順は次のとおりです。

  1. Cymbal Bank は、JSON Web Token(JWT)を使用してユーザー認証を処理します。JWT は、非対称鍵ペアを使用してトークンに署名して検証します。Cymbal Bank では、userservice がユーザーのログイン時に RSA 秘密鍵を使用してトークンを作成して署名し、他のサービスが対応する公開鍵を使用してユーザーを検証します。

    4,096 ビットの強度の RS256 JWT を作成します。

    openssl genrsa -out jwtRS256.key 4096
    openssl rsa -in jwtRS256.key -outform PEM -pubout -out jwtRS256.key.pub
    

    必要に応じて、プラットフォーム用の OpenSSL ツールをダウンロードしてインストールします。

  2. Kubernetes Secret には、鍵やパスワードなどのセンシティブ データを保存できます。クラスタで実行されるワークロードは、アプリケーションにセンシティブ データをハードコードする代わりに、Secret にアクセスしてセンシティブ データを取得できます。

    認証リクエストで Cymbal Bank が使用できるように、前の手順で作成した鍵ファイルから Kubernetes Secret を作成します。

    kubectl create secret generic jwt-key --from-file=./jwtRS256.key --from-file=./jwtRS256.key.pub
    
  3. Cymbal Bank をクラスタにデプロイします。次のコマンドでは、kubernetes-manifests ディレクトリ内のすべてのマニフェスト ファイルをデプロイします。各マニフェスト ファイルは、次のいずれかのサービスを実装して構成します。

    kubectl apply -f kubernetes-manifests/accounts-db.yaml
    kubectl apply -f kubernetes-manifests/balance-reader.yaml
    kubectl apply -f kubernetes-manifests/config.yaml
    kubectl apply -f kubernetes-manifests/contacts.yaml
    kubectl apply -f extras/postgres-hpa/kubernetes-manifests/frontend.yaml
    kubectl apply -f kubernetes-manifests/ledger-db.yaml
    kubectl apply -f kubernetes-manifests/ledger-writer.yaml
    kubectl apply -f extras/postgres-hpa/loadgenerator.yaml
    kubectl apply -f kubernetes-manifests/transaction-history.yaml
    kubectl apply -f kubernetes-manifests/userservice.yaml
    

    マニフェストが Autopilot の制限についてクラスタに適用されると、kubectl 出力にメッセージが表示されることがあります。Autopilot は、ワークロード構成に指定したリソース リクエストを使用して、ワークロードを実行するノードを構成します。Autopilot は、ワークロードが使用するコンピューティング クラスまたはハードウェア構成に基づいて、リソースの最小リクエストと最大リクエストを適用します。一部のコンテナのリクエストを指定していない場合、Autopilot は、コンテナが正常に実行されるようにデフォルト値を割り当てます。

    frontend Service 用の次のサンプル マニフェストを確認します。

    # Copyright 2024 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #     https://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        application: bank-of-anthos
        environment: development
        team: frontend
        tier: web
      name: frontend
    spec:
      ports:
        - name: http
          port: 80
          targetPort: 8080
      selector:
        app: frontend
        application: bank-of-anthos
        environment: development
        team: frontend
        tier: web
      type: LoadBalancer
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        application: bank-of-anthos
        environment: development
        team: frontend
        tier: web
      name: frontend
    spec:
      selector:
        matchLabels:
          app: frontend
          application: bank-of-anthos
          environment: development
          team: frontend
          tier: web
      template:
        metadata:
          annotations:
            proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
          labels:
            app: frontend
            application: bank-of-anthos
            environment: development
            team: frontend
            tier: web
        spec:
          containers:
            - env:
                - name: VERSION
                  value: v0.6.7
                - name: PORT
                  value: "8080"
                - name: ENABLE_TRACING
                  value: "true"
                - name: SCHEME
                  value: http
                - name: LOG_LEVEL
                  value: info
                - name: DEFAULT_USERNAME
                  valueFrom:
                    configMapKeyRef:
                      key: DEMO_LOGIN_USERNAME
                      name: demo-data-config
                - name: DEFAULT_PASSWORD
                  valueFrom:
                    configMapKeyRef:
                      key: DEMO_LOGIN_PASSWORD
                      name: demo-data-config
                - name: REGISTERED_OAUTH_CLIENT_ID
                  valueFrom:
                    configMapKeyRef:
                      key: DEMO_OAUTH_CLIENT_ID
                      name: oauth-config
                      optional: true
                - name: ALLOWED_OAUTH_REDIRECT_URI
                  valueFrom:
                    configMapKeyRef:
                      key: DEMO_OAUTH_REDIRECT_URI
                      name: oauth-config
                      optional: true
              envFrom:
                - configMapRef:
                    name: environment-config
                - configMapRef:
                    name: service-api-config
              image: us-central1-docker.pkg.dev/bank-of-anthos-ci/bank-of-anthos/frontend:v0.6.7@sha256:6d92f3ce81a389738baf236477c6795831a0802c7a007697d7121f10eab9a2cc
              livenessProbe:
                httpGet:
                  path: /ready
                  port: 8080
                initialDelaySeconds: 60
                periodSeconds: 15
                timeoutSeconds: 30
              name: front
              readinessProbe:
                httpGet:
                  path: /ready
                  port: 8080
                initialDelaySeconds: 10
                periodSeconds: 5
                timeoutSeconds: 10
              resources:
                limits:
                  cpu: 250m
                  memory: 128Mi
                requests:
                  cpu: 100m
                  memory: 64Mi
              securityContext:
                allowPrivilegeEscalation: false
                capabilities:
                  drop:
                    - all
                privileged: false
                readOnlyRootFilesystem: true
              volumeMounts:
                - mountPath: /tmp
                  name: tmp
                - mountPath: /tmp/.ssh
                  name: publickey
                  readOnly: true
          securityContext:
            fsGroup: 1000
            runAsGroup: 1000
            runAsNonRoot: true
            runAsUser: 1000
          serviceAccountName: bank-of-anthos
          terminationGracePeriodSeconds: 5
          volumes:
            - emptyDir: {}
              name: tmp
            - name: publickey
              secret:
                items:
                  - key: jwtRS256.key.pub
                    path: publickey
                secretName: jwt-key

    frontend Service のこのマニフェストは、CPU の 100m64Mi をリクエストし、CPU の 250m と Pod あたりの 128Mi の上限を設定します。

    Autopilot クラスタにワークロードをデプロイすると、選択したコンピューティング クラスまたはハードウェア構成(GPU など)で許容される最小値と最大値に対してワークロード構成が GKE により検証されます。リクエストが最小値未満の場合は、Autopilot がワークロード構成を自動的に変更し、リクエストが許容範囲に収まるようにします。これらのメッセージは、適切な上限が自動的に割り当てられていることを示しています。

  4. Pod の準備が整うまで待ちます。kubectl を使用して Pod のステータスを確認します。

    kubectl get pods
    

    STATUS 列が Pending から ContainerCreating に変更されます。次の出力例に示すように、すべての Pod が Running 状態になるまで数分かかります。

    NAME                                  READY   STATUS    RESTARTS   AGE
    accounts-db-6f589464bc-6r7b7          1/1     Running   0          99s
    balancereader-797bf6d7c5-8xvp6        1/1     Running   0          99s
    contacts-769c4fb556-25pg2             1/1     Running   0          98s
    frontend-7c96b54f6b-zkdbz             1/1     Running   0          98s
    ledger-db-5b78474d4f-p6xcb            1/1     Running   0          98s
    ledgerwriter-84bf44b95d-65mqf         1/1     Running   0          97s
    loadgenerator-559667b6ff-4zsvb        1/1     Running   0          97s
    transactionhistory-5569754896-z94cn   1/1     Running   0          97s
    userservice-78dc876bff-pdhtl          1/1     Running   0          96s
    

    すべての Pod が Running 状態になったら、次のステップに進みます。繰り返しになりますが、すべての Pod が Running 状態になるまでには数分ほどかかります。Cymbal Bank がトラフィックを正しく処理できるようになるまで、一部の Pod が READY ステータスを 0/1 と報告するのは正常です。

  5. frontend サービスは、Cymbal Bank のウェブサイト(ログインページ、登録ページ、ホームページを含む)を提供するための HTTP サーバーを公開します。Ingress オブジェクトは、 Google Cloud HTTP(S) ロードバランサを使用してクラスタで実行されているアプリケーションに HTTP(S) トラフィックをルーティングするルールを定義します。

    frontend Ingress の外部 IP アドレスを取得します。

    kubectl get ingress frontend | awk '{print $4}'
    
  6. ウェブブラウザ ウィンドウで、kubectl get ingress コマンドの出力に表示された IP アドレスを開き、Cymbal Bank のインスタンスへのアクセスを開始します。

    デフォルトの認証情報が自動的に入力されます。アプリにログインして、サンプルの取引と残高を確認できます。Cymbal Bank が正常に実行されていることを確認する以外に、特別な操作は必要ありません。すべてのサービスが正しく通信してログインできるようになるまでに 1~2 分かかることがあります。

デプロイを確認する

GKE クラスタを作成してワークロードをデプロイした後、設定の変更やアプリケーションのパフォーマンスの確認を行う必要があります。このセクションでは、 Google Cloud コンソールを使用して、クラスタと Cymbal Bank サンプル アプリケーションに含まれるリソースを確認する方法について説明します。

クラスタ

このチュートリアルでは、GKE クラスタを 1 つ作成し、Cymbal Bank ワークロードをデプロイしました。

  1. Google Cloud コンソールの [Google Kubernetes Engine] ページで、[クラスタ] ページに移動します。

    [クラスタ] ページに移動

  2. 新しくデプロイされた scalable-apps クラスタをクリックします。表示されたクラスタの詳細ページで、クラスタの基本情報と、クラスタのネットワーク構成とセキュリティ構成を確認できます。このクラスタでどの GKE 機能が有効になっているかは、[機能] セクションで確認できます。

オブザーバビリティ

クラスタの健全性とパフォーマンスに関する基本的な指標を表示できます。このシリーズの次のチュートリアルでは、よりきめ細かいモニタリングとオブザーバビリティを実現するために、Google Cloud Managed Service for Prometheus を有効にします。

  1. Google Cloud コンソールの Google Kubernetes Engine の [クラスタ] ページでクラスタを選択し、[オブザーバビリティ] タブに移動します。

  2. CPU やメモリなどの指標グラフィックをいくつか調べます。このビューを使用すると、追加のモニタリング機能をデプロイすることなく、クラスタ ワークロードのさまざまな部分のパフォーマンスをモニタリングできます。

  3. クラスタからストリーミングされたログを表示するには、[ログ] タブを選択します。ログの重大度でフィルタすることも、独自のフィルタを作成して、特定の名前空間、Service、Pod を表示することもできます。Pod の警告やイベントと同様に、クラスタからのログを集計して表示することで、 Google Cloud コンソールで問題を迅速にデバッグできます。

    一部のサービスがまだ通信できないときに Cymbal Bank が最初にデプロイされるため、ログエントリが表示されるのは正常です。

  4. [アプリのエラー] タブを選択します。ワークロードの実行中に、 Google Cloud コンソールで収集された警告とイベントを表示できます。このアプローチを使用すると、クラスタ、ノード、Pod に個別に接続することなく、問題のデバッグを行うことができます。

    繰り返しになりますが、一部のサービスがまだ通信できないときに、Cymbal Bank が最初にデプロイされたときにイベントがログに記録されるのは正常です。

ワークロード

Google Cloud コンソールの GKE ページの [ワークロード] セクションには、すべての GKE クラスタで実行されているワークロードの集計ビューが表示されます。

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

    [ワークロード] ページに移動

    [概要] タブには、GKE クラスタのワークロードと Namespace のリストが表示されます。Namespace でフィルタして、各 Namespace で実行されているワークロードを確認できます。

Service と Ingress

[Services と Ingress] ビューには、プロジェクトの Service リソースと Ingress リソースが表示されます。Service では一連の Pod がエンドポイントでネットワーク サービスとして公開され、Ingress ではクラスタ内の Service への外部アクセスが管理されます。

  1. Google Cloud コンソールの [Google Kubernetes Engine] ページで、[Gateway、Service、Ingress] ページに移動します。

    [Gateway、Service、Ingress] ページに移動

  2. Cymbal Bank Ingress を見つけるには、[Ingress] タブをクリックし、frontend という名前の Ingress を探します。Ingress は、アプリケーションのインバウンド トラフィックを管理します。ロードバランサ、ポート、外部エンドポイントに関する情報を表示できます。

  3. frontend Ingress の IP アドレス(198.51.100.143:80 など)をクリックします。このアドレスでは、Cymbal Bank のウェブ インターフェースが表示されます。