Categories
程式開發

雲原生虛機應用託管-設計篇


基於kubernetes託管虛機有一些現成的方案,不過今天筆者要聊的是在虛機交付後,該如何實現後續的管理,包括如何實現環境和代碼的部署與更新,感興趣的可以一起看看,本篇是設計篇

1. 虛機應用的託管

由於虛機應用交付流程鏈路的複雜性,我們無法設計一套機制,能cover住100%的異常場景,所以我們專注正常流的交付,後期可以針對異常的案例來進行複盤,不斷提高交付成功率,本節主要介紹我們設計的自動化交付流程、以及用到的k8s相關的機制

1.1 面向終態的交付

虛機應用典型的交付流程大概是這樣的:申請機器->部署環境->部署代碼->綁定監控->健康檢查->灰度上線,如果要對標容器則創建機器、部署環境、部署代碼相當於完成了一個”虛機鏡像”的交付,也是我們主要要自動化的流程

1.1.1 核心狀態機

在雲原生中通常都是基於面向終態的交付方式, 基於目標狀態和當前狀態由系統自動進行決策,我們根據現狀定義瞭如下的狀態機:

雲原生虛機應用託管-設計篇 1

這裡重點說下就緒狀態,就緒狀態表示應用的當前的部署環境、代碼完成,並且健康檢查都通過了即一個節點可以進行灰度引流了

同時如果一個應用的環境變更則會按照對應的安全頻率來進行節點環境的變更,只需要變更節點的環境列表,系統會自動發現當前節點需要進行更新,進行狀態機的轉換;然後自動化系統會發現這個變更則就會進行檢查並且自動化的進行環境的安裝

1.1.2 故障轉移

如果發現某個節點宕機後,則會由系統首先將系統設置為下線狀態(IAAS平台還不支持這個事情), 然後會根據策略來進行決策是否自動進行修復,如果需要修復則係統會新創建一個節點然後執行上述流程,否則則會修改對應的副本數量

1.1.3 准入機制

雲原生虛機應用託管-設計篇 2

為了保障穩定性我們在自動化的流程中加入准入機制,即在對應的階段允許引入人工節點來進行決策,將控制權交給應用運維,並且提供相關的數據和策略輔助提高運維決策效率

1.1.4 任務列表

那如果如何確定一個節點處於某個狀態下該做哪些任務呢?這裡其實取決於兩部分當前狀態和目標狀態,首先我們這里通過系統內部(k8s)裡面當前的狀態來進行計算以確定節點當前該處於哪個狀態,每當進入到一個狀態就會同時追加一個任務列表,controller則根據外部狀態和任務列表進行自動化操作,並更新內部狀態,從而不斷的完成不同狀態的切換,最終達到目標狀態

1.1.5 異常流程

異常流程的處理可能是所有自動化系統裡面最頭痛的了,在我們的系統裡面主要通過兩種方式來解決:人工和自動化(好像特麼的是廢話),

雲原生虛機應用託管-設計篇 3

首先來說自動化,當節點某些自動化任務無法進行時系統會通知運維,當前系統遇到無法處理的異常了,這時候運維會根據當前問題來修復某些不滿足的條件,比如開通網絡策略、部署Agent等等,當完成後只需要變更節點狀態,後續就會自動化修復

當遇到無法通過上述自動化短時間來解決的時候,運行運維進行手工修復,並強制更新對應的狀態,則係統會根據當前的狀態進行後續的操作,比如檢測到就緒之後就進行負載掛載等

1.2 kubernetes相關機制

那如何利用k8s的相關機制來實現上述交付流程呢,這裡主要通道了webhook、finalizer、annotations幾個機制

1.2.1 webhook

首先我們通過webhook再server更新的時候通過admission.Mutation機制來根據當前內部狀態進行狀態的決策,以確定接下來的自動化任務,在這環節我們實現了從部署環境->部署代碼->就緒狀態的轉換

1.2.2終結器

在主機進行刪除的時候,需要等待負載刪除、暫停監控、刪除虛機等流程全部結束後才能進行節點對象的刪除,從而實現了節點信息的異步清理機制

2. 核心設計

2.1 核心對象設計

雲原生虛機應用託管-設計篇 4

考慮到應用的環境操作和部署操作兩個操作頻率的差異性,我們這裡參考k8s聲明了兩個上層控制器,即通過VMReplicaSet來實現程序運行環境的交付,而將部​​署操作交由VMDeployment來控制,同時兩個控制在操作某個實例的時候都會先進行狀態檢測,然後在進行資源的鎖定才能進行相關的操作,從而保障執行流程的穩定性

2.2 狀態轉換機制

下面我們會按照幾個不同的場景來分別介紹下虛機狀態的轉換以及對應控制器的控制,我們有兩個核心的設計理念:1.人只負責環境配置的描述,由系統完成相關狀態和自動化操作2.狀態的確定依賴於當前現狀,同時人的決策高於一切

2.2.1 初始化

當檢測副本數量發生變化VMReplicaSet首先會發送申請,確認當前是否要進行機器的創建,同時會創建對應的Server的Package配置,通過計算Package狀態設置當前狀態為Initializing,並同時創建部署環境的任務,然後等待環境部署的結果,同時會掛載Server的負載信息

雲原生虛機應用託管-設計篇 5

等待環境部署完成後,控制器會自動檢測狀態並設置為Deploying,同時通過部署系統進行代碼的部署,並將對象重新入隊,直到狀態部署完成

代碼部署完成後,會進行狀態檢測,如果系統節點健康檢查通過並且監控狀態未發現異常,則會將節點設置為Ready狀態,同時負載控制器和監控控制器都會對應的配置,至此完成虛機的初始化完成,後續如果環境不變,則代碼部署只需要重複當前操作

2.2.2 有狀態的下線

虛機通常是有狀態的應用,如果要下線通常都是選擇指定的節點,並標記為下線狀態,同時結合finalizer和控制器完成對應負載和監控的同步操作,當所有的finalizer都釋放後,最後進行對應節點的刪除

2.2.3 故障轉移機制

如果對應的節點宕機,則只需要加一個處理轉換邏輯即可,如果是短時間可以恢復就只需要將對應的節點標記為UnKnown,同時監控和負載控制器進行對應的操作,然後等待重啟後接收到對應的事件後將節點設置為Initializing, 然後系統會自動進行對應的檢測邏輯,自動轉換為Ready,監控和負載控制器監控自動執行相關邏輯,即可完成上線

如果節點不可修復只需要將狀態設置為下線狀態,然後對應的副本控制器檢測到節點不足,就會自動調用IAAS系統進行自動創建,然後執行初始化流程即可

3. 未完待續

基於流程驅動的跟基於k8s的控制器在實現流程上其實並沒有本質的差別,在雲原生里面有很多種玩法,虛機應用的管理本質上就是複雜環境的管理。

如何管理複雜的環境,其實就是讓環境可描述,系統自治,盡可能減少人的參與,人只參與影響穩定性的決策,而不參與任何關於流程驅動;嗯,這句話說得貌似有道理

最近在搞雲原生應用管理和私有云方向,感興趣的朋友可以一起聊聊,交流交流

雲原生學習筆記地址: https://www.yuque.com/baxiaoshi/tyado3“微信號:baxiaoshi2020 公共號: 圖解源碼

雲原生虛機應用託管-設計篇 6