KubernetesとSpring Bootを使用した自己修復アプリケーション
1. 前書き
このチュートリアルでは、Kubernetesのprobesについて説明し、ActuatorのHealthIndicatorを活用してアプリケーションの状態を正確に表示する方法を示します。 。
このチュートリアルでは、Spring Boot Actuator、Kubernetes、およびDockerの既存の経験を前提としています。
2. クベルネテス プローブ
Kubernetesは、すべてが期待どおりに機能しているかどうかを定期的にチェックするために使用できる2つの異なるプローブ、livenessとreadinessを定義します。
2.1. 活力 and 準備
LivenessおよびReadinessプローブを使用すると、Kubeletは、何かがオフになっていることを検出するとすぐに動作し、アプリケーションのダウンタイムを最小限に抑えることができます。
どちらも同じように構成されていますが、セマンティクスが異なり、Kubeletは、トリガーされるアクションに応じて異なるアクションを実行します。
-
Readiness –Readinessは、Podがトラフィックの受信を開始する準備ができているかどうかを確認します。 Podは、すべてのコンテナの準備ができたら準備ができています
-
Liveness –readinessとは異なり、livenessはPodを再起動する必要があるかどうかを確認します。 アプリケーションは実行されているが、進行できない状態にあるユースケースをピックアップできます。たとえば、デッドロック状態にあります
コンテナレベルで両方のプローブタイプを設定します。
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 n seconds before initiating the probe
-
periodSeconds –How often this probe should be run、デフォルトは10秒。最小は1秒です
-
timeoutSeconds –プローブをタイムアウトする前のHow long we wait。デフォルトは1秒。最小値は再び1秒です
-
failureThreshold –n 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種類のプローブがあります。
-
exec –Executes bash instructions in our container。 たとえば、特定のファイルが存在することを確認します。 命令が失敗コードを返す場合、プローブは失敗します
-
tcpSocket –establish 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が再起動されます。
Podがkubectldescribepodliveness-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にあります。