2017年3月底,Kubernetes隆重發布了1.6版本,在節點規模、安全性、調度和存儲上都有了重大進展。目前來看,不論從社區關注度仍是實踐案例角度,Kubernetes都已經超越Mesos和Docker Swarm,成爲最受歡迎的容器編排技術。node
網易雲從2015下半年開始向Kubernetes社區貢獻代碼,是國內最先的Kubernetes實踐者和貢獻者,也是Kubernetes技術的積極佈道者,網易雲已經成爲CNCF官方受權的CloudNative Meetup主辦方。6月3日,網易雲在網易杭州園區舉辦Kubernetes Meetup杭州站,活動邀請了Hyper項目成員、Kubernetes項目官方Project Manager和Feature Maintainer張磊,網易雲容器編排技術負責人婁超,才雲Caicloud高級軟件工程師岑鵬浩,噹噹網數字業務事業部技術總監李志偉,爲杭州的小夥伴們帶來Kubernetes最新的技術進展和最佳實踐。web
本文主要整理了網易雲容器編排技術負責人婁超的演講「網易雲基於Kubernetes的深度定製化實踐」!算法
婁超,網易雲容器編排技術負責人。曾經參與淘寶分佈式文件系統tfs和阿里雲緩存服務研發,2015年加入網易參與網易雲容器服務研發,經歷網易雲基礎服務(蜂巢)v1.0,v2.0的容器編排相關的設計和研發工做,並推進網易雲內部Kubernetes版本不斷升級。後端
網易雲的容器服務基於網易雲的IaaS。爲了簡化用戶的操做,Kubernetes並非直接暴露給用戶的,而是經過上層的業務層爲用戶提供容器服務,增長獨立的Netease-Controller, 對接網易IaaS及公共平臺,資源管理和複雜的業務需求。api
Kubernetes的社區版本主要面向私有云市場,沒有租戶的概念,只有namespace的邏輯隔離,Node/pv等資源都是集羣全局共享的,服務發現和負載均衡也都是全局的,Node須在集羣內預備足夠,不用擔憂資源調度出現失敗,也無需關心Docker隔離安全性問題。而對於公有云來講,雲中有着海量用戶,用戶的技術背景多樣,須要很高的安全隔離性。網易雲在基於Kubernetes實現公有云的過程當中,作了不少工做。緩存
首先,在多租戶的安全隔離方面,有專門的IaaS團隊提供主機、硬盤和網絡的隔離;安全
對於每一個租戶來講,均可以自定義建立namespace;性能優化
原生的Kubernetes認證很簡單,並且Node是全局共享的,每一個Node上均可訪問Kubernetes的全部資源,因此爲了實現公有云,網易雲作了租戶級別的安全隔離,包括認證、受權和API分類統計和流控報警;網絡
在網易雲中計算、存儲、網絡資源均按需實時分配、回收,保證資源的利用率儘量高;由於資源是實時分配的,因此建立起來通常比較慢,因此網易雲對建立流程作了一些全局的優化,好比加快Node註冊的進程,根據鏡像選擇主機等;架構
原生的Kubernetes中沒有網絡IP的概念,網易雲增長了Network資源類型表示網絡IP。
容器的網絡主要有如下幾種方案:
入門級:Docker 基礎網絡模型 host(共享),bridge(NAT)
進階級:自建網橋(IP-per-pod),可跨主機通信,如Flannel, Weave
專業級: 多租戶,ACL,高性能可擴展 ,如Calico,GCE高級網絡模式
網易雲的容器服務的網絡實現與GCE相似,基於底層的IaaS網絡,經過Kubernetes與網易雲網絡對接,網易雲容器與主機在網絡上徹底對等,租戶內全互通。
Kubernetes中沒有定義IP的管理,可能一個容器或節點重啓一下,IP就變了。網易雲經過IP的管理實現了IP的保持功能,同時Pod支持私有網、公網雙重網絡。
此外,網易雲還實現了Pod的私有網、公網IP映射關係管理,在Kubelet上實現Netease CNI插件管理網卡掛卸載、路由配置。
提到容器的狀態,人們經常使用Cattle和Pet來作比喻。Cattle是指無狀態的容器,隨時能夠被替換,Pet則是有標記的,它的數據、狀態和配置可能都須要持久化。社區從1.3版本就開始用PetSet實現有狀態的容器,最新的1.6版本中,是叫StatefulSet。
網易雲在社區版本的有狀態容器誕生以前(1.0版本),就自研了StatefulPod的實現方式:
和StatefulSet不一樣的是,它能夠支持容器系統卷、數據卷的保持(PV、PVC)。StatefulSet只能支持外掛的數據卷,可是網易雲的StatefulPod可以保證只要不刪除用戶,用戶系統盤的數據也可以保持下來;
StatefulPod還能保證容器私有網、公網IP保持(Network);
在原生的Docker中,一個Node啓動的全部容器目錄都是統一的,網易雲擴展Docker支持容器rootfs目錄自定義;
網易雲的有狀態容器還支持故障的遷移,好比硬盤和IP等資源都能在Node間漂移。
通常在實現公有云時,儘可能會保證同一個機房內,只有一個Kubernetes集羣,但隨着用戶的增多,集羣的規模也愈來愈大,會出現不少性能問題。網易雲隨着社區的發展一路走來,也遇到了不少社區可能在設計之初並無預料到的問題,好比:
Kube-scheduler對全部pod順序串行調度
Kube-controller的deltaQueue是無優先級的FIFO隊列
Serviceaccounts控制器裏沒有Secret本地緩存
全部Node重複配置集羣全部Service的iptables規則
Kubelet的SyncLoop每次檢查都重複GET imagePullSecrets
大量Node的心跳彙報嚴重影響了Node的watch
Kube-apiserver 沒有查詢索引
針對這些問題,網易雲作了不少性能優化,首先是master端的調度器:
公有云的場景和私有云不同,容器分佈在不一樣的租戶中,每一個租戶的資源都是獨立的,自己就能夠經過租戶來溝通並調度;
一般在調度的時候須要一個個去遍歷Node,實際上不少無閒置資源的Node能夠不參與調度的檢查,網易雲會在遍歷前過濾掉無閒置資源的Node;
優化predicate調度算法過濾順序,提升調度效率;
網易雲中,調度都是基於事件的,好比調度失敗若是是由於Node資源不足,就會發一個事件去申請資源,資源回來後會又會返回一個事件驅動Pod重調度,沒有任什麼時候間等待;
上圖就是在網易雲中並行調度的過程。
而後是mater端控制器的優化:
Kubernetes中有不少控制器,好比Node控制器、namespace控制器,其中replication controller是一個核心的控制器,能確保任什麼時候候Kubernetes集羣中有指定數量的pod副本在運行。網易雲建立了事件優先級機制,根據事件類型進入優先級隊列workqueue。
網易雲的用戶不少,用戶之間都是徹底隔離的,網易雲kube-proxy按租戶對Node分組:
租戶之間容器網絡徹底隔離,不配多餘轉發規則;
只watch本租戶的Service,再生成iptable 規則。
Kubelet下降master請求負載:
imagePullSecret推遲都要拉鏡像才GET或增長Secret local cache
只watch本租戶相關資源變化(依賴apiserver新加的tenant索引)
租戶之間容器網絡徹底隔離,不配多餘轉發規則;
精簡kubelet watch 低master鏈接數,包括Node
根據官方的數據,Kubernetes 1.0最多支持100個Node,3000個Pod;在1.3版本中這個數字上升到2K個Node,6W個Pod,今年最新發布的1.6版本已經支持5K個Node,15W個Pod。
經過上圖能夠知道APIserver是整個集羣的通訊網關,只是一個proxy代理,並且goroutine對web服務完美支持,最終性能瓶頸在對 Etcd的訪問上。
爲了解決這個問題,首先想到的是分庫,按Node/RS/Pod/Event分庫存入多個Etcd集羣。由於Etcd自己容量和性能均不能水平擴展,並且沒有性能診斷工具;
Etcd2 調優,好比針對snapshot的優化,採用SSD硬盤等;
升級Etcd3,在以前的版本中,每次更改都會發送一個請求,一個請求又對應一個回覆,在Etcd3中是批量請求的方式,可能一次請求就把1000個變化推送過來了,因此效率提升不少;
更換Kubernetes後端的存儲,換其餘性能更優的KV存儲。
Node心跳彙報模式修改
Node心跳間隔延長
Node心跳不持久化
心跳從Node分離出來,Node心跳只需list沒必要watch
NodeController被動改主動探測
鏡像、容器的GC完善:目前的GC只考慮了磁盤的空間使用量,沒考慮inode的問題,不少用戶的小文件不少,因此網易雲新增了磁盤inode使用率檢查
容器監控統計:Cadvisor新增網絡流量、TCP鏈接、磁盤相關統計
NodeController安全模式,自定義Protected,Normal,Advanced 3種模式。
Protected: 底層IAAS主動臨時運維時,爲了不大規模遷移波動, Node離線只報警不遷移
Normal:有狀態的不遷移,無狀態的及時離線刪除重建。(僅僅底層雲盤、網絡故障)
Advanced:有狀態無狀態都自動遷移恢復
還須要注意的一些問題:
Pod的graceful delete要容器能正常傳遞SIGTERM信號
StatefulSet在kubelet掛掉時可能出現兩個同時運行的Pod