Google Kubernetes Engine 上の Kubernetes に Spring Boot Java アプリをデプロイします。

Google Kubernetes Engine 上の Kubernetes に Spring Boot Java アプリをデプロイする

この Codelab について

subject最終更新: 4月 22, 2020
account_circleGoogle 社員により作成

1. 始める前に

Kubernetes は、ノートパソコン、高可用性マルチノード クラスタ、パブリック クラウドからオンプレミス デプロイ、仮想マシン(VM)インスタンス、ベアメタルまで、さまざまな環境で実行できるオープンソース プロジェクトです。

この Codelab では、簡単な Spring Boot Java ウェブアプリを GKE の Kubernetes にデプロイします。この演習では、ウェブアプリを Kubernetes 上の複製アプリとして実行します。マシン上で開発したコードを Docker コンテナ イメージに変換し、GKE で実行します。

Google Cloud でフルマネージドの Kubernetes サービスである GKE を使用することで、基盤となるインフラストラクチャの設定ではなく、Kubernetes の運用に集中できるようになります。

開発用ノートパソコンなど、ローカルマシンで Kubernetes を実行する場合は、Minikube を検討してください。Minikube は、開発とテスト用に単一ノードの Kubernetes クラスタをシンプルにセットアップしたものです。Minikube を使用して、必要に応じて Codelab を実行できます。

この Codelab では、Spring Boot を使用したアプリのビルドに関するガイドのサンプルコードを使用します。

前提条件

  • Java プログラミング言語とツールに精通していること
  • Linux の標準的なテキスト エディタ(Vim、Emacs、nano など)に関する知識

演習内容

  • シンプルな Java アプリを Docker コンテナとしてパッケージ化する。
  • GKE で Kubernetes クラスタを作成します。
  • GKE 上の Kubernetes に Java アプリをデプロイする。
  • サービスをスケールアップし、アップグレードを展開します。
  • ウェブベースの Kubernetes ユーザー インターフェースであるダッシュボードにアクセスします。

必要なもの

  • Google Cloud プロジェクト
  • Google Chrome などのブラウザ

2. 設定と要件

セルフペース型の環境設定

  1. Cloud Console にログインして新しいプロジェクトを作成するか、既存のプロジェクトを再利用します。(Gmail または G Suite アカウントをまだお持ちでない場合は、作成する必要があります)。

プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID と呼びます。

  1. 次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。

この Codelab を実施した場合、費用は数ドルを超えることはありませんが、より多くのリソースを使用する場合や、実行を継続する場合は、さらにコストがかかる可能性があります。

Google Cloud の新規ユーザーは 300 ドル分の無料トライアルをご利用いただけます。

Cloud Shell をアクティブにする

  1. Cloud Console で、Cloud Shell をアクティブにするアイコン をクリックします。

Cloud Shell を起動したことがない場合、その内容を説明する中間画面が(スクロールしなければ見えない範囲に)が表示されます。その場合は、[続行] をクリックします(以後表示されなくなります)。このワンタイム スクリーンは次のようになります。

Cloud Shell のプロビジョニングと接続に少し時間がかかる程度です。

この仮想マシンには、必要な開発ツールがすべて用意されています。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働するため、ネットワーク パフォーマンスが充実しており認証もスムーズです。このコードラボでの作業のほとんどは、ブラウザまたは Chromebook から実行できます。

Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。

  1. Cloud Shell で次のコマンドを実行して、認証されたことを確認します。
gcloud auth list

コマンド出力

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

コマンド出力

[core]
project = <PROJECT_ID>

上記のようになっていない場合は、次のコマンドで設定できます。

gcloud config set project <PROJECT_ID>

コマンド出力

Updated property [core/project].

3. ソースコードを取得する

Cloud Shell が起動したら、コマンドラインを使用してサンプル ソースコードのクローンをホーム ディレクトリに作成できます。

$ git clone https://github.com/spring-guides/gs-spring-boot.git
$ cd gs-spring-boot/complete

4. アプリをローカルで実行する

  1. Spring Boot プラグインを使用すると、通常どおり Spring Boot アプリを起動できます。
$ ./mvnw -DskipTests spring-boot:run
  1. アプリが起動したら、Cloud Shell ツールバーの [ウェブでプレビュー] をクリックし、[ポート 8080 でプレビュー] を選択します。

