Kubernetes探針踩坑記

有態度的小碼甲發表於2020-09-13

1. 荒腔走板

最近一兩個月生產K8s叢集頻繁出現短時503 Service Temporarily Unavailable,還不能主動復現,相當鬱悶,壓力山大。

HTTP 5xx響應狀態碼用於定義服務端錯誤。

  • 500 Internal Server Error: 所請求的伺服器遇到意外的情況並阻止其執行請求,通常針對單個請求,整個站點有時還是提供服務。
  • 502 Bad Gateway Error 暗示連線鏈路中某個伺服器下線或者不可用;
  • 503 Service Unavailable 意味著託管您的應用程式的實際Web伺服器上存在問題。

2. 排查記錄

  • 基本上每隔2-3天出現一次,每次2-3分鐘,此時整站503;
  • 因為不能主動復現,8月26日排查相應時間段的EFK日誌: impala連線問題,大資料運維同事排查到webapp發起impala的請求與impala叢集時鐘未對齊,導致webapp impalaODBC Driver連不上impala叢集;

進入k8s叢集節點,確實部分節點的時鐘對齊服務未啟動,不定時出現比北京時間慢2,3分鐘的情況,這個確實可以解釋時間差導致的impala連線認證失敗。

  • 8月26日同步所有k8s節點的時鐘,之後接近一週,並未出現問題;
  • 9月3日又出現一次短時503無服務,EFK日誌顯示依舊是impala連線問題,此處大資料同事未能定位具體原因,暫時定義為偶發/抖動

3.思考和推演

故障現場每次只有impala連線問題,我也搞不懂impala連線問題竟然會導致webapp serice下線。

我們的webapp兼具toB和toC業務,站點強相關於mongodb、 弱相關於impala:impala即使連不上,只是不能查,站點sso+訂單相關的寫入操作應該還可用。

回想起前幾天看到的k8s探針,糟糕,我們的就緒探針好像探測了impala

// ASP.NetCore上暴露的的探測邏輯: impala && mongodb
services.AddHealthChecks()
       .AddCheck<ImpalaHealthCheck>(nameof(ImpalaHealthCheck), tags: new[] { "readyz" })
       .AddCheck<MongoHealthCheck>(nameof(MongoHealthCheck), tags: new[] { "readyz" });
       
app.UseHealthChecks("/readyz", new HealthCheckOptions
  {
      Predicate = (check) => check.Tags.Contains("readyz")
  });

強烈推測是: 就緒探針3次探測impala失敗,Pod將會被標記為Unready,該Pod將從webapp服務負載均衡器移除,不再分配流量,導致nginx無實際意義的後端服務,站點503。

迅速找一個beta環境,斷開impala連線,驗證猜想。

4.問題回顧

bugfix不是我正向推斷出來的,而是純靠經驗推演出來的,倒不是有明確推斷思路,也算給大家提前踩坑了。

docker的健康檢查只能探測,K83存活、就緒探針不僅有探測,還有決策能力。

這裡我們的k8s就緒探測使用策略出現了問題:
webapp的弱依賴impala有問題,而下線了整個webapp服務,我們應該只探測強依賴,強依賴有問題,才表明容器未就緒,這也是就緒探針的初衷

強烈建議根據webapp結構合理設定探針引數,避免不切實際的認定失敗導致的頻繁重啟或服務下線。