KubernetesとSpringBootを使用した自己修復アプリケーション
1. 序章
このチュートリアルでは、 Kubernetes のプローブについて説明し、アクチュエータのHealthIndicatorを活用する方法を示します。アプリケーションの状態を正確に把握できます。
このチュートリアルでは、 Spring Bootアクチュエータ、 Kubernetes 、およびDockerの既存の経験を前提としています。
2. Kubernetesプローブ
Kubernetes は、すべてが期待どおりに機能しているかどうかを定期的にチェックするために使用できる2つの異なるプローブを定義します。livenessとreadinessです。
2.1. 活気と準備
LivenessおよびReadinessプローブを使用すると、 Kubelet は、何かがオフになっていることを検出するとすぐに動作し、アプリケーションのダウンタイムを最小限に抑えることができます。
どちらも同じように構成されていますが、セマンティクスが異なり、 Kubelet は、トリガーされるアクションに応じて異なるアクションを実行します。
- Readys – Readyness は、Podがトラフィックの受信を開始する準備ができているかどうかを確認します。 すべてのコンテナの準備が整うと、 P odの準備が整います。
- 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 –コンテナーを作成した後、プローブを開始する前に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 は準備ができていないものとしてマークされ、ローテーションから削除されます。 数秒後、ポッドが再起動します。
Podがkubectl 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のにあります。