【Google Cloud GKE】WebアプリをKubernetesにデプロイ ~Step1 サンプルアプリのデプロイ~

1. はじめに

Spring Bootで作ったWebアプリをGoogle CloudのGKEを用いてKubernetesにデプロイする方法をご紹介します。Google Cloudを使ったことがない方でも順を追ってできるように記載していますので、ぜひ参考にしてみて下さい。まずはStep1としてサンプルアプリをデプロイする方法を通じてGKEの使い方を理解してもらえればと思います。すでにGKEを触ったことがある方はご存じの内容かと思いますので、Step2から始めてもらえればと思います。

2. プロジェクト作成

まずは下記サイトからGoogle Consoleにログインしてプロジェクトを作成します。
クラウド管理コンソール | Google Cloud

下記画面が表示されたら「コンソールに移動」を押下します。

デフォルトだとMy First Projectが選択されていますが、今回は個別のプロジェクトを作成していきましょう。
「My First Project」を押下します。

「新しいプロジェクト」を押下します。

プロジェクト名を入力して「作成」ボタンを押下します。

少し待つと新規プロジェクトが作成されますので、作成したプロジェクトに移動します。
「My First Project」ボタンを押下してください。

自分で作成したプロジェクト名を押下します。

下記のように作成したプロジェクトが選択されていれば成功です。

3. DockerイメージをArtifact registryにPush

続いてサンプルで準備されているDockerイメージをArtifact registryにPushする方法をご紹介します。Artifact registryとは、コンテナのイメージなどの成果物をパッケージとしてまとめて管理するためのサービスとなります。
まずは数の赤枠のアイコンをクリックしてCloud Shellを起動します。

下記のようにCloud Shellのコマンドプロンプトが出てくれば成功です。

ここからはCloud Shellのターミナルにコマンドを打っていきます。
環境変数にプロジェクトIDを設定します。

username@cloudshell:~ (quizappproject-xxxxxx)$ export PROJECT_ID=quizappproject-xxxxxx
username@cloudshell:~ (quizappproject-xxxxxx)$ echo $PROJECT_ID
quizappproject-xxxxxx

続いてプロジェクトIDを設定します。

username@cloudshell:~ (quizappproject-xxxxxx)$ gcloud config set project $PROJECT_ID
Updated property [core/project].

hello-repo リポジトリを作成します。locationにリポジトリのリージョンを設定します。今回は利用料金が比較的安いアイオワ(us-central1)を設定しています。

username@cloudshell:~ (quizappproject-xxxxxx)$ gcloud artifacts repositories create hello-repo \
   --repository-format=docker \
   --location=us-central1 \
   --description="Docker repository"
Create request issued for: [hello-repo]
Waiting for operation [projects/quizappproject-xxxxxx/locations/us-central1/operations/834f
0556-d696-45b9-9ca7-4889baef3326] to complete...done.                                      
Created repository [hello-repo].

hello-appをGKEにデプロイする前に、hello-appソースコードをDockerイメージとしてパッケージ化します。下記コマンドを実行して、hello-appソースコードとDockerfileをダウンロードします。

username@cloudshell:~ (quizappproject-xxxxxx)$ git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
Cloning into 'kubernetes-engine-samples'...
remote: Enumerating objects: 12572, done.
remote: Counting objects: 100% (2755/2755), done.
remote: Compressing objects: 100% (560/560), done.
remote: Total 12572 (delta 2487), reused 2248 (delta 2186), pack-reused 9817 (from 1)
Receiving objects: 100% (12572/12572), 7.05 MiB | 15.10 MiB/s, done.
Resolving deltas: 100% (7978/7978), done.
username@cloudshell:~ (quizappproject-xxxxxx)$ cd kubernetes-engine-samples/quickstarts/hello-app

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

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1 .
[+] Building 48.2s (13/13) FINISHED                                                                                                                                            docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                     0.0s
 => => transferring dockerfile: 983B                                                                                                                                                     0.0s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 16)                                                                                                          0.0s
 => [internal] load metadata for gcr.io/distroless/base-debian11:latest                                                                                                                  1.5s
 => [internal] load metadata for docker.io/library/golang:1.23.2                                                                                                                         2.7s
 => [internal] load .dockerignore                                                                                                                                                        0.0s
 => => transferring context: 2B                                                                                                                                                          0.0s
 => [builder 1/5] FROM docker.io/library/golang:1.23.2@sha256:ad5c126b5cf501a8caef751a243bb717ec204ab1aa56dc41dc11be089fafcb4f                                                          22.4s
 => => resolve docker.io/library/golang:1.23.2@sha256:ad5c126b5cf501a8caef751a243bb717ec204ab1aa56dc41dc11be089fafcb4f                                                                   0.0s
 => => sha256:ad5c126b5cf501a8caef751a243bb717ec204ab1aa56dc41dc11be089fafcb4f 9.74kB / 9.74kB                                                                                           0.0s
 => => sha256:db933bde327ab6b27f54c29b092ab3bf9276738432ed1bc730b5c9bd98ff33ef 2.32kB / 2.32kB                                                                                           0.0s