ブラウザのタブが開き、起動したサーバーに接続されます。

5. Java アプリを Docker コンテナとしてパッケージ化する

次に、アプリを Kubernetes で実行する準備を行う必要があります。最初のステップとして、コンテナとその内容を定義します。

  1. アプリの JAR デプロイ可能を作成します。
$ ./mvnw -DskipTests package
  1. Container Registry を有効にして、作成するコンテナ イメージを保存します。
$ gcloud services enable containerregistry.googleapis.com
  1. Jib を使用してコンテナ イメージを作成し、Container Registry に push します。
$ ./mvnw -DskipTests com.google.cloud.tools:jib-maven-plugin:build \
  -Dimage=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v1
  1. 問題がなければ、[Container Registry] > [イメージ] に移動すると、コンソールにコンテナ イメージが表示されています。これで、プロジェクト全体の Docker イメージが使用可能になりました。このイメージは、Kubernetes が数分でアクセスしてオーケストレートできるものです。
  1. それが完了したら(すべてダウンロードと抽出に時間がかかります)、次のコマンドを使用して、イメージをローカルでテストできます。ここでは、新しく作成されたコンテナ イメージから Docker コンテナをポート 8080 でデーモンとして実行します。
$ docker run -ti --rm -p 8080:8080 \
  gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v1
  1. ここでも、Cloud Shell のウェブ プレビュー機能を使用します。

  1. 新しいタブにデフォルトのページが表示されます。アプリが Docker コンテナでローカルに動作していることを確認したら、Control+C を押して実行中のコンテナを停止できます。

6. クラスタを作成する

GKE クラスタを作成する準備が整いました。クラスタは、Google が管理する Kubernetes API サーバーと一連のワーカーノードで構成されます。ワーカーノードは Compute Engine VM です。

  1. まず、関連する API 機能が有効になっていることを確認します。
$ gcloud services enable compute.googleapis.com container.googleapis.com
Operation "operations/..." finished successfully
  1. 2 つの n1-standard-1 ノードからなるクラスタを作成する(完了には数分かかります)。
$ gcloud container clusters create hello-java-cluster \
  --num-nodes 2 \
  --machine-type n1-standard-1 \
  --zone us-central1-c

最終的に、作成されたクラスタが表示されます。

