この Codelab について
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. 設定と要件
セルフペース型の環境設定
- Cloud Console にログインして新しいプロジェクトを作成するか、既存のプロジェクトを再利用します。(Gmail または G Suite アカウントをまだお持ちでない場合は、作成する必要があります)。
プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID
と呼びます。
- 次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。
この Codelab を実施した場合、費用は数ドルを超えることはありませんが、より多くのリソースを使用する場合や、実行を継続する場合は、さらにコストがかかる可能性があります。
Google Cloud の新規ユーザーは 300 ドル分の無料トライアルをご利用いただけます。
Cloud Shell をアクティブにする
- Cloud Console で、Cloud Shell をアクティブにするアイコン
をクリックします。
Cloud Shell を起動したことがない場合、その内容を説明する中間画面が(スクロールしなければ見えない範囲に)が表示されます。その場合は、[続行] をクリックします(以後表示されなくなります)。このワンタイム スクリーンは次のようになります。
Cloud Shell のプロビジョニングと接続に少し時間がかかる程度です。
この仮想マシンには、必要な開発ツールがすべて用意されています。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働するため、ネットワーク パフォーマンスが充実しており認証もスムーズです。このコードラボでの作業のほとんどは、ブラウザまたは Chromebook から実行できます。
Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。
- 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. アプリをローカルで実行する
- Spring Boot プラグインを使用すると、通常どおり Spring Boot アプリを起動できます。
$ ./mvnw -DskipTests spring-boot:run
- アプリが起動したら、Cloud Shell ツールバーの [ウェブでプレビュー]
をクリックし、[ポート 8080 でプレビュー] を選択します。
ブラウザのタブが開き、起動したサーバーに接続されます。
5. Java アプリを Docker コンテナとしてパッケージ化する
次に、アプリを Kubernetes で実行する準備を行う必要があります。最初のステップとして、コンテナとその内容を定義します。
- アプリの JAR デプロイ可能を作成します。
$ ./mvnw -DskipTests package
- Container Registry を有効にして、作成するコンテナ イメージを保存します。
$ gcloud services enable containerregistry.googleapis.com
- Jib を使用してコンテナ イメージを作成し、Container Registry に push します。
$ ./mvnw -DskipTests com.google.cloud.tools:jib-maven-plugin:build \ -Dimage=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v1
- 問題がなければ、[Container Registry] > [イメージ] に移動すると、コンソールにコンテナ イメージが表示されています。これで、プロジェクト全体の Docker イメージが使用可能になりました。このイメージは、Kubernetes が数分でアクセスしてオーケストレートできるものです。
- それが完了したら(すべてダウンロードと抽出に時間がかかります)、次のコマンドを使用して、イメージをローカルでテストできます。ここでは、新しく作成されたコンテナ イメージから Docker コンテナをポート 8080 でデーモンとして実行します。
$ docker run -ti --rm -p 8080:8080 \ gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v1
- ここでも、Cloud Shell のウェブ プレビュー機能を使用します。
- 新しいタブにデフォルトのページが表示されます。アプリが Docker コンテナでローカルに動作していることを確認したら、
Control+C
を押して実行中のコンテナを停止できます。
6. クラスタを作成する
GKE クラスタを作成する準備が整いました。クラスタは、Google が管理する Kubernetes API サーバーと一連のワーカーノードで構成されます。ワーカーノードは Compute Engine VM です。
- まず、関連する API 機能が有効になっていることを確認します。
$ gcloud services enable compute.googleapis.com container.googleapis.com Operation "operations/..." finished successfully
- 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 にデプロイする
- Kubernetes Deployment は、作成したコンテナ イメージを使用してアプリの複数のインスタンスを作成、管理、スケールできます。
kubectl run
コマンドを使用して、アプリのインスタンスを Kubernetes にデプロイします。
$ kubectl create deployment hello-java \ --image=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v1
- 作成した Deployment を表示するには、次のコマンドを実行します。
$ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE hello-java 1 1 1 1 37s
- デプロイによって作成されたアプリ インスタンスを表示するには、次のコマンドを実行します。
$ 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 サービスとして公開する必要があります。
- 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 の外部からサービスに完全にアクセスできるようにします。
- サービスの一般公開された 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
- サービスには 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 を使用すると、ユーザーに影響を与えることなく、新しいバージョンを本番環境にデプロイできます。
- Cloud Shell メニューで [エディタを開く]
をクリックして、コードエディタを開きます。
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!";
}
}
- Jib を使用して、新しいバージョンのコンテナ イメージをビルドして push します。
$ ./mvnw -DskipTests package \ com.google.cloud.tools:jib-maven-plugin:build \ -Dimage=gcr.io/$GOOGLE_CLOUD_PROJECT/hello-java:v2
これで、Kubernetes でレプリケーション コントローラを新しいバージョンにスムーズに更新できるようになりました。
- 実行中のコンテナのイメージラベルを変更するには、既存の
hello-java
Deployment を編集し、イメージをgcr.io/PROJECT_ID/hello-java:v1
からgcr.io/PROJECT_ID/hello-java:v2
に変更する必要があります。
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
- http://EXTERNAL_IP:8080 を再び確認して、新しい応答を返していることを確認します。
11. ロールバック
申し訳ございませんが、アプリの新しいバージョンを間違って入力した場合は、新しいバージョンにエラーがあり、すぐにロールバックする必要がある可能性があります。Kubernetes を使用すると、簡単に前の状態にロールバックできます。次のコマンドを実行して、アプリをロールバックします。
$ kubectl rollout undo deployment/hello-java