3月25日,網易雲技術佈道系列第三期•對話架構師上海站的活動中,網易雲基礎設施技術總監張曉龍帶來了題爲「網易雲容器服務研發實踐分享」的乾貨演講。網易從2012年春開始雲計算研發,陸續上線私有云IaaS、PaaS服務,並實現網易95%以上的互聯網業務遷移上雲。本次活動中,張曉龍分享了網易雲基礎服務團隊在研發容器服務過程當中的實戰經驗。node
張曉龍,網易雲基礎設施技術總監,網易專業技術委員會委員。浙江大學本科、博士畢業。目前主導網易私有云以及網易公有云基礎設施服務的技術研發,在雲計算基礎設施、分佈式系統方面有多年的架構設計與研發經驗。docker
張曉龍首先介紹了網易雲的研發歷程和總體架構。數據庫
網易雲的產品經歷了長期的技術積累,網易在2012年開始作雲計算,最先實現了IaaS,交付了公司內部的私有云基礎設施服務,包括主機、網絡、存儲等服務;2013年8月,陸續上線了關係型數據庫、負載均衡、對象存儲等平臺服務;2014年12月,網易內部95%以上的互聯網產品都實現了上雲;2015年5月,網易雲對外服務於合做夥伴——網新科技、中順易等;2016年1月,網易基於Docker實現了容器雲,並在9月正式對外發布。後端
下圖是網易雲的簡單架構:api
網易雲的技術架構從底到上分爲三層:緩存
基礎設施層主要採用虛擬化技術將服務器、交換機/路由器以及硬盤等物理設備虛擬成爲能夠按需分配的計算/存儲/網絡資源。基礎設施層主要包括:雲主機、雲網絡、雲硬盤等服務。基礎設施層不只爲網易雲容器服務運行提供計算/存儲/網絡資源,同時也爲爲數據庫、緩存、負載均衡等網易雲平臺服務提供資源;安全
核心業務層主要包括兩塊:一是容器及容器編排:鏡像倉庫、日誌服務、容器服務、編排服務,主要覆蓋了以容器以及容器編排爲中心的網易雲容器服務核心功能;二是PaaS插件服務,主要包括數據庫、負載均衡、對象存儲、緩存等;性能優化
最上面的外圍服務層,也是構成一個平臺不可或缺的一部分。主要包括:認證、API服務、計費服務、安全服務、監控服務服務器
做爲網易雲的核心服務之一,網易雲容器服務的定位是面向高效研發而打造的新一代雲計算平臺,提供彈性計算、DevOps工具鏈及微服務基礎設施等,幫助企業解決IT、架構、運維等問題,使企業更聚焦其業務。容器服務的功能包括3個方面:網絡
提供有狀態/無狀態容器及其鏡像加速/構建/倉庫等在內的容器服務;
提供包括對象存儲、CDN、關係數據庫、MongoDB、負載均衡、緩存服務、安全服務等在內的完善平臺服務,是實現互聯網應用的通用的基礎組件;
提供包括服務發現、編排服務、APM服務、持續集成、監控服務、日誌服務、持續發佈等在內的完整DevOps工具鏈。
要構建一個容器服務,須要三類核心的技術:基礎設施、容器、容器編排。從整個核心技術來看,網易雲容器服務基於流行的開源技術而打造,爲實現極致的用戶體驗實施了各類優化和定製開發。
基礎設施提供容器運行所需計算/存儲/網絡資源,高效管理這些資源並確保資源的按需分配、高效交付,同時要保證交付資源的QoS好比計算能力、網絡性能、I/O能力等;
基礎設施服務的技術基礎是虛擬化技術,包括計算、網絡、存儲的虛擬化技術,計算的虛擬化不管在硬件或軟件層面都相對成熟,而在網絡、存儲的虛擬化上網易雲的選擇是軟件定義的技術。
在計算虛擬化方面,網易雲採用的是高效穩定可靠的KVM虛擬化技術;
在網絡虛擬化方面,網易雲基於OpenVSwitch採用最新流行的SDN技術,得到更大的網絡靈活性;
在塊存儲方面,網易雲採用的是可擴展性較強的Ceph技術;
網易雲使用開源雲平臺框架OpenStack實現對上述資源的高效管理;
容器是網易雲容器服務資源交付的最小單位,網易雲採用了最新Docker技術,實現應用交付的標準化;目前的容器服務基於Docker1.12版本打造。
要基於容器實現一個可水平擴展的產品服務端架構,須要使用容器編排技術實現對容器集羣的發佈、回滾、遷移、擴容、縮容等。網易雲的容器編排基於開源項目Kubernetes,Kubernetes服務將資源抽象爲三個層次:容器(軟件及運行環境),Pod(相關聯的容器組合)容納一個或多個容器,Node(提供計算/網絡/存儲的資源節點)容納一個或多個Pod。
網易雲團隊對這些核心技術有全面的掌控力,一方面也體如今網易雲對這些開源技術的貢獻和參與上:
以OpenStack和Kubernetes爲例,網易從2012年4月開始對OpenStack E版本貢獻代碼,去年下半年網易雲開始向Kubernetes社區貢獻代碼,是國內最先向這2個社區貢獻代碼的團隊之一。
使用VxLan大二層技術實現網絡數據面,基於OpenVswitch開源虛擬交換機實現OpenFlow協議
基於OpenStack Neutron實現網絡控制面
兩類塊存儲後端:1)基於Ceph的普通塊存儲;2)基於軟RAID技術的自研高性能塊存儲(用於高性能IO場景如數據庫等)
基於OpenStack Cinder實現塊存儲資源管理
採用KVM虛擬化技術
基於OpenStack Nova實現虛擬機生命週期的管理
首先,容器的計算資源應該如何提供?應該跑在物理機上仍是虛擬機上?從公有云層面來講,在容器的隔離性不是特別好的狀況下,仍是要跑在雲主機上面,這是對用戶最基本的安全承諾。
好處1:因爲是操做系統層面的輕量級虛擬化,容器安全性一直是用戶很是關心的問題,也制約着容器技術的發展。容器安全性問題以「容器逃逸」問題最有名,也就是黑客是能夠經過容器的一些漏洞滲透到運行容器所在的宿主機上,對宿主機上的其餘容器以及宿主機自己都形成巨大的威脅。在容器安全性問題沒有獲得有效解決前,將容器運行在虛擬機上,利用虛擬機的強隔離性,能夠加固容器的安全性。
好處2:因爲容器是輕量級虛擬化,全部容器共享宿主機的內核,宿主機上一個容器的運行異常和故障,頗有可能致使宿主機內核的crash,從而影響宿主機上其餘容器的正常運行;所以,將容器運行在雲主機中,儘量少的容器共享同一個內核,能夠實現故障的隔離,提升系統穩定性;
好處3:因爲容器運行在雲主機中,咱們能夠大膽把一些系統的能力如設置iptables的能力開發給用戶,而不用擔憂開放這些能力會對宿主機系統形成很大的影響。這可使得用戶獲得更多的功能,對容器具備更強的掌控;
這樣作的缺點在於:容器運行於雲主機,要忍受硬件虛擬化技術帶來必定的資源和性能開銷。
私有網:虛擬平坦二層網絡、租戶間徹底隔離,經過容器私有網卡接入
公網:容許綁定公網IP到容器,經過容器公網網卡接入
容器網絡由基礎設施服務來提供,並確保網絡的性能、可擴展性;容器不關心和處理網絡性能、可擴展性問題,只管用雲提供的網絡服務建立和使用相應的網絡。網易云爲每一個租戶提供一張徹底隔離的私有網絡以及一張全部租戶共享的公網。
私有網接入:基於雲主機上的網橋和容器veth pair實現
公網接入:將雲主機上的公網端口置入容器的namespace中
容器的存儲也是比較難解決的問題,多數容器都是無狀態的,也就是說容器內部不該該保存用戶有用的數據,一個容器掛掉後,用鏡像能很快啓動另外一個容器,保證系統的正常運行。從架構上來講這個設計很好,彈性可擴展。但若是架構設計能力不是太好的狀況下,很容易出現有狀態容器的需求。
但不論是Docker仍是Kubernetes都不解決容器的存儲問題,只能夠用docker -v指定一個數據目錄,因此在構建容器雲時有2個需求:
容器根目錄rootfs會保存其運行時數據,須要用雲盤保存容器rootfs數據
容器須要掛載雲盤做爲data盤
Docker默認會將全部容器rootfs都存儲在overlay目錄下,不一樣容器rootfs數據沒法有效區分並隔離
實現Docker啓動時可指定獨立rootfs的功能
在啓動容器前將雲盤掛載到啓動容器的rootfs上
網絡安全也是雲平臺設計很是重要的一點
L2過濾:確保報文源MAC地址是系統所分配端口MAC地址,防止ARP欺騙
L3過濾:確保數據包源IP是系統所分配IP,防止IP地址欺騙
L4過濾:過濾指定的TCP/UDP端口,便於實施網絡封禁
基於Intel DPDK技術實現高性能實時抗攻擊
保證用戶所申請網絡帶寬
有效利用空閒網絡資源,免費提高用戶帶寬體驗
基於Linux Traffic Control並修改OVS,實現保證速率、最大速率
將小包按照MPU(Minimum Packet Unit)大小來處理
網絡QoS另外一個重要問題是網絡小包過載的問題,
問題:VXLAN小包處理性能不夠好,網絡小包過多致使宿主機CPU過載(軟中斷過多),影響網絡性能和穩定性
方案:限制容器網絡的PPS (Packet Per Second)
容器運行於雲主機,容器啓動依賴於雲主機先啓動,而基於硬件虛擬化技術的雲主機啓動速度較慢。
一、定製系統鏡像,裁剪沒必要要服務啓動加載項;
二、雲主機IP靜態化,加速網絡初始化過程。IP靜態化的緣由:雲主機網絡初始化使用DHCP服務獲取網絡IP和路由等信息,會佔用較多啓動時間。在網絡服務啓動前使用Cloud-init和ConfigDrive完成網卡名稱匹配和IP配置信息注入;
三、優化OpenStack建立雲主機流程,主要是在OpenStack的計算節點上作了一些優化。
建立容器在40秒內完成
內網使用巨幀(Jumbo Frames)模式,提高數據傳輸的吞吐量。
使用不一樣內核版本和OVS版本的組合,VxLan性能差別很大,在萬兆網絡環境下使用3.18版本內核 + 2.6版本OVS,雲主機單鏈接網關轉發性能可近4Gbps,雲主機多鏈接網關轉發性能可達近9Gbps,雲主機間互訪近4Gbps
社區Ceph在osd進程重啓時會出現長時間、極其嚴重的性能衰減(80%+),緣由是osd重啓時要恢復重啓期間髒數據對象,會消耗大量網絡/磁盤開銷
在pglog記錄重啓期間數據對象的增量數據,在重啓時增量恢復數據對象
解決效果
減小重啓過程對集羣正常I/O性能影響( I/O性能下降10%~20%之內)
縮短重啓恢復所需時間(重啓單個osd從10分鐘減小到40秒左右)
原生的Kubernetes沒有租戶和多租戶的概念,意味着要給每一個用戶部署一套Kubernetes的集羣管理系統,網易雲用一套Kubernetes集羣去管理全部租戶的容器,這跟社區版本中徹底不同的地方
將容器的資源按照多租戶進行分類,以下圖所示,將node、存儲、網絡等集羣共享的資源實現租戶隔離
實現租戶資源的安全訪問控制,爲每一個租戶實現獨立的認證和受權
原生K8S編排的可擴展性有瓶頸,沒法支持更大規模節點的編排
K8S各組件在高水位下資源佔用太大
實現調度器並行調度,提高集羣調度能力
實現副本控制器多優先級處理,提高容器建立速度
精簡內部負載均衡轉發表
優化api-server和kubelet、kube-proxy,減小內存資源佔用
問題:原生scheduler調度是全集羣串行,不可並行擴展
優化:全部資源按用戶分組,全並行調度,集羣規模再大也能瞬間調度
問題:原生controller對副本的增量的增/刪/改和全量定時任務單隊列處理
優化:增長多優先級隊列(Add>Update>Delete>Sync All),讓實時控制流優先處理,提高容器建立速度
問題:原生使用iptable全局轉發,性能隨集羣規模增大線性遞減
優化:租戶之間網絡隔離後,能夠將轉發規則精簡到各個租戶內部
問題:這些服務隨着集羣規模增加,內存也都直線上漲
優化:agent只加載本身租戶擁有的namespace下數據, apiserver增長索引下降cpu以減小併發協程數
支持3w+容器的編排
高水位下容器建立時間40s以內完成
K8S上節點佔用內存優化爲原來的1/4,Api-Server內存減小了1/4
數據採集:基於CAdvisor採集計算存儲網絡等監控如cpu/mem/io/tcp鏈接/網絡流量
數據推送:Agent負責從CAdvisor拉取監控數據並推送到後端進行數據聚合
數據聚合:將相關監控項按照容器、pod、副本等層次聚合並展現
雲計算的研發是一項系統的基礎開發工做,有很是大的難度難,雲計算產品最重要的是穩定性、性能和安全,後續的工做也將圍繞這三方面展開。