天天看點

網易雲基于 Kubernetes 的深度定制化實踐

本文由  網易雲 釋出。

2017 年,Kubernetes 超越 Mesos 和 Docker Swarm成為最受歡迎的容器編排技術。網易雲從 2015 下半年開始向 Kubernetes 社群貢獻代碼,是國内最早的 Kubernetes 實踐者和貢獻者,并已經成為 CNCF(雲原生計算基金會)官方授權的 CloudNative Meetup 主辦方。本文将簡單介紹下網易雲基于 Kubernetes 的深度定制化實踐。

1 網易雲容器服務的架構

網易雲容器服務基于網易雲 IaaS。為了簡化使用者操作,Kubernetes 并不直接暴露給使用者,而是通過上層的業務層為使用者提供容器服務。增加獨立的 Netease-Controller, 對接網易 IaaS 及公共平台,資源管理和複雜的業務需求。

網易雲基于 Kubernetes 的深度定制化實踐

2 kubernetes 公有雲實踐

Kubernetes 的社群版本主要面向私有雲市場,沒有租戶的概念,隻有 namespace 的邏輯隔離,Node/pv 等資源都是叢集全局共享的,服務發現和負載均衡也都是全局的,Node 須在叢集内預備足夠,不用擔心資源排程出現失敗,也無需關心 Docker 隔離安全性問題。而對于公有雲來說,雲中有着海量使用者,使用者的技術背景多樣,需要很高的安全隔離性。網易雲在基于 Kubernetes 實作公有雲的過程中,做了很多工作:

首先,在多租戶的安全隔離方面,有專門的 IaaS 團隊提供主機、硬碟和網絡的隔離;

對于每個租戶來說,都可以自定義建立 namespace;

原生的 Kubernetes 認證很簡單,而且 Node 是全局共享的,每個 Node 上都可通路 Kubernetes 的所有資源,是以為了實作公有雲,網易雲做了租戶級别的安全隔離,包括認證、授權和 API 分類統計和流控報警;

在網易雲中計算、存儲、網絡資源均按需實時配置設定、回收,保證資源的使用率盡可能高;因為資源是實時配置設定的,是以建立起來一般比較慢,是以網易雲對建立流程做了一些全局的優化,比如加快 Node 注冊的程序,根據鏡像選擇主機等;

原生的 Kubernetes 中沒有網絡 IP 的概念,網易雲增加了 Network 資源類型表示網絡 IP。

3 網易雲容器 pod 網絡

容器的網絡主要有以下幾種方案:

○ 入門級: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 插件管理網卡挂解除安裝、路由配置。

4 網易雲有狀态容器

提到容器的狀态,人們常用 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 間漂移。

5 網易雲 Kubernetes 性能優化

一般在實作公有雲時,會盡量保證同一個機房内,隻有一個 Kubernetes 叢集,但随着使用者的增多,叢集的規模也越來越大,會出現很多性能問題。網易雲随着社群的發展一路走來,也遇到了社群在設計之初可能沒有預料到的一些問題,比如:

○ Kube-scheduler 對所有 Pod 順序串行排程;

○ Kube-controller 的 deltaQueue 是無優先級的 FIFO 隊列;

○ Serviceaccounts 控制器裡沒有 Secret 本地緩存;

○ 所有 Node 重複配置叢集所有 Service 的 iptables 規則;

○ Kubelet 的 SyncLoop 每次檢查都重複 GET imagePullSecrets;

○ 大量 Node 的心跳彙報嚴重影響了 Node 的監聽;

○ Kube-apiserver 沒有查詢索引。

master 端的排程器

針對這些問題,網易雲做了很多性能優化,首先是 master 端的排程器:

公有雲的場景和私有雲不一樣,容器分布在不同的租戶中,每個租戶的資源都是獨立的,本身就可以通過租戶來溝通并排程;

通常在排程的時候需要一個個去周遊 Node,實際上很多無閑置資源的 Node 可以不參與排程的檢查,網易雲會在周遊前過濾掉無閑置資源的 Node;

優化 predicate 排程算法過濾順序,提高排程效率;

網易雲中,排程都是基于事件的,比如排程失敗如果是因為 Node 資源不足,就會發一個事件去申請資源,資源回來後會又傳回一個事件驅動 Pod 重排程,沒有任何時間等待。

網易雲基于 Kubernetes 的深度定制化實踐
網易雲基于 Kubernetes 的深度定制化實踐

mater 端控制器的優化

Kubernetes 中有很多控制器,比如 Node 控制器、Namespace 控制器,其中 Replication Controller 是一個核心的控制器,能確定任何時候 Kubernetes 叢集中有指定數量的 Pod 副本在運作。網易雲建立了事件優先級機制,根據事件類型進入優先級隊列 workqueue。

Node 端的優化

網易雲的使用者很多,使用者之間都是完全隔離的,網易雲 kube-proxy 按租戶對 Node 分組:

○ 租戶之間容器網絡完全隔離,不配多餘轉發規則;

○ 隻監聽本租戶的 Service,再生成 iptable 規則。

Kubelet 降低 master 請求負載:

○ imagePullSecret 推遲都要拉鏡像才 GET 或增加 Secret local cache;

○ 隻監聽本租戶相關資源變化(依賴 apiserver 新加的 tenant 索引);

○ 精簡 kubelet watch 低 master 連接配接數,包括 Node。

單叢集擴充的優化

根據官方的資料,Kubernetes 1.0 最多支援 100 個 Node,3000 個 Pod;在 1.3 版本中這個數字上升到 2000 個 Node,6 萬個 Pod,今年最新釋出的 1.6 版本已經支援 5K 個 Node,15W 個 Pod。

網易雲基于 Kubernetes 的深度定制化實踐

通過上圖可以知道 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。

網易雲基于 Kubernetes 的深度定制化實踐

婁超,網易雲容器編排技術負責人。曾經參與淘寶分布式檔案系統 TFS 和阿裡雲緩存服務研發,2015 年加入網易參與網易雲容器服務研發,經曆網易雲基礎服務(蜂巢)v1.0,v2.0 的容器編排相關的設計和研發工作,并推動網易雲内部 Kubernetes 版本不斷更新。

了解 網易雲 :

網易雲官網:https://www.163yun.com/

新使用者大禮包:https://www.163yun.com/gift

網易雲社群:https://sq.163yun.com/

繼續閱讀