1. 概要

このチュートリアルでは、 Spring Boot 2.3Kubernetesプローブとどのように統合され、さらに快適なクラウドネイティブエクスペリエンスを作成するかを確認します。

まず、Kubernetesプローブの背景について少し説明します。 次に、ギアを切り替えて、Spring Boot2.3がこれらのプローブをどのようにサポートするかを確認します。

2. Kubernetesプローブ

オーケストレーションプラットフォームとしてKubernetesを使用する場合、各ノードの kubelet は、そのノードのポッドを正常に保つ役割を果たします。

たとえば、アプリがリクエストを受け入れるまでに少し時間がかかる場合があります。 kubeletは、アプリケーションが準備ができたときにのみリクエストを受信するようにすることができます。 また、ポッドのメインプロセスが何らかの理由でクラッシュした場合、kubeletはコンテナを再起動します。

これらの責任を果たすために、Kubernetesには2つのプローブがあります。活性プローブと準備プローブです。

kubeletは、準備プローブを使用して、アプリケーションが要求を受け入れる準備ができているかどうかを判断します。より具体的には、ポッドは、すべてのコンテナーの準備ができたときに準備ができています。

同様に、 kubeletは、ライブネスプローブを介してポッドがまだ生きているかどうかを確認できます。 基本的に、活性プローブは、kubeletがいつコンテナを再起動する必要があるかを知るのに役立ちます。

概念に慣れてきたので、Spring Boot統合がどのように機能するかを見てみましょう。

3. アクチュエータの活気と準備

Spring Boot 2.3以降、LivenessStateHealthIndicatorおよびReadinessStateHealthIndicatorクラスは、アプリケーションの活性と準備状態を公開します。 アプリケーションをKubernetesにデプロイすると、SpringBootはこれらのヘルスインジケーターを自動的に登録します。

その結果、 / actuator / health /livenessおよび/actuator / health / readiness エンドポイントを、それぞれ活性および準備プローブとして使用できます。

たとえば、これらをポッド定義に追加して、活性プローブをHTTPGETリクエストとして構成できます。

livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
    initialDelaySeconds: 3
    periodSeconds: 3

通常、これらのプローブをいつ立ち上げるかはSpring Bootに決定させます。 ただし、必要に応じて、application.properties。で手動で有効にすることができます。

Spring Boot 2.3.0または2.3.1を使用している場合は、構成プロパティを使用して上記のプローブを有効にできます。

management.health.probes.enabled=true

ただし、 Spring Boot 2.3.2以降、構成の混乱のため、このプロパティは非推奨になりました。

Spring Boot 2.3.2を使用する場合、新しいプロパティを使用して、活性と準備のプローブを有効にできます。

management.endpoint.health.probes.enabled=true
management.health.livenessState.enabled=true
management.health.readinessState.enabled=true

3.1. 準備と活気の状態の遷移

Spring Bootは、2つの列挙型を使用して、さまざまな準備状態と活性状態をカプセル化します。 準備状態の場合、次の値を持つReadyStateと呼ばれる列挙型があります。

  • ACCEPTING_TRAFFIC 状態は、アプリケーションがトラフィックを受け入れる準備ができていることを表します
  • REFUSING_TRAFFIC 状態は、アプリケーションがまだリクエストを受け入れないことを意味します

同様に、 LivenessState enumは、アプリの活性状態を2つの値で表します。

  • CORRECT 値は、アプリケーションが実行中であり、その内部状態が正しいことを意味します
  • 一方、 BROKEN の値は、アプリケーションが実行中であり、致命的な障害が発生していることを意味します。

Springのアプリケーションライフサイクルイベントに関して、準備状態と活性状態がどのように変化するかを次に示します。

  1. リスナーと初期化子の登録
  2. 環境の準備
  3. ApplicationContextの準備
  4. Bean定義のロード
  5. 活性状態をCORRECTに変更します
  6. アプリケーションとコマンドラインランナーの呼び出し
  7. 準備状態をACCEPTING_TRAFFICに変更します

