Kubernetes 存活、就緒探針

在設計關鍵任務、高可用應用程序時,彈性是要考慮的最重要因素之一。web

當應用程序能夠快速從故障中恢復時,它便具備彈性。mongodb

雲原生應用程序一般設計爲使用微服務架構,其中每一個組件都位於容器中。爲了確保Kubernetes託管的應用程序高可用,在設計集羣時須要遵循一些特定的模式,其中有「健康探測模式」。應用高可觀察性原則(HOP)可確保您的應用程序收到的每一個請求都能及時找到響應。api

The High Observability Principle (HOP)

高可觀察性原則是基於容器的應用程序設計原則之一。微服務體系要求每一個服務不關心(也不該該關心)被調用方如何處理請求。
HOP原則要求每一個服務必須公開幾個API端點,其意義在於揭示服務健康狀態,Kubernetes調用這些端點,決定下一步的路由和負載平衡架構

設計良好的雲原生程序應將日誌事件記錄到STDERR和STDOUT,由logstash、Fluent等日誌攝取服務將這些日誌運送到集中式監控(例如Prometheus)和日誌聚合系統(例如ELK)。下圖說明了雲原生應用程序如何遵照健康情況探測模式和高可觀察性原則。
app

How to Apply Health Probe Pattern in Kubernetes?

我以前寫過ASP.NetCore + Docker健康檢查的原創:[web程序暴露http健康檢查端點,平臺輪詢探測],Kubernetes針對不一樣場合細化了探針,更爲強大的是給出對應決策。負載均衡

Liveness Probes

使用[存活探針]判斷何時重啓容器。
使用存活探針檢查容器自己是否無響應、死鎖, 有時候重啓容器經常能解決此類問題。async

咱們以kubernetes官方demo爲例:ide

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5   # 指示kubectl等待5s才執行首次探測
      periodSeconds: 5         # 間隔5秒輪詢
  • 在第5秒kubectl開始首次liveness探測
  • 在30秒進行的每次探測均成功
  • 30s以後容器內文件被刪除,以後間隔5s的探測會失敗,根據liveness默認配置連續3次失敗就會放棄探測,放棄探測意味着重啓容器,故容器會在第45s重啓
  • 重啓以後又開始以上流程, 故能夠看到此探針以重啓的決策嘗試修復應用問題。

這個探針會體現到kubectl get podRESTARTS
微服務

Readiness Probes

使用[就緒探針]判斷容器是否就緒,是否能夠接受流量。
Pod內全部容器ready,則該Pod被認爲ready,當pod沒有ready,將會從服務負載均衡中移除。設計

有些時候,應用程序臨時不可用(加載大量數據或者依賴外部服務),這個時候,重啓這個Pod無濟於事,同時你也不但願請求被髮送到該Pod

下面的應用強依賴mongodb,咱們針對這些依賴項設置了readiness探針

services.AddHealthChecks()
    .AddCheck<MongoHealthCheck>(nameof(MongoHealthCheck), tags: new[] { "readyz" });
// ----------------------
app.UseHealthChecks("/readyz", new HealthCheckOptions
{
        Predicate = (check) => check.Tags.Contains("readyz")
});

如下是探測Mongodb的連通性

sealed class MongoHealthCheck : IHealthCheck
    {
        private readonly IMongoDatabase _defaultMongoDatabase;

        public MongoHealthCheck(IDefaultMongoDatabaseProvider defaultMongoDatabaseProvider)
        {
            _defaultMongoDatabase = defaultMongoDatabaseProvider.GetDatabase();
        }

        public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
        {
            var doc = await _defaultMongoDatabase.RunCommandAsync(
                new BsonDocumentCommand<BsonDocument>(
                    new BsonDocument() {
                        { "ping", "1" }
                    }), 
                cancellationToken: cancellationToken);

            var ok = doc["ok"].ToBoolean();

            if (ok)
            {
                return HealthCheckResult.Healthy("OK");
            }

            return HealthCheckResult.Unhealthy("NotOK");
        }
    }

對於依賴項的探測,探測週期和超時時間能夠設置的稍長一點

readinessProbe:
  httpGet:
    path: /readyz
    port: 80
  initialDelaySeconds: 5
  periodSeconds: 60     # 60s探測一次
  timeoutSeconds: 30    # 每次探測30s超時,與應用創建與依賴項的鏈接超時時間一致
  failureThreshold: 3   # 連續3次探測失敗,該Pod會被標記爲`Unready`

Startup Probes

使用[啓動探針]判斷容器應用是否已經啓動。若是配置了這個探針,則該探針成功以前將會禁用存活和就緒探針。

配置探針

  • initialDelaySeconds:容器啓動,探針延後工做,默認是0s
  • periodSeconds 探針探測週期,默認10s
  • timeoutSeconds: 探針工做的超時時間,默認1s
  • successThreshold: 連續幾回探測成功,該探針被認爲是成功的,默認1次
  • failureThreshold: 連續幾回探測失敗,該探針被認爲最終失敗,對於livenes探針最終失敗意味着重啓,對於readiness探針意味着該pod Unready, 默認3次。

強烈建議根據應用結構合理設置探針參數,避免不切實際的認定失敗致使的頻繁重啓或 Unready

結論:

Kubernetes生態這麼龐大,爲啥單獨拎出k8s探針, 是由於k8s探針是與應用程序結構密切相關的機制。
就使用方式看:

存活探針:用於快速判斷應用進程是否無響應,嘗試重啓修復;

就緒探針:判斷應用及依賴項是否就緒,是否能夠分配流量,若是不能就標記Unready,從負載均衡器中移除該Pod

Kubernetes存活、就緒探針能夠極大地提升服務的健壯性和彈性,並提供出色的最終用戶體驗。

相關文章
相關標籤/搜索