はじめに
Google Cloudのドキュメントを参考にしながら実際にコンテナアプリケーションのデプロイを実施してみたので、記事にまとめてみました。
1. 構成
1-1. 使用したサービス
-
Artifact Registry
パッケージとDockerコンテナイメージを管理するためのレジストリサービス。
Container Registryの進化系(機能を拡張している)。 -
Google Kuberntes Engine
クラウド上でKubernetesを管理・操作するためのサービス。
Kubernetesはコンテナ化されたワークフローやサービスを管理するためのプラットフォーム。
1-2. イメージ図
2. GKEの構成
2-1. 構成要素の説明
- クラスタ
コンテナアプリを実行するためのノードの集合体。
Kubernetesにおいて最も大きい概念。 - ノード
Kubernetes環境を構成する個々のサーバー(物理サーバもしくは仮想マシン)。
2種類のノードが存在する。- マスターノード
クラスタ全体を監視・管理するためのノード。
クライアントからの操作は、マスターノードを経由してワーカーノードに割り振られる。 - ワーカーノード
コンテナアプリが実際にデプロイされるノード。
- マスターノード
- ポッド
Kubernetesアプリケーションにおける最小単位。
アプリのコンテナ、ストレージ、ネットワークなどのリソースをカプセル化する。
2-1. イメージ図
3. 手順
3-1. API の有効化
Google Cloudのプロジェクトと課金設定が有効になっていることを確認した上で、下記2つのAPIを有効にします。
- Artifact Registry API
- Kubernetes Engine API
下記でArtifact RegistryとKubernetes EngineのAPIを一括で有効化できます。
APIs へのアクセスの有効化
GCPコンソールのナビゲーションメニュー→「APIとサービス」→「有効なAPIとサービス」に移動し、有効化したAPIが一覧にあれば大丈夫です。
3-2. リポジトリ作成
Cloud Shellで操作を行います。
下記コマンドを実行し、Artifact Registryに hello-repo
というリポジトリを作成します。
gcloud artifacts repositories create hello-repo \
--repository-format=docker \
--location=<REGION> \
--description="Docker repository"
「--location」はリポジトリを作成するリージョンを指定します。
自分は「asia-northeast1」を指定してみました。
3-3. コンテナイメージのビルド
GoogleがGithubで公開しているGKEのサンプルを使用します。
下記のコマンドを実行し、サンプルコードをクローンします。
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
今回は kubernetes-engine-samples
に同梱されている hello-app
を使用します。
ポート8080のリクエストに対して「Hello, World!」というメッセージを返すGoのWebアプリケーションになっています。
kubernetes-engine-samples/hello-app
内で下記のコマンドを実行し、コンテナイメージをビルドします。
docker build -t <REGION>-docker.pkg.dev/<PROJECT_ID>/hello-repo/hello-app:v1 .
コンテナイメージがローカルにビルドされたことを確認します。
docker images
ローカルのDockerエンジンを使用し、ビルドしたコンテナイメージが正常に動作することを確認します。
下記のコマンドでアプリを起動します。
docker run --rm -p 8080:8080 <REGION>-docker.pkg.dev/<PROJECT_ID>/hello-repo/hello-app:v1
Cloud Shellターミナルをもう1つ立ち上げ、curlを使用してポート8080にリクエストを送信し、「Hello, World!」というメッセージが返されたら成功です。
正常に動作することを確認したら、Ctrl+Cキーでアプリを停止します。
3-4. ビルドしたコンテナイメージをリポジトリにプッシュ
前述のとおり、コンテナイメージをビルドして正常に動作することを確認できました。
このコンテナイメージを先ほど作成した Artifact Registry のリポジトリにプッシュします。
はじめに、Docker用のArtifact Registryの認証を行います。
gcloud auth configure-docker <REGION>-docker.pkg.dev
そして、コンテナイメージをリポジトリにプッシュします。
docker push <REGION>-docker.pkg.dev/<PROJECT_ID>/hello-repo/hello-app:v1
GCPコンソールからArtifact Registryのリポジトリを確認すると、プッシュしたイメージが存在することを確認できました。
3-5. GKEクラスタ作成
GKEクラスタは2種類のモードが存在します。
-
スタンダードモード
事前にワーカーノードのリソース情報を含んだ設定を用意する。 -
Autopilot モード
ワーカーノードが自動で管理されるモード。
コンテナが要求するリソース分のワーカーノードを自動で用意するため、ユーザ自身が管理しなくてもオートスケーリングしてくれる。
詳細は公式ドキュメントのクラスタのタイプを参照してください。
GKEのクラスタは、Kubernetesを実行しているCompute EngineのVMインスタンスプールで構成されています。
そのため、GKEクラスタを作成する際は、Compute Engineのゾーンまたはリージョンを指定する必要があります。
スタンダードモードは ゾーンクラスタ が作成されるため、ゾーンを指定します。
Autopilot モードは リージョンクラスタ が作成されるため、リージョンを指定します。
Cloud Shellにて下記のコマンドを使用するクラスタモードに応じて実行します。
(Artifact Registryのリポジトリと近いゾーンまたはリージョンを選択してください)
スタンダードクラスタの場合
gcloud config set compute/zone <COMPUTE_ZONE>
Autopilot クラスタの場合
gcloud config set compute/region <COMPUTE_REGION>
そして、GKEクラスタを作成します。
今回クラスタの名前は hello-cluster
とします。
スタンダードクラスタの場合
gcloud container clusters create hello-cluster
Autopilot クラスタの場合
gcloud container clusters create-auto hello-cluster
Autopilot モードで実施しましたが、コマンド実行後、クラスタの作成に5分ほどかかりました。
少し時間がかかるそうです。コーヒーでも飲みながら待ちましょう。
GCPコンソールでも確認してみると、クラスタ作成されていました。
下記のコマンドを実行し、クラスタのノードを確認します。
kubectl get nodes
3-6. ビルドしたコンテナイメージをGKEにデプロイ
GKEクラスタを作成できたので、ビルドしたコンテナイメージをGKEクラスタにデプロイしていきますが、
そこで レプリカセット と デプロイメント というリソースが登場します。
-
レプリカセット
コンテナをデプロイする際に作成するポッド数を定義するためのリソース。
例えば、特定のポッドについて「クラスタ全体で3つのポッドを常に維持する」とレプリカセットで設定すれば、kubernetesがその設定をもとにポッド数を3個維持してくれる。
もし障害などが発生してポッドが減少した場合に、Kubernetesが別のノードで自動的にポッドを起動し、レプリカ数を維持するといったことが可能。
まずは、GKEクラスタの接続を確認します。
gcloud container clusters get-credentials hello-cluster --region <REGION>
コンテナイメージのデプロイメントを作成します。
kubectl create deployment hello-app --image=<REGION>-docker.pkg.dev/<PROJECT_ID>/hello-repo/hello-app:v1
Pod数を3個に設定します。
kubectl scale deployment hello-app --replicas=3
Pod数を確認
kubectl get pod
Horizontal Pod Autoscaler を設定します。
- Horizontal Pod Autoscaler
CPU使用率などの負荷状況に基づき、Pod単位でオートスケーリングする機能のこと。
今回は、Podの平均CPU使用率を80%とし、CPU負荷に応じてPod数を3から1~5にスケーリングするように設定。
kubectl autoscale deployment hello-app --cpu-percent=80 --min=1 --max=5
現在のAutoscalerの状況を確認
kubectl get hpa
※現在CPU使用率が0%なのは、リクエストが送られてきていないから。
3-7. インターネットに公開
デプロイしたアプリに外部からアクセスできるようにするため、Kubernetesの サービス を使用し、クラスタ内のアプリにアクセスするための静的な外部IPアドレスを設定します。
- サービス
複数デプロイされた同一ポッドを1つのリソースにグループ化したもの。
グループ化したポッドに対するアクセス手段をそれぞれ提供する。
デプロイメントを公開するサービスを作成します。
kubectl expose deployment hello-app --name=hello-app-service --type=LoadBalancer --port 80 --target-port 8080
「LoadBalancer」はサービスタイプの1つであり、アプリをクラスタ外部に公開するしくみです。
※サービスタイプを指定していない場合、デフォルトで「ClusterIP」が設定され、クラスタ内でのみ到達可能な IP アドレスを取得します。
サービスの詳細情報を取得します。
kubectl get service
「hello-app-service」のEXTERNAL_IPをコピーします。
新しいブラウザタブを立ち上げ、コピーしたEXTERNAL_IPに移動します。
「Hello, World!」というメッセージが表示されればうまくできたと思います。
おわりに
今回はArtifact RegistryとGoogle Kuberntes Engineを使用してコンテナアプリのデプロイから動作確認までの一連の操作を実施しました。
GKEのローリングアップデートやクリーンアップなどの機能については、次回実践して記事にまとめてみようと思います。