アプリケーションが起動して実行されると、適切な AvailabilityChangeEvents を公開することで、これらの状態を変更できます。

4. アプリケーションの可用性の管理

アプリケーションコンポーネントは、 ApplicationAvailability インターフェイスを挿入することにより、現在の準備状態と活性状態を取得できます。

@Autowired private ApplicationAvailability applicationAvailability;

次に、次のように使用できます。

assertThat(applicationAvailability.getLivenessState())
  .isEqualTo(LivenessState.CORRECT);
assertThat(applicationAvailability.getReadinessState())
  .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
assertThat(applicationAvailability.getState(ReadinessState.class))
  .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);

4.1. 可用性状態の更新

AvailabilityChangeEvent イベントを公開することで、アプリケーションの状態を更新することもできます。

assertThat(applicationAvailability.getLivenessState())
  .isEqualTo(LivenessState.CORRECT);
mockMvc.perform(get("/actuator/health/liveness"))
  .andExpect(status().isOk())
  .andExpect(jsonPath("$.status").value("UP"));

AvailabilityChangeEvent.publish(context, LivenessState.BROKEN);

assertThat(applicationAvailability.getLivenessState())
  .isEqualTo(LivenessState.BROKEN);
mockMvc.perform(get("/actuator/health/liveness"))
  .andExpect(status().isServiceUnavailable())
  .andExpect(jsonPath("$.status").value("DOWN"));

上記のように、イベントを公開する前に、 /アクチュエータ/ヘルス/ライブネスエンドポイントは、次のJSONで200OK応答を返します。

{
    "status": "OK"
}

次に、活性状態を解除した後、同じエンドポイントが次のJSONで503サービス利用不可応答を返します。

{
    "status": "DOWN"
}

REFUSING_TRAFFICの準備状態に変更すると、ステータスの値はOUT_OF_SERVICE:になります。

assertThat(applicationAvailability.getReadinessState())
  .isEqualTo(ReadinessState.ACCEPTING_TRAFFIC);
mockMvc.perform(get("/actuator/health/readiness"))
  .andExpect(status().isOk())
  .andExpect(jsonPath("$.status").value("UP"));

AvailabilityChangeEvent.publish(context, ReadinessState.REFUSING_TRAFFIC);

assertThat(applicationAvailability.getReadinessState())
  .isEqualTo(ReadinessState.REFUSING_TRAFFIC);
mockMvc.perform(get("/actuator/health/readiness"))
  .andExpect(status().isServiceUnavailable())
  .andExpect(jsonPath("$.status").value("OUT_OF_SERVICE"));

4.2. 変化に耳を傾ける

アプリケーションの可用性状態が変化したときに通知されるイベントリスナーを登録できます。

@Component
public class LivenessEventListener {
    
    @EventListener
    public void onEvent(AvailabilityChangeEvent<LivenessState> event) {
        switch (event.getState()) {
        case BROKEN:
            // notify others
            break;
        case CORRECT:
            // we're back
        }
    }
}

ここでは、アプリケーションの活性状態の変化をリッスンしています。

5. 自動構成

まとめる前に、Spring BootがKubernetesデプロイメントでこれらのプローブを自動的に構成する方法を見てみましょう。 AvailabilityProbesAutoConfiguration クラスは、活性および準備プローブを条件付きで登録する役割を果たします。

実際のところ、次のいずれかが trueの場合にプローブを登録する特別な条件があります:

  • Kubernetesはデプロイ環境です
  • management.health.probes.enabledプロパティがtrueに設定されています

アプリケーションがこれらの条件のいずれかを満たすと、自動構成はLivenessStateHealthIndicatorおよびReadinessStateHealthIndicator。のBeanを登録します。

6. 結論

この記事では、SpringBootを使用してKubernetes統合用の2つのヘルスプローブを提供する方法を説明しました。

いつものように、すべての例はGitHubから入手できます。