在設計關鍵任務、高可用應用程序時,彈性是要考慮的最重要因素之一。web
當應用程序能夠快速從故障中恢復時,它便具備彈性。mongodb
雲原生應用程序一般設計爲使用微服務架構,其中每一個組件都位於容器中。爲了確保Kubernetes託管的應用程序高可用,在設計集羣時須要遵循一些特定的模式,其中有「健康探測模式」。應用高可觀察性原則(HOP)可確保您的應用程序收到的每一個請求都能及時找到響應。api
高可觀察性原則是基於容器的應用程序設計原則之一。微服務體系要求每一個服務不關心(也不該該關心)被調用方如何處理請求。
HOP原則要求每一個服務必須公開幾個API端點,其意義在於揭示服務健康狀態,Kubernetes調用這些端點,決定下一步的路由和負載平衡。架構
設計良好的雲原生程序應將日誌事件記錄到STDERR和STDOUT,由logstash、Fluent等日誌攝取服務將這些日誌運送到集中式監控(例如Prometheus)和日誌聚合系統(例如ELK)。下圖說明了雲原生應用程序如何遵照健康情況探測模式和高可觀察性原則。
app
我以前寫過ASP.NetCore + Docker健康檢查的原創:[web程序暴露http健康檢查端點,平臺輪詢探測],Kubernetes針對不一樣場合細化了探針,更爲強大的是給出對應決策。負載均衡
使用[存活探針]判斷何時重啓容器。
使用存活探針檢查容器自己是否無響應、死鎖, 有時候重啓容器經常能解決此類問題。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秒輪詢
這個探針會體現到kubectl get pod
的RESTARTS
列
微服務
使用[就緒探針]判斷容器是否就緒,是否能夠接受流量。
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`
使用[啓動探針]判斷容器應用是否已經啓動。若是配置了這個探針,則該探針成功以前將會禁用存活和就緒探針。
強烈建議根據應用結構合理設置探針參數,避免不切實際的認定失敗致使的頻繁重啓或 Unready。
Kubernetes生態這麼龐大,爲啥單獨拎出k8s探針, 是由於k8s探針是與應用程序結構密切相關的機制。
就使用方式看:
存活探針:用於快速判斷應用進程是否無響應,嘗試重啓修復;
就緒探針:判斷應用及依賴項是否就緒,是否能夠分配流量,若是不能就標記Unready,從負載均衡器中移除該Pod
Kubernetes存活、就緒探針能夠極大地提升服務的健壯性和彈性,並提供出色的最終用戶體驗。