KubernetesとSpring Bootによる自己修復アプリケーション

KubernetesとSpring Bootを使用した自己修復アプリケーション

1. 前書き

このチュートリアルでは、Kubernetesprobesについて説明し、ActuatorHealthIndicatorを活用してアプリケーションの状態を正確に表示する方法を示します。 。

このチュートリアルでは、Spring Boot ActuatorKubernetes、およびDockerの既存の経験を前提としています。

2. クベルネテス プローブ

Kubernetesは、すべてが期待どおりに機能しているかどうかを定期的にチェックするために使用できる2つの異なるプローブ、livenessreadinessを定義します。

2.1. 活力 and 準備

LivenessおよびReadinessプローブを使用すると、Kubeletは、何かがオフになっていることを検出するとすぐに動作し、アプリケーションのダウンタイムを最小限に抑えることができます。

どちらも同じように構成されていますが、セマンティクスが異なり、Kubeletは、トリガーされるアクションに応じて異なるアクションを実行します。

  • ReadinessReadinessは、Podがトラフィックの受信を開始する準備ができているかどうかを確認します。 Podは、すべてのコンテナの準備ができたら準備ができています

  • Livenessreadinessとは異なり、livenessPodを再起動する必要があるかどうかを確認します。 アプリケーションは実行されているが、進行できない状態にあるユースケースをピックアップできます。たとえば、デッドロック状態にあります

コンテナレベルで両方のプローブタイプを設定します。

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
      timeoutSeconds: 2
      failureThreshold: 1
      successThreshold: 1
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20
      timeoutSeconds: 2
      failureThreshold: 1
      successThreshold: 1

プローブの動作をより正確に制御するために設定できるフィールドがいくつかあります。

  • initialDelaySeconds –コンテナの作成後、wait seconds before initiating the probe

  • periodSecondsHow often this probe should be run、デフォルトは10秒。最小は1秒です

  • timeoutSeconds –プローブをタイムアウトする前のHow long we wait。デフォルトは1秒。最小値は再び1秒です

  • failureThresholdn times before giving upを試してください。 readinessの場合、ポッドは準備ができていないとマークされますが、livenessの場合はあきらめることは、Podを再起動することを意味します。 ここでのデフォルトは3回の失敗で、最小は1回です。

  • successThreshold –これはthe minimum number of consecutive successes for the probe to be considered successful after having failedです。 デフォルトは1成功で、最小も1です。

この場合、we opted for a tcp probe,ですが、使用できる他のタイプのプローブもあります。

2.2. Probe T * ypes *

使用例によっては、1つのプローブタイプが他のプローブタイプよりも有用であることがわかります。 たとえば、コンテナがウェブサーバーの場合、httpプローブを使用すると、tcpプローブよりも信頼性が高くなる可能性があります。

幸い、Kubernetesには、使用できる3種類のプローブがあります。

  • execExecutes bash instructions in our container。 たとえば、特定のファイルが存在することを確認します。 命令が失敗コードを返す場合、プローブは失敗します

  • tcpSocketestablish a tcp connection to the container, using the specified portを試行します。 接続の確立に失敗すると、プローブは失敗します

  • httpGet –コンテナで実行され、指定されたポートでリッスンしているSends an HTTP GET request to the server。 200以上400未満のコードは成功を示します

HTTPプローブには、前述のフィールドに加えて、追加のフィールドがあることに注意してください。

  • host –接続するホスト名。デフォルトはポッドのIPです。

  • scheme –接続に使用する必要のあるスキーム(HTTPまたはHTTPS)。デフォルトはHTTPです。

  • path –Webサーバーでアクセスするためのパス

  • httpHeaders –リクエストに設定するカスタムヘッダー

  • port –コンテナ内でアクセスするポートの名前または番号

3. 春 アクチュエータ and クベルネテス 自己回復 能力

アプリケーションが壊れた状態にあるかどうかをKubernetesがどのように検出できるかについての一般的な考え方がわかったので、wecantakeadvantageを見てみましょう。 ofSpring’sActuatorは、目を近づけますnot only on our application but also on its dependencies!

これらの例では、Minikubeに依存します。

3.1. アクチュエータとそのHealthIndicators

Springにはすぐに使用できるHealthIndicatorsがいくつかあることを考えると、Kubernetesのプローブに対するアプリケーションの依存関係の状態を反映することは、Actuatorの依存関係をpom.xml:


    org.springframework.boot
    spring-boot-starter-actuator

3.2. 活気の例

