CDN邊緣節點容器調度實踐(下)
5 人贊了文章
5月27日,OSC 源創會在上海成功舉辦。又拍雲系統開發高級工程師黃勵博在大會分享了《CDN 邊緣節點容器調度的實踐》。主要介紹又拍雲自主開發的邊緣節點容器調度方案,從 0 到 1 ,實現零停機、負載均衡,以及基於容器的子網組建、管理等底層功能。
因為分享內容較多,所以將分享整理為兩篇文章:第一篇文章,CDN邊緣節點容器調度實踐(上)介紹又拍雲邊緣節點容器調度平台版本1到版本2的發展過程,以及搭建平台時的基本思路;第二篇文章著重介紹又拍雲邊緣節點容器調度平台版本3到版本4的發展過程,對平台後續功能的完善做了詳細的講解。本文是第二篇,以下為講師分享內容:
版本 3 支持動態負載均衡
版本 2 完成了對 App 所有者的隔離和限制,我們來看下服務的訪問者,現在他們都是直接訪問節點的機器,這樣並不適合完成一些服務的調度, 比如負載均衡和服務更新等。
由於之前提供埠映射方案可以是隨機的,在這種情況下,App 的訪問者甚至不知道服務具體跑在哪些機器, 監聽在哪些埠上,因此需要有一個統一的入口。
上圖是又拍雲開源的基於 ngx_lua 的動態負載均衡方案——Slardar。它可以做到在不 load Nginx 的情況下,動態更新 upstream 列表和動態更新 lua 代碼。方便動態的維護容器服務的地址。
那麼 Slardar 是如何完成服務動態選擇的?
如圖所示, 首先對於 http 服務我們可以通過 host 來區分不同服務,動態地找到指定的服務,類似的, 對於 tcp 服務,我們通過接入的埠來區分不同的服務
其中, checkups 是一個動態選擇上游的組件,他提供了一個註冊機制,我們可以註冊用戶自定義的負載均衡策略, 默認支持輪詢和 hash 演算法,同時也支持註冊主動的健康檢查策略, 默認支持 tcp http mysql等協議,這樣為每個服務選擇一個正常工作的地址。
上圖是健康檢查頁面,在 slardar 中我們會啟用一個定時器來定時檢查所有上游的狀態。其中 checkup_timer_alive 欄位代表這個定時器是否還存活著,last_check_time 欄位代表上一次定時器的檢查時間。後面是上游的健康狀態, 包括 IP、埠號、服務名稱, status 狀態等。
我們可以在節點上部署 slardar 作為容器服務的統一入口完成服務的負載均衡和健康檢查。服務的用戶訪問時,都會接入到 Slardar 這個統一入口。由 Slardar 代理到具體的 Task。版本3 的架構如上圖所示。
版本 4 支持零停機更新
有了統一的入口,我們可以保證在任務更新時,服務不會出現不可用的狀態。可以通過運行兩個不同版本的服務同時運行來實現藍綠更新。
當 Master 收到服務更新請求的時候,Master 會讓 Agent 負責啟動服務新版本的容器 Tasks,同時把新版本容器地址寫入 etcd 把舊版本的地址刪除, 之前我們介紹過 calico 會用到這個分散式的 key value 伺服器,這邊管理 upstream 列表, 我們也同樣使用了 etcd 這個 kv 資料庫。
舊版本是圖中三個藍色的 Tasks,更新任務開始,會部署三個綠色的新版本 Tasks。當三個新版本任務起來後,Agent 會把 Tasks 中的地址更新到 etcd 中。圖中看到有個 confd 的服務會監聽 etcd 中 upstream 列表的變更, 把 upstream 列表主動同步給 slardar 完成 upstream 的切換, 而 slardar 啟動的時候也支持從 etcd 載入 upstream 列表, 這樣就完成了服務的更新, 等舊版本的服務流量沒有的時候 Agent 會主動刪除舊版本完成更新操作。
結合上文講的訪問控制、統一入口以及動態更新,我們就擁有了這樣一個架構。
版本 4 架構中,Slardar 是 HTTP/TCP 代理,它是一個無狀態的代理服務,所以可以任意部署,不存在單點問題,直接部署多台就可以保障可用性。而 Hancock Master 作為服務擁有者的入口,擁有著所有服務的狀態,可以看到到現在為止,還是單點的,不是一個高可用的服務。為了解決這個問題,我們需要有一個高可用的方案。
版本 5 實現高可用
與版本 4 項目,版本 5 中使用 Raft 分散式一致性協議實現高可用。
Raft 主要特點有三個:
- 領導選舉: 心跳機制來觸發選舉, term 充當邏輯時鐘的作用;
- 日誌複製: 領導者把一條指令(能被複制狀態機執行)附加到日誌中,發起附加條目 RPC 請求給其他角色;
- 強領導者:日誌條目只從 leader 發送給其他的伺服器。
如圖所示, 服務起來時默認為跟隨者, 如果發現當前集群中有一個領導者, 那就接受它。如果超時時間內一直沒有收到領導者的消息, 它就會把角色切換成獲選人, 同時把自己的 term 任期號加1, 開始一輪選舉, 如果獲得了集群中半數以上的節點的投票, 它就會變成領導者。如果在此過程中, 發現了集群領導者, 而且它的任期號不小於自身的任期號, 那麼就把角色退化成跟隨者, 如果在隨機的一段超時時間到來後, 沒有發現領導者也沒有多數人的投票, 那麼就再進行一輪新的選舉。
領導者會把指令附加到日誌中, 然後發起 RPC 請求給集群中的其他伺服器, 讓他們複製日誌, 這條指令會最終在集群的每台機器上在 Raft 的狀態機中執行, 日誌條目只能從 leader 發送給其他伺服器。
在增加了 Raft 之後,版本 5 已經是一個高可用的方案,leader 平時是會與所有的 Agent 交
互,並且它是有狀態的,可以把狀態同步到兩個跟隨者中。當 leader 掛掉時,follower 擁有 leader 完整的狀態,只要重新選舉出來一個成為新的 leader,服務就可以繼續運行下去。
版本 6 監控與告警
由於系統中的消息都是非同步交互, App 服務可以通過註冊回調通知地址,來實時獲取各個事件。除了用戶需要及時獲取一些事件(實例狀態變更,服務狀態變更等)之外, 我們也需要一個監控和告警方案來及時了解我們邊緣服務的情況。
監控:
Agent 會收集 Metrics 到 InfluxDB, 由 Grafana 展示, 如圖所示幾個節點的流量監控
告警:
告警信息分兩類, 一類是任務相關: Hancock 會發送消息到 slack , 截圖是 Hancock 的一個告警信息。
還有一類是監控相關, 比如設定的指標異常時, 發送實時消息到 slack, 截圖是 slardar 上 500-504 響應的告警信息 , 可以看到在 21點左右 502 的狀態出現了一個峰值,有三百多次 502.
最後有了我們現在的邊緣容器調度架構。
這些就是我們邊緣節點容器調度架構涉及到的一些主要組件, 一些更具體的細節就不再這邊一一展開了, 歡迎感興趣的公司或個人使用我們的這個服務。
了解更多:容器雲 - 全球首家分散式容器雲平台
推薦閱讀: