1. 序章

このチュートリアルでは、 Kubernetes プローブについて説明し、アクチュエータHealthIndicatorを活用する方法を示します。アプリケーションの状態を正確に把握できます。

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

2. Kubernetesプローブ

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

2.1. 活気と準備

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

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

  • Readys Readyness は、Podがトラフィックの受信を開始する準備ができているかどうかを確認します。 すべてのコンテナの準備が整うと、 P odの準備が整います。
  • Liveness readiness とは異なり、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 –コンテナーを作成した後、プローブを開始する前にn秒待機します
  • periodSeconds このプローブを実行する頻度、デフォルトは10秒。 最小は1秒です
  • timeoutSeconds プローブをタイムアウトするまでの待機時間、デフォルトは1秒。 最小値も1秒です
  • failureThreshold をあきらめる前にをn回試してください。 準備の場合、ポッドは準備ができていないとマークされますが、活性の場合、あきらめることはポッドを再起動することを意味します。 ここでのデフォルトは3回の失敗で、最小は1回です。
  • successThreshold –これは、失敗した後に成功したと見なされるプローブの連続成功の最小数です。 デフォルトは1回の成功で、最小値も1です。

この場合、 tcpプローブを選択しましたが、、他のタイプのプローブも使用できます。

2.2. プローブタイプ

ユースケースによっては、一方のプローブタイプがもう一方のプローブタイプよりも役立つ場合があります。 たとえば、コンテナがWebサーバーの場合、httpプローブを使用するとtcpプローブよりも信頼性が高くなる可能性があります。

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

  • exec コンテナでbash命令を実行します。 たとえば、特定のファイルが存在することを確認します。 命令が失敗コードを返す場合、プローブは失敗します
  • tcpSocket –指定されたポートを使用して、コンテナーへのtcp接続を確立しようとします。 接続の確立に失敗した場合、プローブは失敗します
  • httpGet コンテナで実行され、指定されたポートでリッスンしているサーバーにHTTPGETリクエストを送信します。 200以上400未満のコードは成功を示します

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

  • host –接続するホスト名。デフォルトはポッドのIPです。
  • schema –接続に使用するスキーム。HTTPまたはHTTPS、デフォルトはHTTPです。
  • path –Webサーバーでアクセスするためのパス
  • httpHeaders –リクエストで設定するカスタムヘッダー
  • port –コンテナ内でアクセスするポートの名前または番号

3. SpringActuatorとKubernetesの自己修復機能

Kubernetes がアプリケーションが壊れた状態にあるかどうかを検出する方法についての一般的な考え方がわかったので、 we can takeを見てみましょう。 利点of Springのアクチュエータは、アプリケーションだけでなくも監視します。その依存関係について!

これらの例では、Minikubeを使用します。

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

Springに多数のHealthIndicatorが用意されていることを考えると、 Kubernetes のプローブに対するアプリケーションの依存関係の状態を反映するのは、を追加するのと同じくらい簡単です。 pom.xml:へのアクチュエータの依存関係

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

3.2. 活気の例

正常に起動するアプリケーションから始めましょう。30遷移 to a broken state

boolean変数がtrueであるかどうかを検証する、HealthIndicator 作成することにより、壊れた状態をエミュレートします。 変数を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

アクチュエータの正常性エンドポイントを指すhttpGetプローブを使用しています。アプリケーションの状態(およびその依存関係)への変更は、展開の正常性に反映されます。

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

Podkubectl describe pod liveness-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デプロイメントの健全性に反映する方法を説明しました。

別のユースケースで使用してみましょう。アプリケーションa bit of timeを必要としているとします。 ] beforeそれは可能から受信トラフィックです。 たとえば、ファイルをメモリにロードし、その内容を検証する必要があります。

これは、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秒かかることがわかっているため、readynessプローブのinitialDelaySecondsを40秒に増やしました。
  • 同様に、livenessプローブのinitialDelaySecondsを100秒に増やして、Kubernetesによって早期に強制終了されないようにしました。

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

4. 結論

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

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