正常に起動するアプリケーションから始めましょう。after30secondswilltransitiontoa%(t7 )sstate

壊れた状態をcreating a HealthIndicatorでエミュレートし、boolean変数がtrueであるかどうかを確認します。 変数をtrueに初期化し、30秒後にfalseに変更するタスクをスケジュールします。

@Component
public class CustomHealthIndicator implements HealthIndicator {

    private boolean isHealthy = true;

    public CustomHealthIndicator() {
        ScheduledExecutorService scheduled =
          Executors.newSingleThreadScheduledExecutor();
        scheduled.schedule(() -> {
            isHealthy = false;
        }, 30, TimeUnit.SECONDS);
    }

    @Override
    public Health health() {
        return isHealthy ? Health.up().build() : Health.down().build();
    }
}

HealthIndicatorを配置したら、アプリケーションをドッキングする必要があります。

FROM openjdk:8-jdk-alpine
RUN mkdir -p /usr/opt/service
COPY target/*.jar /usr/opt/service/service.jar
EXPOSE 8080
ENTRYPOINT exec java -jar /usr/opt/service/service.jar

次に、Kubernetesテンプレートを作成します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: liveness-example
spec:
  ...
    spec:
      containers:
      - name: liveness-example
        image: dbdock/liveness-example:1.0.0
        ...
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          timeoutSeconds: 2
          periodSeconds: 3
          failureThreshold: 1
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 20
          timeoutSeconds: 2
          periodSeconds: 8
          failureThreshold: 1

We’re using an httpGet probe pointing to Actuator’s health endpoint.アプリケーションの状態(およびその依存関係)への変更は、デプロイメントの正常性に反映されます。

アプリケーションをKubernetesにデプロイすると、両方のプローブが動作していることを確認できます。約30秒後、Podは準備ができていないものとしてマークされ、ローテーションから削除されます。数秒後、Podが再起動されます。

Podkubectldescribepodliveness-exampleを実行しているイベントを確認できます。

Warning  Unhealthy 3s (x2 over 7s)   kubelet, minikube  Readiness probe failed: HTTP probe failed ...
Warning  Unhealthy 1s                kubelet, minikube  Liveness probe failed: HTTP probe failed ...
Normal   Killing   0s                kubelet, minikube  Killing container with id ...

3.3. 準備の例

前の例では、HealthIndicatorを使用して、Kubernetesデプロイメントの正常性に関するアプリケーションの状態を反映する方法を確認しました。

別のユースケースで使用してみましょう。アプリケーションneedsabitoftimebeforeit’sabletoreceivetraffic。 たとえば、ファイルをメモリにロードし、そのコンテンツを検証する必要があります。

これは、readinessプローブを利用できる良い例です。

前の例のHealthIndicatorテンプレートとKubernetesテンプレートを変更して、次のユースケースに適合させましょう。

@Component
public class CustomHealthIndicator implements HealthIndicator {

    private boolean isHealthy = false;

    public CustomHealthIndicator() {
        ScheduledExecutorService scheduled =
          Executors.newSingleThreadScheduledExecutor();
        scheduled.schedule(() -> {
            isHealthy = true;
        }, 40, TimeUnit.SECONDS);
    }

    @Override
    public Health health() {
        return isHealthy ? Health.up().build() : Health.down().build();
    }
}

変数をfalseに初期化し、40秒後にタスクが実行され、true.に設定されます。

次に、次のテンプレートを使用してアプリケーションをドッキングしてデプロイします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: readiness-example
spec:
  ...
    spec:
      containers:
      - name: readiness-example
        image: dbdock/readiness-example:1.0.0
        ...
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 40
          timeoutSeconds: 2
          periodSeconds: 3
          failureThreshold: 2
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 100
          timeoutSeconds: 2
          periodSeconds: 8
          failureThreshold: 1

似ていますが、指摘する必要があるプローブ設定にはいくつかの変更があります。

  • アプリケーションがトラフィックを受信できるようになるまでに約40秒かかることがわかっているため、readinessプローブのinitialDelaySecondsを40秒に増やしました。

  • 同様に、Kubernetesによって早期に強制終了されないように、livenessプローブのinitialDelaySecondsを100秒に増やしました。

40秒経っても終了しない場合は、約60秒で終了します。 その後、livenessプローブが起動し、Pod.を再起動します

4. 結論

この記事では、Kubernetesプローブと、SpringのActuatorを使用してアプリケーションのヘルスモニタリングを改善する方法について説明しました。

これらの例の完全な実装は、over on Githubにあります。