~~中略~~
 => => writing image sha256:5d2f9fac3e81795c41f3cd6dd9b82bb2d764512a7092a8945f046521e4bd08a0                                                                                             0.0s
 => => naming to us-central1-docker.pkg.dev/quizappproject-xxxxxx/hello-repo/hello-app:v1                                                                                                0.0s

 2 warnings found (use docker --debug to expand):
 - FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 16)
 - LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format (line 25)

下記コマンドを実行して、ビルドがうまくいっていることを確認します。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ docker images
REPOSITORY                                                              TAG       IMAGE ID       CREATED          SIZE
us-central1-docker.pkg.dev/quizappproject-xxxxxx/hello-repo/hello-app   v1        5d2f9fac3e81   32 seconds ago   28MB

続いてコンテナイメージの動作確認をしてみましょう。下記コマンドを実行してください。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ docker run --rm -p 8080:8080 us-central1-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1
2024/12/15 12:14:35 Server listening on port 8080

クラウド管理コンソールの下記赤枠のアイコンの「ポート8080でプレビュー」をクリックします。

下記の通り、サンプルアプリの画面が出力されれば問題なくDockerイメージが作成できております。

続いてArtifact Registry への認証を構成します。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ gcloud auth configure-docker us-central1-docker.pkg.dev
WARNING: Your config file at [/home/username/.docker/config.json] contains these credential helper entries:

{
  "credHelpers": {
    "gcr.io": "gcloud",
~中略~
    "us-west8-docker.pkg.dev": "gcloud"
  }
}
Adding credentials for: us-central1-docker.pkg.dev
gcloud credential helpers already registered correctly.

ビルドした Docker イメージをリポジトリに push します。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ docker push us-central1-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1
The push refers to repository [us-central1-docker.pkg.dev/quizappproject-xxxxxx/hello-repo/hello-app]
1b70d0d2cc1c: Pushed 
6835249f577a: Pushed 
~中略~
577c8ee06f39: Pushed 
5342a2647e87: Pushed 
v1: digest: sha256:cb47d3adcf6856e1c90d5757fe494a2429c9073cbf2520dfe400061caa2640a6 size: 3445

Dockerイメージがリポジトリにpushされているかどうかを確認してみましょう。
クラウドコンソールの検索ボックスに「Artifact Registry」と入力してArtifact Registryを選択します。

下記の通りhello-repoが登録されていれば問題なしです。

4. GKEクラスタの作成

まず、Compute Engine のリージョンを設定します。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ gcloud config set compute/region us-central1
WARNING: Property validation for compute/region was skipped.
Updated property [compute/region].

続いて下記URLにアクセスしてKubernetes Engin APIを有効にします。{プロジェクトID}をご自身の値に変換してアクセスしてください。
https://console.developers.google.com/apis/api/container.googleapis.com/overview?project={プロジェクトID}

上記画面が出力されたら「有効にする」を押下します。続いて下記コマンドを投入してGKEクラスタを作成します。5分くらいかかるのでしばらく待ちます。
下記の通りSTATUSがRUNNINGになっていればGKEクラスタが問題なく作成できています。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ gcloud container clusters create-auto hello-cluster
Note: The Kubelet readonly port (10255) is now deprecated. Please update your workloads to use the recommended alternatives. See https://cloud.google.com/kubernetes-engine/docs/how-to/disable-kubelet-readonly-port for ways to check usage and for migration instructions.
Creating cluster hello-cluster in us-central1... Cluster is being health-checked (Kubernetes Control Plane is healthy)...done.                                                               
Created 
https://container.googleapis.com/v1/projects/quizappproject-xxxxxx/zones/us-central1/clusters/hello-cluster
. To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1/hello-cluster?project=quizappproject-xxxxxx kubeconfig entry generated for hello-cluster. NAME: hello-cluster LOCATION: us-central1 MASTER_VERSION: 1.30.6-gke.1125000 MASTER_IP: 35.222.110.93 MACHINE_TYPE: e2-small NODE_VERSION: 1.30.6-gke.1125000 NUM_NODES: 3 STATUS: RUNNING username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$

5. サンプルアプリをGKEにデプロイ

