k8s集群StatefulSets的Pod調度查詢丟失問題?
考點之簡單介紹下StatefulSets 和 Deployment 之間有什么本質區別?特定場景該如何做出選擇呢?
考點之你能辯證的說說看StatefulSets 和 Deployment具體有哪些區別嘛?
考點之你了解k8s集群StatefulSets的Pod調度查詢丟失問題嗎?k8s集群中StatefulSet管理的Pod已經完成調度并啟動,為什么還是無法查詢Pod 的 DNS 命名?

囧么肥事-胡說八道


簡單介紹下StatefulSets 和 Deployment 之間有什么本質區別?
首先、StatefulSet 和Deployment 都是用來管理應用的作業負載 API 物件,都管理基于各自相同容器規約的一組 Pod,同時負責各自管理的Pod 集合的部署和擴縮、更新回滾等,
但和 Deployment 本質上不同的是,StatefulSets 用來管理有狀態應用,而Deployment 負責管理無狀態應用,
如果應用程式不需要任何穩定的識別符號或有序的部署、洗掉或伸縮,則應該使用 由一組無狀態的副本控制器提供的作業負載來部署應用程式,比如 Deployment或者ReplicaSet,
如果希望使用存盤卷為作業負載提供持久存盤,可以使用 StatefulSet 作為解決方案的一部分,
盡管 StatefulSet 中的單個 Pod 仍可能出現故障, 但持久的 Pod 識別符號 可以更容易將現有卷與于重新調度的Pod進行系結,
說道這里,下面簡單介紹一下,應用分類:
應用通常可以分為兩大類:有狀態與無狀態
無狀態應用
簡單理解就是沒有特殊狀態的服務
服務和資料分離,本身不存盤資料
各個請求對于服務器來說統一無差別處理
請求可以隨機發送到任意一臺server上
請求自身攜帶了所有服務端所需要的所有引數
服務自身不存盤跟請求相關的任何資料
有狀態應用
容器資料需要持久化保持
對于有資料存盤功能的服務
每個實體都需要有自己獨立的持久化存盤
或者指多執行緒型別的服務、佇列
mysql資料庫、kafka、zookeeper等
如果server是有狀態的,客戶端需要始終把請求發到同一臺server才行,
同時,這里理解StatefulSets 兩個關鍵點:1、穩定的 2、有序的
“穩定的”意味著 Pod 調度或重調度的整個程序是有持久性的
“有序的”意味著 Pod 調度或重調度的整個程序是需要保持順序的
關于Deployment 的具體情況,可參考:【跟k8s作業負載Deployments的緣起緣滅】
你能辯證的說說看StatefulSets 和 Deployment具體有哪些區別嘛?
Deployment管理的Pod特點
Deployment被設計用來管理無狀態服務的pod,每個pod完全一致
- 無序性:無狀態服務的多個Pod副本創建和銷毀是無序的,可以并行創建或銷毀,相互之間不必等待,除了需要遵守規約中定義的副本個數之外,沒有其他制約,
- 隨機性:無狀態服務的多個Pod副本的名稱是隨機的,pod被重新啟動調度后,它的名稱與IP都會發生變化,替換為一個新的副本,
- 共享性:無狀態服務的多個Pod副本共享存盤卷,Deployment中Pod基于template定義存盤卷,所有副本集共用一個存盤卷,

StatefulSets管理的Pod特點
StatefulSets 被設計用來管理有狀態的應用,StatefulSet 管理的 Pod 具有唯一的標識,該標識包括順序標識、穩定的網路標識和穩定的存盤, 并且該標識和 Pod 是系結,不管它被調度在哪個節點上,最終都會被系結這個唯一標識,
- 唯一性:對于具有 N 個副本的 StatefulSet,它管理的每個 Pod 將被分配一個整數序號,該序號在 StatefulSet 上是唯一的,
- 順序性:順序標識、Pod 調度程序,無論是啟動、銷毀、更新都需要嚴格遵守順序,有序優雅的部署和縮放,有序自動的滾動更新,
- 穩定的網路標識:Pod主機名、DNS地址不會隨著Pod被重新調度而發生變化,
- 穩定的持久化存盤:Pod被重新調度后,不會洗掉原有的PV,重新調度成功后,繼續掛載系結原有的PV,從而保證了資料的完整性和一致性,
你了解過k8s集群StatefulSets的Pod調度查詢丟失問題嗎?
k8s集群中StatefulSet管理的Pod已經完成調度并啟動,為什么還是無法查詢Pod 的 DNS 命名?如果需要在 Pod 調度完成之后及時發現,該怎么做?
先看看StatefulSet是如何為每個Pod分配DNS的呢?
StatefulSet 中管理的每個 Pod 會根據 StatefulSet 的名稱和 以及為 Pod 的分配的有序索引(序號),派生出它的主機名,
組合主機名的格式為:
$(StatefulSet 名稱)-$(序號)
StatefulSet 使用 Headless Services 控制內部 Pod 的網路域,
通過Headless Service為Pod編號,在DNS服務器中生成帶有編號的DNS記錄,從而可以達到通過Pod名字定位到相應的服務
管理域的服務的格式為:
$(服務名稱).$(命名空間).svc.cluster.local
其中 cluster.local 是集群域, 一旦每個 Pod 創建成功,就會得到一個匹配的 DNS 子域,格式為: $(pod 名稱).$(所屬服務的 DNS 域名),其中所屬服務由 StatefulSet 的 serviceName 域來設定,
了解完分配和組成,接下來說一下為什么會出現查詢失敗的情況呢?
第一種情況,Pod尚在創建程序中,這時候查詢,DNS命名還未分配成功
第二種情況,Pod已經創建成功,取決于集群域內部 DNS 的配置,可能無法查詢一個剛剛啟動的 Pod 的 DNS 命名,原因是k8s有個負快取的概念,
負快取 (在 DNS 中較為常見)
之前失敗的查詢結果會被記錄和重用至少若干秒鐘
默認快取時長為 30s
查詢程序
第一次查詢結果是失敗
結果記錄到負快取中,標注失敗
在快取周期內查詢,直接從負快取中取,結果是失敗
如何及時發現創建的Pod的DNS命名?
如果需要在 Pod 被創建之后及時發現它們,有以下選項:
- 直接查詢
Kubernetes API(比如,利用watch機制)而不是依賴于 DNS 查詢 - 縮短
Kubernetes DNS驅動的快取時長(修改CoreDNS的ConfigMap,目前DNS快取時長為 30 秒)

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/440424.html
標籤:其他
