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