Kubernetesで運用されているアプリケーションの暖気処理をpostStartからStartup Probeに移行する方法

:::note info
これは [ZOZO Advent Calendar 2022](https://qiita.com/advent-calendar/2022/zozo) カレンダー Vol.1 の 24日目の記事です。昨日の投稿は @yyokii  さんの「[[Mac App] TCAを使ってシンプルなMacアプリを作成してみた](https://zenn.dev/yyokii/articles/create-mac-app-with-tca)」でした。
:::
## はじめに
今回は、Kubernetesで運用されているアプリケーションの暖気処理をpostStartからStartup Probeする移行する方法についてまとめていきたいと思います。

## 本記事を読むにあたっての前提条件
* 本記事で指すアプリケーションはTomcat＋SpringBootで作られたアプリケーションのことです。

* 本記事では、暖気処理をpostStartからStartup Probeに移行する方法についてまとめていこうと考えているので暖気処理については時に記述はしません。

## 実行環境
* Kubernetes環境
  - EKS
* application
  - Java 
    *  Tomcat + SpringBoot

## Kubernetesのライフサイクルについて
### postStartとは？
:::note info
postStartとは、コンテナフックでcontainerの起動直後に任意のコマンドを実行することができるものです。
ref:[コンテナライフサイクルフック](https://kubernetes.io/ja/docs/concepts/containers/container-lifecycle-hooks/)

図で表すとこんな感じ↓
![スクリーンショット 2022-12-20 18.33.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/5988df9d-fee4-0e1a-a282-996eeac8bdce.png)


<b>注意</b>
postStart場合、postStartとLiveness Probe/Rediness Probeの順序制御そのままではができません。

順序制御を行う場合には、`minReadySeconds` と `initialDelaySeconds` を設定する必要があります。



:::

### Startup Probeとは？
:::note info
Startup Probeは、コンテナ内のアプリケーションが起動したかどうかを示します。
<b>注意</b>
Startup Probeが設定された場合、完了するまでその他のすべてのProbeは無効になります。
<b>※Startup Probeが完了するまで、livenessProbe/redinessProbeが実行されることはありません。</b>
ref:[Podのライフサイクル](https://kubernetes.io/ja/docs/concepts/workloads/pods/pod-lifecycle/#container-probes)

図で表すとこんな感じ↓
![スクリーンショット 2022-12-20 18.39.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/88b7a070-2279-e344-c6a4-d16cd65ce32a.png)


:::
## postStartでの暖気処理の実行

### 設定方法

```diff_yaml:deployment.yaml(postStartフェイズでの暖気処理)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
  annotations:
    test: "test"
spec:
+  minReadySeconds: {"PodがReadyになってから利用可能になるまでの時間"}
  replicas: 1
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: sample-deployment
        image: java-application
        resources:
          limits:
            cpu: "500m"
            memory: "1.5Gi"
          readinessProbe:
            httpGet:
              path: /health/readiness
              port: {port_number}
+            initialDelaySeconds: {"初回ヘルスチェック時間までの遅延"}
            periodSeconds: {"ヘルスチェック間隔の秒数"}
            timeoutSeconds: {"タイムアウトまでの秒数"}
            successThreshold: {"成功と判断するまでのチェック回数"}
            failureThreshold: {"失敗と判断するまでのチェック回数"}
          livenessProbe:
            httpGet:
              path: /health/liveness
              port: {port_number}
+            initialDelaySeconds: {"初回ヘルスチェック時間までの遅延"}
            periodSeconds: {"ヘルスチェック間隔の秒数"}
            timeoutSeconds: {"タイムアウトまでの秒数"}
            successThreshold: {"成功と判断するまでのチェック回数"}
            failureThreshold: {"失敗と判断するまでのチェック回数"}
+        lifecycle:
+          postStart:
+            exec:
+              command:
+                - sh
+                - -c
+                - |
+                  //ここになんらかの処理を書く
+                  //今回の場合には暖気処理


```

#### 暖気処理をpostStartで行っていた時の課題
postStartフェイズで暖気処理を行おうとすると、Liveness Probe/Rediness Probeに`initalDelaySeconds`の設定を入れてLiveness Probe/Rediness Probeの開始時間を調整したり、`minReadySeconds`の設定をいれてPodがReadyになってから利用可能になるまでの時間を調整する必要があり、これらのパラメータ調整に不備があると暖気処理が終わらないままPodにリクエストが流れる可能性があることが課題でした。

![スクリーンショット 2022-12-20 18.17.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/fbc8967d-430e-3bc7-9b38-9abd79fe3e90.png)


## Startup Probeでの暖気処理の実行

### 設定方法
```diff_yaml:deployment.yaml(Startup Probeでの暖気処理)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
  annotations:
    test: "test"
spec:
-  minReadySeconds: {"PodがReadyになってから利用可能になるまでの時間"}
  replicas: 1
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: sample-deployment
        image: java-application
        resources:
          limits:
            cpu: "500m"
            memory: "1.5Gi"
+          startupProbe:
+            failureThreshold: {"失敗と判断するまでのチェック回数"}
+            periodSeconds: {"ヘルスチェック間隔の秒数"}
+            timeoutSeconds: {"タイムアウトまでの秒数"}
+            exec:
+              command:
+                - sh
+                - -c
+                - |
+                  //ここになんらかの処理を書く
+                  //今回の場合には暖気処理
          readinessProbe:
            httpGet:
              path: /health/readiness
              port: {port_number}
-           initialDelaySeconds: {"初回ヘルスチェック時間までの遅延"}
            periodSeconds: {"ヘルスチェック間隔の秒数"}
            timeoutSeconds: {"タイムアウトまでの秒数"}
            successThreshold: {"成功と判断するまでのチェック回数"}
            failureThreshold: {"失敗と判断するまでのチェック回数"}
          livenessProbe:
            httpGet:
              path: /health/liveness
              port: {port_number}
-           initialDelaySeconds: {"初回ヘルスチェック時間までの遅延"}
            periodSeconds: {"ヘルスチェック間隔の秒数"}
            timeoutSeconds: {"タイムアウトまでの秒数"}
            successThreshold: {"成功と判断するまでのチェック回数"}
            failureThreshold: {"失敗と判断するまでのチェック回数"}

```
#### 暖気処理をStartup Probeで行うメリット
postStartフェイズで暖気処理の実行は、Liveness Probe/Rediness Probeの開始時間を調整したり、PodがReadyになってから利用可能になるまでの時間を調整する必要がありましたが、Startup ProbeではLiveness Probe/Rediness Probeの開始前の処理フェイズを設定することができるため、暖気処理が終わらないままPodにリクエストが流れる可能性を排除することができます。
![スクリーンショット 2022-12-20 18.38.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567360/44097088-36ea-cb49-e7ed-11236205c5ee.png)


## まとめ
本記事では、Kubernetesで運用されているアプリケーションの暖気処理をpostStartからStartup Probeに移行する移行する方法についてまとめました。postStartからStartup Probeに移行すると`initalDelaySeconds`や`minReadySeconds`の設定が必要なくなりpostStartよりも格段に運用がしやすくなると思います。
postStartからStartup Probeに移行する際の際の参考になれば幸いです。

:::note info
明日は @sonots さんです。
:::