まずは作成したGKEクラスタの認証情報を取得することで、GKEクラスタに接続できることを確認します。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ gcloud container clusters get-credentials hello-cluster --region us-central1
Fetching cluster endpoint and auth data.
kubeconfig entry generated for hello-cluster.

続いてKubernetes Deploymentを作成します。Kubernetes Deploymentとは、アプリケーションのデプロイメントやスケーリング、ローリングアップデートなどを管理するために使用するリソースとなります。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ kubectl create deployment hello-app --image=us-central1-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1
Warning: autopilot-default-resources-mutator:Autopilot updated Deployment default/hello-app: defaulted unspecified 'cpu' resource for containers [hello-app] (see http://g.co/gke/autopilot-defaults).
deployment.apps/hello-app created
username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$

Deployment レプリカのベースライン数を設定します。今回はベースライン数を2に設定しています。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ kubectl scale deployment hello-app --replicas=2
deployment.apps/hello-app scaled

続いて、DeploymentのHorizontalPodAutoscalerリソースを作成します。CPU使用率に応じてpodをオートスケーリングする設定を追加することができます。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ kubectl autoscale deployment hello-app --cpu-percent=80 --min=2 --max=3
horizontalpodautoscaler.autoscaling/hello-app autoscaled

下記コマンドを実行してpodが作成できているか確認しましょう。起動に数分かかります。下記の通り2つPodができていてSTATUSがRunningになっていれば成功です。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
hello-app-676bf8b664-46llx   1/1     Running   0          2m2s
hello-app-676bf8b664-nmvqx   1/1     Running   0          2m14s

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

サンプルアプリをインターネットに公開するために下記コマンドを実行します。hello-app-serviceという名前でサービスを公開しています。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ kubectl expose deployment hello-app --name=hello-app-service --type=LoadBalancer --port 80 --target-port 8080
service/hello-app-service exposed

公開したサービスの状態を確認します。hello-app-serviceのLoadBalancerのEXTERNAL-IPが割り当てられるまでしばらく待ちます。コマンド実行直後はEXTERNAL-IPが<pending>となります。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ kubectl get service
NAME                TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
hello-app-service   LoadBalancer   34.118.233.194   <pending>     80:31114/TCP   10s
kubernetes          ClusterIP      34.118.224.1     <none>        443/TCP        11m

下記の通りEXTERNAL-IPが割り当てられたら完了です。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ kubectl get service
NAME                TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)        AGE
hello-app-service   LoadBalancer   34.118.233.194   34.59.239.14   80:31114/TCP   2m29s
kubernetes          ClusterIP      34.118.224.1     <none>         443/TCP        13m

インターネット経由でアクセスできるか確認してみましょう。EXTERNAL-IPに割り当てられたIPアドレスをブラウザに入力します。下記の通りサンプルアプリが表示されれば成功です。

7. 作成したリソースの削除

最後に不要な料金が発生しないように、作成したリソースをひととおり削除しておきましょう。まずはhello-app-serviceを削除します。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ kubectl delete service hello-app-service
service "hello-app-service" deleted

続いてGKEクラスタを削除します。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ gcloud container clusters delete hello-cluster --region us-central1
The following clusters will be deleted.
 - [hello-cluster] in [us-central1]

Do you want to continue (Y/n)?  y

Deleting cluster hello-cluster...done.                                                                                                                                                       
Deleted 
https://container.googleapis.com/v1/projects/quizappproject-xxxxxx/zones/us-central1/clusters/hello-cluster
.

最後、Artifact registryにPushしたDockerイメージを削除します。

username@cloudshell:~/kubernetes-engine-samples/quickstarts/hello-app (quizappproject-xxxxxx)$ gcloud artifacts docker images delete \
    us-central1-docker.pkg.dev/${PROJECT_ID}/hello-repo/hello-app:v1 \
    --delete-tags --quiet
Digests:
- us-central1-docker.pkg.dev/quizappproject-xxxxxx/hello-repo/hello-app@sha256:905ef95aa871e88d940abaab687551419910b1dc3d33264e2b864a924bdec287

Tags:
- us-central1-docker.pkg.dev/quizappproject-xxxxxx/hello-repo/hello-app:v1
Delete request issued.
Waiting for operation [projects/quizappproject-xxxxxx/locations/us-central1/operations/2c793cce-e0ad-4b1c-b430-ce62b245d341] to complete...done. 

8. まとめ

GKEを使ってKubernetes上にサンプルアプリをデプロイする方法をご紹介しました。GKEを使うことで、簡単にインターネット上にサンプルアプリを公開することができることがお分かりいただけたかと思います。次のステップ以降では、クイズアプリをkubernetes上にデプロイする方法をご紹介していきますので、ぜひ見てもらえると嬉しいです。

9. 参考文献

コメント