1. 程式人生 > >魅族容器雲平臺自動化運維實踐

魅族容器雲平臺自動化運維實踐

linux

魅族容器雲平臺主要是基於 k8s 的技術。將從以下六個方面介紹魅族容器雲的實踐過程,分別是基本介紹、k8s 集群、容器網絡、外部訪問4/7層負載均衡、監控/告警/日誌、業務發布/鏡像/多機房。

1、基本介紹

魅族雲平臺的定位是私有雲平臺,主要是用於支撐在線業務,用以替換傳統的虛擬化方式。目前現狀是2017年完成全國三個數據中心的建設,年內完成90%業務的遷移。

我們是以小團隊緊跟 k8s 社區步伐,快速叠代、低成本試錯的方式來構建我們的平臺的。同時,針對一些我們遇到的問題,做一些局部創新,在保證系統核心的隨社區穩定升級的前提下,解決好非功能性問題。

技術分享

2、k8s 集群

對於 k8s 集群構建,將從 k8s 的單一鏡像、k8s 集群 master、minion 三個方面分別展開介紹。

2.1 單一鏡像

技術分享

k8s 集群的安裝部署是利用單一鏡像 + docker run 實現一鍵安裝。為此將所有 k8s 相關的描述文件、腳本和二進制全部打包成鏡像,目的是實現集群的快速部署和升級。

2.2Master

技術分享

為了能夠實現自動加載,k8s 集群核心組件使用了 Static Pod 方式。在自動修復方面,kubelet probe 可以實現 Pod 的自檢,配置了自動重啟。如果需要對核心組件進行升級,指定統一鏡像的版本號即可實現核心組件升級更新。

技術分享

controller manager 和 scheduler 服務在三臺物理機實現集群 master 高可用。API Server 的高可用既可以通過負載均衡方式實現,也能通過 DNS 方式實現。

技術分享

集群 controller mananger 重啟可能會出現 Node 狀態不同步的問題,因此對於核心組件狀態,需要配置告警並及時檢查有無異常狀態。

2.3 minion

硬件方面並沒有固定的配置,盡量利用現有的資源。在我們的集群中,常見 minion 的配置是 24核 CPU(with ht)、128GB 內存以及千兆網卡。

技術分享

k8s 集群中 minion 作為計算節點,其上主要是各種業務的容器和 Systempods。

對於 minion 節點做了三個方面參數的優化,中斷相關、TCPbacklog 和 swap。

技術分享

minion 節點操作系統使用的是 centos 7,docker storage 使用的 devicemapper driver,日誌基本寫到外掛的 EmptyDir volume,docker 存儲使用得很少。

我們為 EmptyDir Volume 專門開辟了普通分區,沒有使用 lvm,因為日誌量不好預估,遭遇過因為 lvm metadata 的事故。

技術分享

使用 Device Mapper 還遭遇過 kernel issue,因此需要更新內核。

技術分享

默認內核是3.10版本,長期維護的內核版本的是我們需要的。而且考慮到要對某些內核模塊做 hacking,4.0及以上變化較大,hackingtcp_v4_syn_recv_sock 存在問題,所以我們最終選擇了自行編譯 3.16內核。

考慮到和 CMDB 的結合,minion 節點打上了 Label,例如標記它的功能是什麽,物理位置信息,機櫃等。這些信息對於 Pod 調度非常重要。包括 Pod 的 Node 親和性,Pod 親和性和反親和性。

3、容器網絡

技術分享

容器網絡的方面我們采用的是 calico 的方案。主機通過 BGP 直接和核心路由設備對接,這裏也可以用 RouteReflector 替代。

控制層面走 BGP,數據層面走三層路由。網絡封包會經過主機的 netfilter框架,最後經由主機 forward chain 進入容器,默認都會被 conntrack。部署方面,Calico 通過 k8s 的 Daemonset 方式,部署非常方便

技術分享

優化主要是針對 conntrack,建議盡量使用 headless service,少產生 iptables rule。同時,對 conntrack 用量進行監控。容錯方面,容器會主動去 ping 交換機,確保網絡的連通性。當 calico 出現問題的時候,容器是不會加入服務的,由此來保證服務的可靠性。

對於我們系統,絕大部分流量來自外部 LVS,其可信任度高,默認的方式會產生大量的 conntrack 記錄,所以應當把 LVS 過來的流量直接給 bypass conntrack。

經過生產實踐效果驗證,no mesh 模式的穩定性要優於 mesh 模式。異常處理主要分為 POD 主動檢測網絡和 calico 的整體健康監控告警。

4、外部訪問4/7層負載均衡

我們做的是對外服務,大部分流量都是從外部打進來的,終端用戶都是外部的客戶,所以針對外部的訪問做了4層和7層的負載均衡。我們做的是對外服務,大部分流量都是從外部打進來的,終端用戶都是外部的客戶,所以針對外部的訪問做了4層和7層的負載均衡。

在4層接入上采用了是阿裏開源的 Fullnat LVS 方案,看中了它運維方便、水平擴展性好。工作在4層的 LVS 服務既可以支持 TCP 同時也支持 UDP,流量從client 端經過 LVS 做 Fullnat 後到達 minion,應答直接路由回對應的LVS。

