知識庫 / DevOps RSS 訂閱

Kubernetes 和 Spring Boot 自愈應用

Architecture,DevOps,Spring
HongKong
4
01:35 PM · Dec 06 ,2025

1. 引言

在本教程中,我們將討論 Kubernetes探測器probes)及其如何利用 ActuatorHealthIndicator 來準確瞭解應用程序的狀態。

為了方便本教程,我們假設您已經具備了對 Spring Boot ActuatorKubernetesDocker 的一定經驗。

2. Kubernetes 探針

Kubernetes 定義了兩種不同的探針,我們可以定期檢查它們是否按預期工作:就緒探測就緒狀態探測

2.1. 活躍性與就緒性

通過使用探針,Kubelet 可以在檢測到問題後立即啓動,從而最大限度地減少應用程序停機時間。

兩者配置方式相同,但具有不同的語義,並且Kubelet 根據觸發的不同探針執行不同的操作。

  1. ReadinessReadiness 驗證我們的Pod 是否準備好接收流量。當所有容器都已準備好時,我們的Pod 就可以接收流量。
  2. 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 次,在失敗後放棄。對於 readiness ,我們的 Pod 將被標記為不可準備就緒;而對於 liveness ,放棄意味着重啓 Pod 。 默認值為 3 次失敗,最小值為 1
  • successThreshold這是探測器被認為是成功的最小連續成功次數,在已失敗後。 默認值為 1 次成功,最小值為 1

在這種情況下,我們選擇了 tcp 探測器,但我們還可以使用其他類型的探測器。

2.2. 探測類型

根據我們的使用場景,一種探測類型可能比另一種更實用。例如,如果我們的容器是一個 Web 服務器,使用一個 http 探測可能比使用一個 tcp 探測更可靠。

幸運的是,Kubernetes 提供了三種不同的探測類型供我們使用:

  • `exec` – 在我們的容器中執行 `bash` 指令。例如,檢查是否存在特定文件。如果指令返回失敗代碼,探測將失敗
  • `tcpSocket` – 嘗試使用指定的端口建立到容器的 `tcp` 連接。如果無法建立連接,探測將失敗
  • `httpGet` – 向容器中運行並監聽指定端口的服務器發送 HTTP GET 請求。任何 200 到 400 之間的代碼都表示成功

需要注意的是,<em>HTTP</em> 探測具有除了我們之前提到的之外的額外字段:

  • `host` – 連接的 Hostname,默認值為 Pod 的 IP
  • `scheme` – 應該使用的 Scheme,`HTTP` 或 `HTTPS`,默認值為 `HTTP`
  • `path` – 用於訪問 Web 服務器的路徑
  • `httpHeaders` – 用於在請求中設置的自定義 Header
  • `port` – 用於訪問容器的端口名稱或數字

3. Spring Actuator 和 Kubernetes 自愈能力

現在我們對 Kubernetes 如何檢測應用程序是否處於故障狀態有了初步瞭解,接下來讓我們看看我們如何利用 Spring 的 Actuator 來更密切地關注應用程序及其依賴項。

為了便於這些示例,我們將依賴 Minikube

3.1. Actuator及其HealthIndicators

考慮到Spring提供了多種HealthIndicator,將應用程序的依賴項狀態反映到Kubernetes的探測器中,只需將Actuator依賴項添加到我們的pom.xml中即可。

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

3.2. 活體檢測示例

讓我們從一個正常啓動並將在 30 切換到異常狀態的應用開始。

我們將通過創建一條 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

我們正在使用一個 httpGet 探測器,指向 Actuator 的健康端點。 應用程序狀態(及其依賴項)的任何更改都將反映在部署的健康狀況上。

將我們的應用程序部署到 Kubernetes 後,我們可以看到這兩個探測器在行動:大約 30 秒後,我們的 Pod 將被標記為未就緒並從輪換中移除;幾秒鐘後, 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 部署健康狀況上的狀態。

讓我們在另一個用例中使用它:假設我們的應用程序 需要 一些 時間 能夠 接收 流量。例如,它需要將文件加載到內存中並驗證其內容。

這是一個很好的例子,説明我們如何利用 就緒探測

讓我們修改 HealthIndicatorKubernetes 模板,並將其調整為該用例:

@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

接下來,我們使用以下模板通過Docker化和部署應用程序:

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秒才能準備好接收流量,因此我們增加了 initialDelaySeconds 的值,將我們的 就緒 探測器設置為40秒。
  • 同樣,我們增加了 initialDelaySeconds 的值,將我們的 活躍性 探測器設置為100秒,以避免被 Kubernetes 提前終止。

如果40秒後仍未完成,它仍有大約60秒的時間完成。之後,我們的 活躍性 探測器將啓動並重啓 Pod

4. 結論

在本文中,我們討論了&nbsp;Kubernetes 探測器以及如何使用 Spring 的&nbsp;Actuator 來改進我們應用程序的健康監控。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.