Spring Boot Kubernetes

このガイドでは、Kubernetes (英語) に Spring Boot アプリケーションをデプロイするプロセスについて説明します。Spring Boot と Kubernetes を使用してさまざまな方法から選択できます。このガイドの目的は、すべての代替案について説明したり、本番環境に移行する方法の詳細をすべて説明したりすることではなく、できるだけ早く作業を進めることです。

構築するもの

Kubernetes (英語) は、コンテナー化されたアプリケーションのデプロイ、スケーリング、管理を自動化するためのオープンソースシステムです。アプリケーションを構成するコンテナーを論理ユニットにグループ化して、管理と検出を容易にします。このガイドでは、単純な Spring boot アプリケーションを構築してデプロイします。

Docker には入門ガイドトピックガイドもあります。これらは、コンテナーイメージを構築する際の背景の一部をカバーしています。

必要なもの

Linux または Linux に似たコマンドラインが必要です。このガイドのコマンドラインの例は、Linux、シェル付き MacOS ターミナル、Windows 上の WSL で動作します。

また、Kubernetes クラスターとコマンドラインツール Kubectl (英語) も必要です。kind [GitHub] (英語) (Docker 上)または Minikube [GitHub] (英語) を使用して、ローカルでクラスターを作成できます。または、Google クラウドプラットフォーム (英語) Amazon Web Services Microsoft Azure (英語) などのクラウドプロバイダーを使用することもできます。先に進む前に、シェルから kubectl コマンドを実行できることを確認してください。次の例では、kind を使用しています。

$ kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:46253
KubeDNS is running at https://127.0.0.1:46253/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

次のコマンドも実行する必要があります。

$ kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.43.0.1    <none>        443/TCP   7m13s

Spring Boot アプリケーションを作成する

まず、Spring Boot アプリケーションを作成します。すでに github で使用したいものがある場合は、ターミナルでクローンを作成できます(git と java はすでにインストールされています)。または、start.spring.io を使用して、アプリケーションを最初から作成することもできます。

curl https://start.spring.io/starter.tgz -d dependencies=webflux,actuator -d type=maven-project | tar -xzvf -

その後、アプリケーションをビルドできます。

./mvnw install
初回は数分かかりますが、依存関係がすべてキャッシュされると、高速になります。

次に、ビルドの結果を確認できます。ビルドが成功すると、次のような JAR ファイルが表示されます。

ls -l target/*.jar
-rw-r--r-- 1 root root 19463334 Nov 15 11:54 target/demo-0.0.1-SNAPSHOT.jar

JAR は実行可能です:

$ java -jar target/*.jar

プロジェクトのダウンロード時に追加した actuator 依存関係のため、アプリケーションにはいくつかの組み込み HTTP エンドポイントがあります。起動時のログに次のような出力が表示されます。

...
2019-11-15 12:12:35.333  INFO 13912 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2019-11-15 12:12:36.448  INFO 13912 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
...

次に、別のターミナルのエンドポイントを curl できます。

$ curl localhost:8080/actuator | jq .
{
  "_links": {
    "self": {
      "href": "http://localhost:8080/actuator",
      "templated": false
    },
    "health-path": {
      "href": "http://localhost:8080/actuator/health/{*path}",
      "templated": true
    },
    "health": {
      "href": "http://localhost:8080/actuator/health",
      "templated": false
    },
    "info": {
      "href": "http://localhost:8080/actuator/info",
      "templated": false
    }
  }
}

この手順を完了するには、Ctrl + C を押してアプリケーションを停止します。

アプリケーションをコンテナー化する

Spring Boot アプリケーションをコンテナー化するための複数のオプションがあります。Spring Boot jar ファイルをすでに作成している限り、プラグインを直接呼び出すだけで済みます。次のコマンドは Maven を使用します。

$ ./mvnw spring-boot:build-image

次のコマンドは Gradle を使用します。

$ ./gradlew bootBuildImage

コンテナーをローカルで実行できます:

$ docker run -p 8080:8080 demo:0.0.1-SNAPSHOT

次に、別のターミナルで機能することを確認できます。

$ curl localhost:8080/actuator/health

コンテナーを停止して終了します。

Dockerhub(docker login)で認証しない限り、イメージをプッシュすることはできませんが、動作するはずのイメージがすでに存在します。認証された場合は、次のことができます。

$ docker tag demo:0.0.1-SNAPSHOT springguides/demo
$ docker push springguides/demo

実際には、Kubernetes は通常ローカルの docker デーモンに接続されていない Kubelets(ノード)内からイメージをプルするため、イメージを Dockerhub(またはその他のアクセス可能なリポジトリ)にプッシュする必要があります。このシナリオでは、プッシュを省略して、すでに存在するイメージを使用できます。

テストの場合、docker push を安全でないローカルレジストリ(たとえば)で機能させる回避策がありますが、このガイドの範囲外です。

アプリケーションを Kubernetes にデプロイする

これで、ポート 8080 を実行して公開するコンテナーができたため、Kubernetes を実行するために必要なのは YAML だけです。YAML を確認または編集する必要がないように、今のところ、kubectl に YAML を生成するように依頼できます。ここで異なる可能性があるのは、--image 名だけです。コンテナーを独自のリポジトリにデプロイした場合は、次のタグの代わりにそのタグを使用してください。

$ kubectl create deployment demo --image=springguides/demo --dry-run -o=yaml > deployment.yaml
$ echo --- >> deployment.yaml
$ kubectl create service clusterip demo --tcp=8080:8080 --dry-run -o=yaml >> deployment.yaml

上で生成された YAML を取得して、必要に応じて編集するか、そのまま適用することができます。

$ kubectl apply -f deployment.yaml
deployment.apps/demo created
service/demo created

アプリケーションが実行されていることを確認します。

$ kubectl get all
NAME                             READY     STATUS      RESTARTS   AGE
pod/demo-658b7f4997-qfw9l        1/1       Running     0          146m

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/kubernetes   ClusterIP   10.43.0.1       <none>        443/TCP    2d18h
service/demo         ClusterIP   10.43.138.213   <none>        8080/TCP   21h

NAME                   READY     UP-TO-DATE   AVAILABLE   AGE
deployment.apps/demo   1/1       1            1           21h

NAME                              DESIRED   CURRENT   READY     AGE
replicaset.apps/demo-658b7f4997   1         1         1         21h
d
デモ pod が Running としてステータスを示すまで、kubectl get all を繰り返します。

次に、Kubernetes でサービスとして公開したアプリケーションに接続できるようにする必要があります。それを行う 1 つの方法は、開発時にうまく機能し、SSH トンネルを作成することです。

$ kubectl port-forward svc/demo 8080:8080

次に、アプリが別のターミナルで実行されていることを確認できます。

$ curl localhost:8080/actuator/health
{"status":"UP"}

コードを入手する