對於4層負載均衡的配置,是通過自動化方式來實現的,無需人工配置,可以自動在路由設備宣告 vip,並生成對應的 ECMP 路由。LVS 的 VirtualServer 配置也是自動生成的,VirtualServer 到 EndPoint ip 的自動映射。

我們對 LVS 控制程序做了改造,暴露了一些指標,包括網絡和應用服務相關的數據,並以此實現了 Grafana 可視化和監控告警。

一方面是對 LVS 整體流量異常告警,另一方面 realserver (Pod) 做高延遲異常檢測告警。

七層負載均衡采用的是 POD 裏面跑 nginx+ingress controller,它的定位是業務專屬的反向代理,能夠實現自動擴縮容,面向的 upstream 主要是 Jetty 業務容器。

由於四層負載均衡采用的是 FullnatLVS,真正的終端 ip 地址已經被隱藏起來了,需要從 TCPoption 中獲取。realserver 默認取到的是 LVS 的 local ip 地址,需要使用 TOA 模塊來獲取終端 ip。

開源版本的 TOA 一直沒有升級,為此我們將其移植到 3.16,對於大多數業務來說,客戶端 ip 地址是不可或缺的。

在把 nginx 容器化之後,踩了一些坑,其中一個是延遲過高。從 access.log 看,upstream 的 RT 時間長達幾秒,而直接訪問 upstream Pod 服務又是很快的,說明是 nginx 的問題。經分析後發現配置不合理,nginx 容器化之後缺少對 worker 數量和親和性的優化。

按照默認配置,一臺24核 CPU 的機器上,對於一個業務的 nginx,自動配置為 24個 worker 進程,而 cpu limit 往往只設置成 5、6個核,worker 沒有 cpu 資源導致高延遲。同時,調整 worker 進程的親和性,防止壓力堆積在前幾個核上。技術分享

Nginx 動態縮容需考慮柔性,比如某業務原來有3個 Nginx 容器,現在要縮成2個,被停掉這個 Nginx 容器需要做一些優雅退出的準備工作,否則可能導致服務整體響應延遲陡增。

這個 POD 一開始就從 LB 上被摘掉了,我們利用 Pod 的 prestop hook,等待並優雅退出。

擴容時,需要考慮啟動時間和熱身問題。有的業務可能需要幾秒或幾十秒,要有充足的初始化時間,否則,請求過去就會失敗。

如果 Probe Timeout 設置得比較小,會導致 Pod 被強制重啟或者摘除,導致整體服務的雪崩。在實際運行過程中,應根據監控情況對 CPU request 和 Hpa 配置持續優化。

5、監控/告警/日誌

技術分享

監控采用的是 prometheus,開箱即用的整體方案。部署方面是在 k8s 上部署成 Daemonsets 或者 Deployment,針對其特點會調度到特定的機型,通過類型拆分成幾種 map 來方便管理。

監控指標包括兩個方面,一個是硬指標,例如,從 nginx 獲取當前業務的qps、http code 分布、當前整個業務的資源消耗情況以及後端的 jetty 消耗情況。

另一方面是業務的軟指標,指的是內部指標,主要包括 jvm 的指標,內部的logger 相關,如 error 計數器。

日誌的處理是收集到 elasticsearch 處理的。ES 的部署和 prometheus 類似也是 POD 的方式。部署 ES 的 datanode、master 和 client 需要關註線程數據和 CPU limit 的匹配問題。

日誌收集容器試過使用 fluentd 進行收集,與業務容器共享一個存儲,發現有日誌滯後和資源消耗高的問題。用 filebeat 容器替代 fluentd 之後,資源占用率很小,消耗不到0.1核、內存不到 100M 就可以實現比較好的日誌傳輸效果。

6、業務發布/鏡像/多機房

技術分享

業務發布考慮到效率和交互性,需要給用戶提供一個交互界面,能夠生成 k8s的資源描述文件,並能執行具體的 Action,如創建/更新/刪除。

實現上是通過 json schema 的方式來描述所有參數,默認值+結合用戶輸入最終生成 k8s 的資源描述文件。

利用 ansible 調用 kubectl 來實現自動化部署。實現了部署進度,發布歷史管理,模板化部署。對於多集群管理,ansible 通過切換不同 k8s 集群的 context,發布業務到不同機房。

對於鏡像的選擇我們的原則就是夠小、夠用,為了保證兼容性我們加入 glibc 支持。Docker 其實推薦只跑一個進程,但很多業務都是需要多個進程配合的,S6 用於應對這種場景,作為進程和服務的管理器來實現一些比較復雜的功能。

總的來說,這是一套低成本的私有雲實現方案,核心部分持續享受到 k8s 的紅利,可以集中力量解決 4/7 層負載均衡及一些非功能性問題。同時,利用k8s核心系統的能力,快速構建外部支撐系統,如監控、告警、日誌、發布系統等,在很大程度上提高了效率和可維護性。


魅族容器雲平臺自動化運維實踐