DUICUO

わずか 5 つのステップで Spring Boot サービスを Kubernetes に移行

多くのJava開発者は、Springフレームワークを使用してWebサービスを迅速に作成していますが、ランタイムオプションやクラウドプロバイダーの多さから、本番環境での実行は大きな課題となる場合があります。AWS Elastic Beanstalkなどのサービスを利用すれば、自動スケーリング、ダウンタイムゼロのデプロイメント、そしてインフラストラクチャの新バージョンをデプロイする必要がないため、Webサービスを継続的に稼働させることができますが、予算が限られている開発者にとっては高額になる可能性があり、サービスインフラストラクチャに対する制御を失うことにもつながります。

予算が限られていて、低コストで Elastic Beanstalk のすべてのメリットを得たい場合は、オープンソースの Kubernetes を使用できます。

1. Dockerイメージを生成する

Kubernetesは、コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するコンテナオーケストレーションプラットフォームです。Kubernetesの仕組みは以下のとおりです。アプリケーションからDockerイメージを作成し、Kubernetesにそれらのイメージのインスタンスを1つ以上起動するように指示します。Kubernetesはこれらのインスタンスを利用可能なノードに自動的に割り当て、常に稼働状態を維持します。ノードに障害が発生した場合やアプリケーションのスケーリングが必要な場合は、Kubernetesが自動的にインスタンスを再割り当てし、アプリケーションが常に稼働状態を維持できるようにします。そのため、最初のステップはSpring Bootサービスからイメージを作成することです。

Dockerfile の例を次に示します。

 FROM openjdk:8-jdk-alpine VOLUME /tmp MAINTAINER Samuel Birocchi <[email protected]> ADD target/*.jar app.jar COPY newrelic newrelic ENV JAVA_OPTS="" ENV SPRING_PROFILE="default" ENV MONGO_PASSWORD="" ENTRYPOINT exec java $JAVA_OPTS \ -javaagent:newrelic/newrelic.jar \ -Djava.security.egd=file:/dev/./urandom \ -Dspring.profiles.active=$SPRING_PROFILE \ -Dmongo.password=$MONGO_PASSWORD \ -jar app.jar

これとdocker buildプラグインを使えば、`gradle clean buildDocker`(またはMaven dockerプラグイン)を実行してDockerイメージをビルドできます。`gradle.properties`または`build.gradle`で設定されたバージョンタグ付きのイメージが作成されることに注意してください。

2. デプロイメントとポッドを作成する

作成したイメージをKubernetesにデプロイするには、レジストリにアップロードする必要があります。パブリックDockerレジストリにアップロードすることもできますが、そうするとイメージが誰でもアクセスできてしまいます。私たちのサービスはプライベートなので、プライベートレジストリにアップロードする必要があります。幸いなことに、Gcloudはアカウント用のプライベートレジストリを提供しています。

これで、Kubernetes クラスタにサービスをデプロイできるようになりました!Gcloud を使用しているので、GKE を使ったクラスタの作成は非常に簡単です。このチュートリアルに従ってください。クラスタを作成し、コマンドライン接続を設定したら、アプリケーションのスケーラビリティを確保するために、デプロイメント(またはレプリケーション コントローラ)を作成する必要があります。初期設定として、以下の構成を使用してください。

 apiVersion: apps/v1beta1 # for versions before 1.8.0 use apps/v1beta1 kind: Deployment metadata: name: spring-boot-deployment spec: selector: matchLabels: app: spring-boot-app replicas: 3 # tells deployment to run 3 pods matching the template template: # create pods using pod definition in this template metadata: labels: app: spring-boot-app spec: containers: - name: spring-boot-app image: #your image name here ports: - containerPort: 8080 name: server - containerPort: 8081 name: management

Kubernetesコマンドラインインターフェース(kubectl)は前のステップで設定済みなので、「kubectl apply -f Deployment.yml」コマンドを使用してKubernetesクラスターの新しいデプロイメントを作成し、この設定を使用できます。しばらくすると、「kubectl get deployment spring-boot-deployment」コマンドでデプロイメントのステータス、「kubectl get pods spring-boot-app」コマンドでポッドのステータスを確認できます。ポッドのログを確認するには、「kubectl log」コマンドを使用します。

3. サービスを使用してポッドを公開します。

Podが実行中になったので、それを公開するためのサービスを作成する必要があります。以下の設定でサービスを作成します。

 apiVersion: v1 kind: Service metadata: name: spring-boot-service spec: ports: - port: 8080 targetPort: 8080 name: http - port: 8081 targetPort: 8081 name: management selector: app: spring-boot-app type: NodePort

ご覧の通り、サービス設定は非常にシンプルです。ただし、この設定は公開されていません。gcloud はサービス用のロードバランサと外部 IP アドレスを自動的に作成するため、サービスタイプを LoadBalancer に設定できます。ただし、実際にはこの設定では TLS と HTTPS を適切に設定できません。サービスへのアクセスは HTTPS のみで行いたいからです。では、どうすれば実現できるでしょうか?

4. ルーティングにIngressを使用する

Kubernetes Ingress が利用可能です。比較的新しい機能ですが、非常に効果的です。LoadBalancer のようなサービスに似ていますが、カスタムルーティングルールを設定できます。以下は Ingress の設定です。

 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: spring-boot-ingress annotations: kubernetes.io/ingress.allow-http: "false" spec: tls: - secretName: your-tls-secret backend: serviceName: spring-boot-service servicePort: 8080

ご覧のとおり、kubernetes.io/ingress.allow-http: "false" を使用して、Ingress が HTTPS 接続のみを許可するように設定しています。ただし、このファイルには TLS 設定が含まれています。まず、Ingress アクセス用の SSL 証明書データを含む Secret を作成する必要があります。これは以下の設定で実行できます。

5. 秘密

apiVersion: v1 data: tls.crt: #base64 hash of your cert tls.key: #base64 hash of your key kind: Secret metadata: name: your-tls-secret namespace: default type: Opaque

すべての設定を適用したら、`kubectl get ingress spring-boot-ingress` コマンドを使用してアプリケーションの外部IPアドレスを確認できます。HTTPS経由でアクセスすると、Spring BootアプリケーションがKubernetesクラスター上で実行されていることがわかります。

重要!Kubernetesサービスは、デフォルトのポッドポートとエンドポイント「/」でヘルスチェックを実行します。このエンドポイントをマッピングしていない場合、または保護されている場合は、livenessProbeおよびreadinessProbe構成に追加する必要があります。

Kubernetes 環境に慣れるために、本番環境にデプロイする前に、minikube でこれらの設定をテストすることをお勧めします。

新しいバージョンをデプロイするには、「kubectl set image deployment/spring-boot-deployment spring-boot-app=your-new-image」を使用するか、「kubectl edit deployment spring-boot-deployment」を使用して設定を編集します。2つ目のコマンドを使用すると、イメージとPodの数を同時に更新できます。アプリケーションのスケーリングのみを行う場合は、「kubectl scale deployment spring-boot-deployment --replicas=10」を実行するか、自動スケーリング設定を作成してください。

デプロイメントの更新はKubernetesのローリングアップデートによって行われ、すべてが自動的に処理されるためダウンタイムは発生しません。そのため、ユーザーはただ座って待つだけで済みます。インフラストラクチャをGKEに切り替えることで、アプリケーションの健全性への懸念が軽減され、開発に集中できるようになります。Kubernetesは、Jenkins、GitLab CI、BitBucket PipelinesなどのCIツールとも非常に簡単に連携できます。