★微服務系列
微服務1:微服務及其演進史
微服務2:微服務全景架構
微服務3:微服務拆分策略
微服務4:服務註冊與發現
微服務5:服務註冊與發現(實踐篇)
微服務6:通訊之閘道器
微服務7:通訊之RPC
微服務8:通訊之RPC實踐篇(附原始碼)
微服務9:服務治理來保證高可用
微服務10:系統服務熔斷、限流
微服務11:熔斷、降級的Hystrix實現(附原始碼)
微服務12:流量策略
微服務13:雲基礎場景下流量策略實現原理
微服務14:微服務治理之重試
微服務15:微服務治理之超時
微服務16:微服務治理之熔斷、限流
1 介紹
大家都知道,一個主機(或稱為節點)可以部署多個Pod,Pod作為Kubernetes中的最小部署單元。是一組一個或多個緊密關聯的容器的集合,它們共享相同的網路名稱空間和儲存卷。
一般來說,服務上雲之後,我們的服務會配置 anti-affinity(反親和排程),他有哪些利弊權衡呢:
- affinity 可以實現就近部署,增強網路能力實現通訊上的就近路由,減少網路的損耗。如同一個BCC聚類多個例項Pod。
- anti-affinity 反親和性主要是出於高可靠性考慮,儘量分散例項Pod,某個節點故障的時候,對應用的影響只是 N 分之一或者單例項。
所以,最終的部署結構可能是:
同一個服務(如 Service A)的例項不會部署在同一個主機節點上(Node),即Node1上不會同時存在 Service-A-Ins1 和 Service-A-Ins2,這就好比如把雞蛋分在不同的籃子裡,不會因為一個主機節點故障導致全盤失敗的風險。
但是依然不能解決一個問題,就是主機上可能部署了別的服務,如Service-A和B、C、D混部,雖然你們執行在不同的主機上,但是如果因為BCD服務導致的故障把整個主機節點都拖垮了,依然會影響你們的穩定性,至少是你們某個例項的穩定性。
所以需要強有力的解決方案來高保你們服務健壯存活著。
2 例項異常之後的解決方案
2.1 對叢集的異常例項進行驅逐
下面以Istio為例子說明
服務混部模型下,經常會因為某一個或者某幾個例項的故障而導致整個服務可用性降低。適當的把故障的例項短暫的驅逐出叢集,可以保證整個叢集的健康。
★ 這種手段在雲基礎上我們稱之為離群檢測(Outlier Detection):
當叢集中的服務故障的時候,其實我們最優先的做法是先進行離群,然後再檢查問題,處理問題並恢復故障。所以,能否快速的離群對系統的可用性很重要。
Outlier Detection 允許你對上游的服務進行掃描,然後根據你設定的引數來判斷是否對服務進行離群。
下面的配置表示每秒鐘掃描一次上游主機,連續失敗 2 次返回 5xx 錯誤碼的所有主機會被移出負載均衡連線池 3 分鐘,上游被離群的主機在叢集中佔比不應該超過10%。
但無論比例多少,只要你叢集下的服務例項>=2個,都將彈出至少1個主機。它有很詳細的配置,參考。
注意:3分鐘之後回群,如果再被離群,則為上次離群時間+本次離群時間,即 3+3;預設恐慌閾值為0,不啟用,建議設定30%(可調整比例)被離群,進入恐慌模式,不再驅逐。
outlierDetection:
consecutiveErrors: 2
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 10
2.2 單(例項)節點的長時間故障不可用
當一個叢集例項保持長時間的異常,或者說在指定時間驅逐迴歸之後依然是異常狀態,則說明該例項的環境(或者該例項所屬的主機環境)始終保持在一個不健康的狀態。
比較好的自愈辦法是:隔離並摘除流量,重啟之後排程在另一臺主機上去建立一個新例項,重新引入流量,達到故障恢復的目的。
例項容器重建能力一般是採用容器健康探針來進行摘流和重啟。需要注意的是,極端異常會引發批次重啟,這其實是個缺陷。
解決方案是PDB(Pod Disruption Budget),它負責中斷預算,避免過度重啟導致問題!PDB的作用就是透過控制 minAvailable(maxUnavailable)來控制存活的Pod例項,低於這個數,無論如何都不讓重啟了。
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: svc-a-pdb
spec:
minAvailable: 8 #svc-a至少要有8個例項是存活著得
selector:
matchLabels:
app: svc-a
3 總結
雲基礎場景下的多副本服務的單個副本出故障或者異常的現象在業內還是很常見的,這邊講解了初級版的異常驅逐和容器重啟,
而且這種驅逐和重啟是在平滑下執行的,對使用者無感,讓使用者有一個更優良的使用體驗。
在後續的章節我們在瞭解下大叢集模式下的高可用架構怎麼設計。