このチュートリアルでは、コンテナ化されたワークロードに馴染みがない方を対象に、ソースコードから GKE でのコンテナ実行までのシンプルなアプリケーションの設定手順を通して、コンテナとコンテナ オーケストレーションについて説明します。
このチュートリアルには、コンテナや Kubernetes の使用経験は必要ありません。このチュートリアルを開始する前に Kubernetes の主な用語をおおまかに確認しておくには、Kubernetes の学習を開始するをご覧ください。ご希望なら、Kubernetes を漫画で学習できる Kubernetes コミックもあります。詳細なリソースについては、チュートリアルの最後にある次のステップをご覧ください。
コンテナと Kubernetes をすでによくご存じの場合は、このチュートリアルをスキップして、GKE 自体の学習を開始できます。
サンプルコードをダウンロードする
helloserverソースコードをダウンロードします。git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samplesサンプルコードのディレクトリに移動します。
cd anthos-service-mesh-samples/docs/helloserver
マルチサービス アプリケーションを確認する
サンプル アプリケーションは Python で記述されており、REST を使用して通信する次のコンポーネントがあります。
server: 1 つのGETエンドポイント(/)を持つ基本的なサーバー。ターミナル ウィンドウに「hello world」を出力します。loadgen:serverにトラフィックを送信するスクリプト。1 秒あたりのリクエスト数(RPS)を構成できます。
ソースからアプリケーションを実行する
サンプル アプリケーションに慣れるため、Cloud Shell で実行します。
sample-apps/helloserverディレクトリからserverを実行します。python3 server/server.py起動時に、
serverには次のとおりに表示されます。INFO:root:Starting server...
別のターミナル ウィンドウを開き、
serverにリクエストを送信できるようにします。Cloud Shell でこれを行うには、 [新しいタブを開く] をクリックして別のセッションを開きます。新しいターミナル ウィンドウで、
serverにリクエストを送信します。curl http://localhost:8080serverの出力は次のとおりです。Hello World!
同じタブで、
loadgenスクリプトを含むディレクトリに移動します。cd anthos-service-mesh-samples/docs/helloserver/loadgen
次の環境変数を作成します。
export SERVER_ADDR=http://localhost:8080 export REQUESTS_PER_SECOND=5virtualenvを開始します。virtualenv --python python3 env仮想環境をアクティブにします。
source env/bin/activateloadgenの要件をインストールします。pip3 install -r requirements.txtloadgenアプリケーションを実行して、serverのトラフィックを生成します。python3 loadgen.py起動時に、
loadgenの出力は次のようになります。Starting loadgen: 2024-10-11 09:49:51.798028 5 request(s) complete to http://localhost:8080
次に、
serverを実行しているターミナル ウィンドウを開きます。次のようなメッセージが表示されます。127.0.0.1 - - [11/Oct/2024 09:51:28] "GET / HTTP/1.1" 200 - INFO:root:GET request, Path: / Headers: Host: localhost:8080 User-Agent: python-requests/2.32.3 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive
ネットワーキングの観点からは、アプリケーション全体が同じホスト上で実行されているため、
localhostを使用してserverにリクエストを送信できます。loadgenとserverを停止するには、各ターミナル ウィンドウでCtrl-cを入力します。loadgenターミナル ウィンドウで、仮想環境を無効にします。deactivate
アプリケーションをコンテナ化する
GKE でアプリケーションを実行するには、サンプル アプリケーションの両方のコンポーネントをコンテナにパッケージ化する必要があります。コンテナは、アプリケーションをどの環境でも実行できるようにするために必要なすべての要素を含むパッケージです。このチュートリアルでは、アプリケーションのコンテナ化に Docker を使用します。
Docker でアプリケーションをコンテナ化するには、Dockerfile が必要です。Dockerfile はテキスト ファイルで、アプリケーション ソースコードとその依存関係をコンテナ イメージにアセンブルするために必要なコマンドを定義します。イメージをビルドしたら、そのイメージを Artifact Registry などのコンテナ レジストリにアップロードします。
このチュートリアルのソースコードには、server と loadgen の両方の Dockerfile があり、イメージのビルドに必要なすべてのコマンドが用意されています。以下は、server 用の Dockerfile です。
このファイルでは次の内容を確認できます。
FROM python:3-slim as base命令は、最新の Python 3 イメージをベースイメージとして使用するように Docker に指示します。COPY . .命令は、現在の作業ディレクトリ(この場合はserver.py)からコンテナのファイル システムに、ソースファイルをコピーします。ENTRYPOINTは、コンテナを実行するために使用するコマンドを定義します。この例の命令は、ソースコードからのserver.pyの実行で使用した命令と似ています。EXPOSE命令は、serverがポート8080でリッスンすることを指定します。この命令はポートを公開しませんが、コンテナの実行時にポート8080を開く必要があることを示すドキュメントとして機能します。
アプリケーションのコンテナ化を準備する
アプリケーションをコンテナ化する前に、使用するツールとサービスの設定を行う必要があります。
Google Cloud CLI のデフォルト Google Cloud プロジェクトを設定します。
gcloud config set project PROJECT_ID
Google Cloud CLI のデフォルトのリージョンを設定します。
gcloud config set compute/region us-central1
リポジトリを作成する
Artifact Registry に Docker コンテナ イメージの新しいリポジトリを作成するには、次の操作を行います。
Google Cloud プロジェクトで Artifact Registry サービスが有効になっていることを確認します。
gcloud services enable artifactregistry.googleapis.comArtifact Registry リポジトリを作成します。
gcloud artifacts repositories create container-intro --repository-format=docker \ --location=us-central1 \ --description="My new Docker repository"Google Cloud CLI を使用して、Docker から Artifact Registry への認証を設定します。
gcloud auth configure-docker us-central1-docker.pkg.dev
server をコンテナ化する
次に、アプリケーションをコンテナ化します。まず、「hello world」server をコンテナ化し、イメージを Artifact Registry に push します。
サンプル
serverがあるディレクトリに移動します。cd ~/anthos-service-mesh-samples/docs/helloserver/server/
Dockerfileを使用してイメージをビルドします。docker build -t us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1 .PROJECT_IDは、 Google Cloud プロジェクトの ID に置き換えます。
-tフラグは Docker タグを表します。これは、コンテナのデプロイ時に使用するイメージの名前です。イメージを Artifact Registry に push します。
docker push us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1
loadgen をコンテナ化する
次に、同じ方法で負荷生成ツールのサービスをコンテナ化します。
サンプル
loadgenがあるディレクトリに移動します。cd ../loadgenイメージをビルドします。
docker build -t us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1 .イメージを Artifact Registry に push します。
docker push us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1
イメージのリストを表示する
リポジトリ内のイメージのリストを取得して、イメージが push されたことを確認します。
gcloud container images list --repository us-central1-docker.pkg.dev/PROJECT_ID/container-intro
出力には、push したイメージ名が次のように一覧表示されます。
NAME us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen
GKE クラスタを作成する
この時点で、docker run コマンドを使用して、Cloud Shell VM でコンテナを実行することもできます。ただし、本番環境で信頼性の高いワークロードを実行するには、より統一された方法でコンテナを管理する必要があります。たとえば、コンテナが失敗した場合に確実に再起動するようにする必要があります。また、トラフィックの増加に対応するためにスケールアップし、コンテナの追加インスタンスを起動する方法も必要です。
GKE では、これらのニーズに対処できます。GKE は、VM をクラスタに接続することで機能するコンテナ オーケストレーション プラットフォームです。各 VM はノードと呼ばれます。GKE クラスタでは、Kubernetes オープンソース クラスタ管理システムが使用されます。クラスタの操作には、Kubernetes のメカニズムが使用されます。
GKE でコンテナを実行するには、まずクラスタを作成して接続する必要があります。
クラスタを作成します。
gcloud container clusters create-auto container-intro
gcloudコマンドは、前に設定したデフォルト Google Cloud プロジェクトとリージョンにクラスタを作成します。クラスタを作成するコマンドが完了するまで数分かかります。クラスタの準備ができている場合、出力は次のようになります。
NAME: container-intro LOCATION: us-central1 MASTER_VERSION: 1.30.4-gke.1348000 MASTER_IP: 34.44.14.166 MACHINE_TYPE: e2-small NODE_VERSION: 1.30.4-gke.1348000 NUM_NODES: 3 STATUS: RUNNING
kubectlコマンドライン ツールに認証情報を提供して、クラスタの管理に使用できるようにします。gcloud container clusters get-credentials container-intro
Kubernetes マニフェストを調べる
ソースコードからアプリケーションを実行したとき、命令型コマンド python3 server.py を使用しました。
命令型とは、「これをしろ」のような動詞駆動という意味です。
対照的に、Kubernetes は宣言型モデルで動作します。つまり、Kubernetes には、実際の処理を指示するのではなく、望ましい状態を提示します。たとえば、実際のシステム状態が望ましい状態になるように、Kubernetes は必要に応じて Pod を起動または停止します。
望ましい状態は、マニフェストというファイルで指定します。マニフェストは YAML や JSON などの言語で記述され、1 つ以上の Kubernetes オブジェクトの仕様が含まれています。
このサンプルには、server と loadgen のマニフェストがそれぞれ含まれています。各マニフェストは、Kubernetes Deployment オブジェクト(Kubernetes Pod として管理用にパッケージ化されたコンテナの実行を管理する)と Service(Pod の IP アドレスを提供する)の望ましい状態を指定します。Pod は、Kubernetes で作成して管理できる、デプロイ可能なコンピューティングの最小単位であり、1 つ以上のコンテナを保持しています。
次の図は、GKE で実行されるアプリケーションを示しています。
Pod、Deployment、Service の詳細については、Kubernetes の学習を開始する、またはこのページの下部にあるリソースをご覧ください。
サーバー
まず、「hello world」server のマニフェストを確認します。
このマニフェストには次のフィールドが含まれています。
kindはオブジェクトの種類を示します。metadata.nameで Deployment の名前を指定します。- 最初の
specフィールドには、望ましい状態の説明が含まれています。 spec.replicasで目的の Pod の数を指定します。spec.templateセクションで Pod テンプレートを定義します。Pod の仕様には、Artifact Registry から pull するイメージの名前であるimageフィールドが含まれています。次のステップでは、このイメージを先ほど作成した新しいイメージに更新します。
hellosvc Service は、次のように定義されます。
LoadBalancer: クライアントは、安定した IP アドレスを持ち、クラスタの外部からアクセス可能なネットワーク ロードバランサの IP アドレスにリクエストを送信します。targetPort:DockerfileのEXPOSE 8080コマンドでは実際にはポートが公開されないことに注意してください。ポート8080を公開して、クラスタの外部にあるserverコンテナにアクセスできるようにします。この場合、hellosvc.default.cluster.local:80(略称:hellosvc)はhelloserverPod IP のポート8080にマッピングされます。port: クラスタ内の他のサービスでリクエストを送信するときに使用するポート番号です。
負荷生成ツール
loadgen.yaml の Deployment オブジェクトは server.yaml に類似します。大きな違いとして、loadgen Deployment の Pod 仕様に env というフィールドがあります。このセクションでは、ソースからアプリケーションを実行したときに設定済みの loadgen で必要とされる環境変数を定義します。
loadgen は受信リクエストを受け付けないため、type フィールドは ClusterIP に設定されます。このタイプの Service は、クラスタ内のエンティティが使用できる安定した IP アドレスを提供しますが、その IP アドレスは外部クライアントには公開されません。
コンテナを GKE にデプロイする
コンテナをデプロイするには、kubectl を使用して、望ましい状態を指定するマニフェストを適用します。
server をデプロイする
サンプル
serverがあるディレクトリに移動します。cd ~/anthos-service-mesh-samples/docs/helloserver/server/
Cloud Shell エディタ(または任意のテキスト エディタ)で
server.yamlを開きます。imageフィールド内の名前を Docker イメージの名前に置き換えます。image: us-central1-docker.pkg.dev/PROJECT_ID/container-intro/helloserver:v0.0.1
PROJECT_ID は、実際の Google Cloud プロジェクト ID に置き換えます。
- Cloud Shell エディタを使用している場合、ファイルは自動的に保存されます。[ターミナルを開く] をクリックして、ターミナル ウィンドウに戻ります。
- Cloud Shell でテキスト エディタを使用している場合は、
server.yamlを保存して閉じます。
マニフェストを Kubernetes にデプロイします。
kubectl apply -f server.yaml出力は次のようになります。
deployment.apps/helloserver created service/hellosvc created
loadgen をデプロイする
loadgenがあるディレクトリに移動します。cd ../loadgen前と同様に、テキスト エディタで
loadgen.yamlを開きます。再度、
imageフィールド内の名前を Docker イメージの名前に置き換えます。image: us-central1-docker.pkg.dev/PROJECT_ID/container-intro/loadgen:v0.0.1
PROJECT_ID は、実際の Google Cloud プロジェクト ID に置き換えます。
- Cloud Shell エディタを使用している場合、ファイルは自動的に保存されます。[ターミナルを開く] をクリックして、ターミナル ウィンドウに戻ります。
- Cloud Shell でテキスト エディタを使用している場合は、
loadgen.yamlを保存して閉じます。
マニフェストをクラスタにデプロイします。
kubectl apply -f loadgen.yaml成功すると、コマンドは次のレスポンスを返します。
deployment.apps/loadgenerator created service/loadgensvc created
デプロイを確認する
マニフェストをクラスタにデプロイしたら、コンテナが正常にデプロイされたことを確認します。
クラスタ内の Pod のステータスを確認します。
kubectl get podsこのコマンドは、次のようなステータスを返します。
NAME READY STATUS RESTARTS AGE helloserver-69b9576d96-mwtcj 1/1 Running 0 58s loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s
loadgenPod からアプリケーション ログを取得します。POD_ID は、出力済みの負荷生成ツールの Pod ID に置き換えます。kubectl logs POD_ID
hellosvcの外部 IP アドレスを取得します。kubectl get service hellosvc出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hellosvc LoadBalancer 10.81.15.158 192.0.2.1 80:31127/TCP 33m
hellosvcにリクエストを送信します。EXTERNAL_IP はhellosvcの外部 IP アドレスに置き換えます。curl http://EXTERNAL_IP
サーバーから「Hello World!」というメッセージが表示されます。