Creating cluster hello-java-cluster...done.
Created [https://container.googleapis.com/v1/projects/...].
kubeconfig entry generated for hello-dotnet-cluster.
NAME                  ZONE            MASTER_VERSION  
hello-java-cluster  us-central1-c  ...

これで、GKE を利用する Kubernetes クラスタが完全に機能するようになりました。

次は、コンテナ化されたアプリを Kubernetes クラスタにデプロイします。ここからは、kubectl コマンドライン(Cloud Shell 環境で設定済み)を使用します。Codelab の残りの部分では、Kubernetes クライアントとサーバーのバージョンが 1.2 以上である必要があります。kubectl version により、コマンドの現在のバージョンが表示されます。

7. アプリを Kubernetes にデプロイする

  1. Kubernetes Deployment は、作成したコンテナ イメージを使用してアプリの複数のインスタンスを作成、管理、スケールできます。kubectl run コマンドを使用して、アプリのインスタンスを Kubernetes にデプロイします。
$ kubectl create deployment hello-java \
  --image=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v1
  1. 作成した Deployment を表示するには、次のコマンドを実行します。
$ kubectl get deployments
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   1         1         1            1           37s
  1. デプロイによって作成されたアプリ インスタンスを表示するには、次のコマンドを実行します。
$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
hello-java-714049816-ztzrb   1/1       Running   0          57s

この時点で、コンテナは Kubernetes の管理下で実行されているはずですが、外部からアクセスできるようにする必要があります。

8. 外部トラフィックを許可する

デフォルトでは、Pod にはクラスタ内の内部 IP からのみアクセスできます。Kubernetes 仮想ネットワークの外部から hello-java コンテナにアクセスできるようにするには、Pod を Kubernetes サービスとして公開する必要があります。

  1. Cloud Shell で、kubectl expose コマンドと --type=LoadBalancer フラグを組み合わせて、Pod を公共のインターネットに公開できます。外部からアクセス可能な IP を作成するには、このフラグが必要です。
$ kubectl create service loadbalancer hello-java --tcp=8080:8080

コマンドで使用されるフラグは、基盤となるインフラストラクチャで提供されるロードバランサを使用することを指定します。デプロイは Pod ではなく直接公開します。その結果、サービスは Deployment で管理されるすべての Pod 間でトラフィックを負荷分散します(この場合は Pod は 1 つだけですが、後でレプリカを追加します)。

Kubernetes マスターはロードバランサと関連する Compute Engine 転送ルール、ターゲット プール、ファイアウォール ルールを作成し、Google Cloud の外部からサービスに完全にアクセスできるようにします。

  1. サービスの一般公開された IP アドレスを確認するには、kubectl をリクエストしてすべてのクラスタ サービスを一覧表示します。
$ kubectl get services
NAME         CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE
Hello-java   10.3.253.62    aaa.bbb.ccc.ddd  8080/TCP    1m
kubernetes   10.3.240.1     <none>           443/TCP    5m
  1. サービスには IP が 2 つあり、どちらもポート 8080 を使用しています。1 つは Virtual Private Cloud 内でのみ表示される内部 IP アドレスです。もう 1 つは外部負荷分散された IP アドレスです。この例の外部 IP アドレスは aaa.bbb.ccc.ddd です。ブラウザで http://<EXTERNAL_IP>:8080 の URL にアクセスすると、サービスにアクセスできるようになります。

9. サービスのスケーリング

Kubernetes の強力な機能の 1 つに、アプリのスケーリングが簡単であることが挙げられます。急激にアプリの容量が必要になった場合、アプリ インスタンスの新しいレプリカ数を管理するようレプリケーション コントローラに指示できます。

$ kubectl scale deployment hello-java --replicas=3
deployment "hello-java" scaled

$ kubectl get deployment
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   3         3         3            3           22m

宣言型のアプローチに注目してください。新しいインスタンスの起動や停止を行うのではなく、実行するインスタンスの数を宣言します。Kubernetes の調整ループは、現実にリクエストした内容と一致することを確認し、必要に応じて対処します。

10. サービスへのアップグレードをロールアウトする

いずれかの時点で本番環境にデプロイしたアプリでは、バグの修正や追加機能が必要になります。Kubernetes を使用すると、ユーザーに影響を与えることなく、新しいバージョンを本番環境にデプロイできます。

  1. Cloud Shell メニューで [エディタを開く] をクリックして、コードエディタを開きます。
  2. src/main/java/hello/HelloController.java に移動して、レスポンスの値を更新します。
package hello;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
public class HelloController {    
   
@RequestMapping("/")
   
public String index() {
       
return "Greetings from Google Kubernetes Engine!";
   
}
}
  1. Jib を使用して、新しいバージョンのコンテナ イメージをビルドして push します。
$ ./mvnw -DskipTests package \
  com.google.cloud.tools:jib-maven-plugin:build \
  -Dimage=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v2

これで、Kubernetes でレプリケーション コントローラを新しいバージョンにスムーズに更新できるようになりました。

  1. 実行中のコンテナのイメージラベルを変更するには、既存の hello-java Deployment を編集し、イメージを gcr.io/PROJECT_ID/hello-java:v1 から gcr.io/PROJECT_ID/hello-java:v2 に変更する必要があります。
  1. kubectl set image コマンドを使用すると、Kubernetes にローリング アップデートで一度に 1 つのクラスタ全体でアプリの新しいバージョンをデプロイできます。
$ kubectl set image deployment/hello-java \
  hello-java=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v2

deployment "hello-java" image updated
  1. http://EXTERNAL_IP:8080 を再び確認して、新しい応答を返していることを確認します。

11. ロールバック

申し訳ございませんが、アプリの新しいバージョンを間違って入力した場合は、新しいバージョンにエラーがあり、すぐにロールバックする必要がある可能性があります。Kubernetes を使用すると、簡単に前の状態にロールバックできます。次のコマンドを実行して、アプリをロールバックします。

$ kubectl rollout undo deployment/hello-java

12. 完了

新しい Java ベースのウェブアプリをビルドして GKE 上の Kubernetes にデプロイする方法を学習しました。

詳細