小白也能玩轉Kubernetes 你與大神只差這幾步
本文較長,請耐心讀完,預計閱讀時間:38分鐘
隨著Kubernetes技術熱度的不斷提升,大容器時代的序幕已經開啟。容器技術日新月異,在企業應用實踐中得到了不斷的發展,高效的運維、管理和部署都成為雲服務的重頭戲。而與此同時,Kubernetes雖然降低了容器的使用門檻,但其本身的技術門檻卻並不低,這種矛盾引起了開發者的關注,也成功在2018年將Kubernetes推到了頂峰。
6月30日,騰訊雲聯合InfoQ舉辦的雲+社區技術沙龍,以Kubernetes 上雲一鍵部署、雲上大規模計算平台構建、CIS底層技術實現、Tencent Hub技術架構與DevOps落地實踐等五大主題內容,分享容器與k8s技術的部署優化與應用實踐。本文整理了講師演講精彩內容!
Kubernetes 上雲一鍵部署實踐
在2016年底,騰訊雲開始提供全託管Kubernetes服務,主要提供了四個方面的功能,第一,一鍵部署完全隔離的Kubernetes服務,用戶獨享所有結算節點和控制節點,並提供集群的全生命周期管理;第二,為方便Kubernetes使用,在控制台進行了界面包裝,通過可視化的方式創建負載,避免手工編寫代碼;第三,提供周邊監控能力,與騰訊雲監控產品打通,直接在產品界面上使用;第四,在Kubernetes集群外還提供了Docker鏡像倉庫、Tencent Hub、CI/CD等功能,提供一站式應用上雲解決方案。
騰訊雲容器服務 Kubernetes 組件一覽
Kubernetes的運行需要進行Master組件和Node組件的初始化。
Master組件最簡單的部署要包括Kube-apiserver、Kube-contioller-mannager和kube-scheduler。Kube-apiserver是整個集群的集中存儲器,其功能包括了所有組件與Kubernetes的交互、部分工作負載的存儲、部分用戶對存儲的需求。Kube-controller-manager主要負工作負載在集群里的運行;Kube-scheduler主要負責pod的調度,如所在的運行機器、調度到集群含GPU的節點等調度工作。
集群的Master組件部署好後就需要部署一些 Node,主要包括兩個組件, 第一個是負責在Node上創建Pod的kubelet;第二個則是負責程序在集群配置規則使其能夠被自動發現和訪問的kube-proxy。
此外,騰訊雲還提供了一些自研組件。第一個組件是hpa-metrics-server,為了讓用戶能夠使用Kubernetes提供的Pod橫向擴展控制器而研發,其優點在於,除了基於CPU和內存擴展之外,還能擴展pod出入帶寬的指標,方便用戶適應更多擴縮容場景。第二個組件是則是cbs-provisioner,提供了pod使用騰訊雲cbs塊存儲服務的能力;第三是ccs-log-collector,主要是負責收集容器里pod運行日誌。
容器網路
當Kubernetes把控制組件搭建起來後,它要求網路提供三點,在pod不使用NAT的情況下,第一,集群內所有容器之間可以進行通訊;第二,所有的節點和容器之間可以進行通信;第三,為了應對服務發現的需求,降低網路複雜度,要求不能使用NAT,並實現Node和pod之間的扁平化網路。
圖片
騰訊雲Kubernetes使用的方案如上,這一方案方案直接使用了VPC提供的路由能力global route。使用 docker bridge 網路模式;pod ip 由 cni 插件分配;pod可以跨主機訪問使用 vpc global route;採用了扁平化網路,主機、容器間實現對等互訪。Kubernetes結點加入到一個集群中觸發網路的過程如上圖所示,這套過程中Docker採用了bridge的網路模式,pod IP直接由cni插件分配。
容器存儲
這套Kubernetes集群中主要集成了騰訊雲的塊存儲服務的CBS和CFS兩個能力。
圖片
Kubernetes將volume掛載到pod裡面時包含的過程如下:首先,Kube-controller-manager會為CBS提供volume進行準備。即會先創建一個雲盤,然後將創雲盤插到對應的主機上,主機上的Kubelet會做一個mount動作,將設備mount到一個Kubernetes指定的文件夾,Kubelet在創建這個pod時,會通過mount的形式把mount到的目錄實際掛載到容器的namespace里。當pod銷毀後, volume不再被需要,就會反向執行,先從主機上把對應的塊設備先umount掉,再把detach掉,然後由Kube-controller-manager根據對應的plugin設置銷毀或保留。
Kubernetes volume的插件機制主要包括了三種,第一種是早期使用的In tree volume plugin,需要將代碼寫在的代碼倉庫中,會影響正常存儲功能的使用和集群穩定性;第二種是Flex Volume在擴展性和穩定性上有所增加,能夠通過特定介面的二進位文件,實現mount和umount動作。這種方式的缺陷在於自動性不足且對環境有要求;第三種基於社區CSI介面實現的插件,也就是將Flex volume的二進位文件工作全部放到了容器裡面,讓Kubelet與對應功能的插件通信,最終實現mount和umount的動作。
容器日誌與監控
在Kubernetes裡面並沒有提供默認的日誌方案,資源消耗較大且步驟複雜。騰訊雲容器服務的日誌收集控制器主要基於Fluentd + kubernetes CRD(custom resource definition)實現,能夠提供可視化配置。
圖片
該控制器支持收集容器的標準輸出,也支持收集pod所在的Node上主機文件路徑的內容。另外可以通過LogCollector監聽Kubernetes-apiserver資源,生成對應的Fluentd的配置文件,觸Fluentd重載收集日誌文件。直接配置Fluentd收集pod對應的路徑規則,根據需求做日誌路徑,將不同的日誌發往不同後端,這樣就實現了日誌收集。
圖片
在監控方面,Kubernetes里的pod性能信息和雲監控進行對接,在用戶的Kubernetes節點上運行agent,在kubelet里內置的cadvisor收集pod運行性能信息,再去apiserver獲取pod對應的元數據並進行打標籤,然後上傳到騰訊雲監控服務。
另外基於騰訊雲存儲的監控指標實現hpa-metrics-server, 再利用Kubernetes提供的HPA能力會定期獲取pod當前的入帶寬、出帶寬等指標熟練,並且根據定義進行擴容和縮容。
CVM上部署Kubernetes
在早期,為了實現產品快速上線,同時滿足完全隔離的全託管Kubernetes服務,Master組件部署在一台CVM並放到用戶VPC里,用戶的Node節點直接在CVM的機器上,在此基礎上做Kubelte等參數初始化工作、集群證書配置、默認拉取鏡像憑證初始化等工作。
圖片
該方案節點均處於用戶VPC中,通過Agent初始化部署整個集群,缺點就算管理困難。通過SSH直接登錄到客戶的Master節點進行運維操作,無法編程化,而且容器運維與Kubernetes關係離散。
Kubernetes in kubernetes
在此前,每個集群都在ETCD裡面各自目錄,相當於軟隔離的措施。但ETCD並不是為海量數據存儲服務的,因此在線上運行了數萬個集群後, ETCD問題越發密集。因此最終決定了把Kubernetes部署在Kubernetes裡面,通過Kubernetes API去管理Master組件,包括的apiserver、kube-controller-manager和自研組件。這樣做就不需要通過SSH方式,到每台機器上進行操作,而是直接通過deployment提供的滾動升級能力來完成。
這樣做的話可以充分利用Kubernetes的健康檢查和就緒檢查等機制實現故障自愈。基於hpa-metrics-server,可以實現apiserver的動態擴容,滿足Kubernetes集群節點對於apiserver性能的需求。
圖片
但是基於CVM的部署方案,所有的組件都部署在用戶的VPC裡面,如果我們把所有組件部署在Kubernetes Master裡面,而且不能給每個用戶部署一個Kubernetes集群。所以騰訊雲提供了一個專門的Kubernetes集群,運行所有集群的Master。VPC提供的彈性網卡能力,直接綁定到運行apiserver的pod里,去實現和用戶Node相關的互通。
通過在Kubernetes集群裡面部署Kubernetes Master組件,成功降低了運維成本和Master組件的資源消耗。
CIS底層技術實現
Kubernetes上雲部署實現了運維簡化的基礎,各種優質工具的開發則進一步丟下了開發者的包袱。對於開發者而言,Docker應該是非常常見的一種技術。通過Dockerfile或者Docker build 命令打包鏡像,通過Docker pull、Docker push命令和容器倉庫進行對接,最終實現跨平台的運行,Docker Wrong命令直接把Docker鏡像運行了起來。
但Docker的問題在於管理複雜,需要Kubernetes簡化編排。可是Kubernetes本身卻比較複雜,一是安裝複雜,組件頗多,需要master節點、Node節點等,還需要諸多軟體,如apiserver、controller-manager、scheduler、Kubelet等;另外資源也複雜,入門需要一定時間。
騰訊雲原來有TKE集群,能夠幫助用戶快速建立Kubernetes集群,master節點和node節點都是由騰訊工程師維護,給用戶使用帶來諸多便利。但是問題在於,當集群節點突發性不夠用時,資源受節點限制,擴展需要手動添加節點,至少要幾十秒延遲才能完成創建。
圖片
其他方法還有,如用Kubernetes開源的CA與騰訊雲彈性伸縮組進行對接,當節點不夠用時,可以通過CA來擴容一個節點。或者採用HPA,可以進行pod橫向伸縮容,但這樣做雖然可以解決部分靈活問題,但依然不夠。
在這些原因的驅使下,騰訊雲CIS(Container Instance Service)服務就有了需求動力,其本質就是Serverless Kubemetes服務,將Kubernetes集群交給雲廠商管理,而用戶只需要關注Docker本身即可。
容器實例服務
容器實例服務(Container Instance Service,CIS)是一種使用容器為用戶承載工作負載,不需要用戶管理、維護伺服器的全託管容器服務。它具有便捷、安全、便宜、靈活等四個特性。
便捷意味著用戶無須購買底層資源,通過簡單的配置,就可以用docker image生成容器實例,而容器結束實例即會結束,無須手工釋放,也可以配置重啟策略使實例長久存在。
安全是因為CIS由騰訊雲自己進行集群維護,Kata containers提供了docker級別的生產速度和vm級別的資源隔離,在實例運行在用戶的vpc網路中,支持配置安全組和ACL策略進行訪問控制。
在成本方面,CIS根據購買的cpu、內存量,按實例實際運行的時間按秒計費;需要多少用多少,從啟動開始,實例無論出於什麼原因一旦結束即停止計費,價格合適。
而靈活性方面,容器實例支持購買超小資源,在一個pod里可以跑多個容器;一個實例可以是一個容器,亦可以包含多個相關容器;
圖片
在應用場景方面,容器實例支持秒級批量啟動、邏輯結束自動釋放、便宜的價格、支持通過內外網和其他資源互通等特性使其很適合進行計算作業。
其次也可以有有鏡像的快速驗證產品,用戶只要擁有程序的容器的鏡像,就可以通過一些簡單的配置,以極低的成本把程序運行起來。例如進行一次程序驗證、爬取一個網站、部署一個 Web 服務等等,任何支持容器的簡單應用都可以使用容器實例來部署。
CIS技術方案
CIS可以讓用戶只需要關注容器實例本身,將運維CIS所屬的落地K8s集群的工作交給騰訊雲。用戶在啟動一個CIS時,騰訊雲會對應在K8s集群中提供CVM資源,在這個資源給出pod和對應的容器,用戶就可訪問該容器。CIS資源有VPC屬性,用戶可以直接通過網路訪問所購買的CIS實例。當然,它還會和我們的Tencent Hub和image registry去進行對接。
圖片
CIS底層由多地域多套Kubernetes集群組成,而每個CIS實例生成時會配置用戶VPC的彈性網卡的功能。VPC彈性網卡本質上是,彈性網卡可以達到VPC網路的相連,彈性網卡是掛在容器裡面。當有了VPC屬性之後,它就可以訪問VPC內的其他CIS、CVM、CDB和COS等網上的其他資源打通。
一般來講,容器中的日誌真實文件會隨著k8s pod的消失而消失。但要支持秒級計費能力,就需要通過日誌判斷實例,因此日誌是不允許消失。所以騰訊雲採用的是時序型資料庫,通過開源軟體Filebeat來收集CIS日誌,轉到ES資料庫中。在每個實例節點上部署DaemonSet後,日誌轉到CIS集群中,用戶查詢日誌時,就會通過ES集群中的相關API進行查詢。
CIS 與 Serverless Kubernetes 集群
開源項目Virtual Kubelet是一個可以部署在已有Kubernetes集群節點上,並把該集群的pod調度到「無限資源」的虛擬節點CIS集群上。pod節點可以部署在virtual Kubelet上,其可以通過CIS集群落地,pod上的彈性網卡屬於Kubernetes的VPC網路,這樣做就可以直接在CIS上運行大批量、周期性的、突發的任務,作為已有 kubernetes 集群的資源補充。
圖片
Virtual Kubelet可以與騰訊雲容器服務( Cloud Container Service,CCS)共同構建Severless服務。CCS 支持用戶使用CVM、VPC、LB、CBS等基礎產品搭建具備完全操作許可權的 Kubernetes 集群,通過在 CCS 集群 node 上部署 virtual kubelet 可以把 CIS 實例作為集群 pod 調度。
具體操作時,需要在 CCS 上任一節點上部署 virtual-kubelet pod,該操作會為該 CCS 集群添加一個虛擬節點「virtual-kubelet node」;然後新建 DeploymentJobCronJob 時通過將目標節點指向 virtual-kubelet node,則這些服務的 pod 不會佔用 CCS 集群的 CVM 資源;
圖片
CCS 服務的 pod 被調度到了 CIS 服務上,意味著用戶可以不考慮 CCS 集群的底層資源,當然也不需要做 CVM 擴縮容,就可以創建「無限」的服務;通過 virtual kubelet 調度創建出的 CIS 實例依然會被上層的 CCS 服務控制,例如 Deployment 會把下層的 CIS 實例總保持在期望的數量和狀態;這些 CCS 服務一旦被刪掉,跟其相關的 CIS 實例也會被自動刪除;
容器實例與Clear Containers
總結來看,Docker是一個輕量級的虛擬化項目,同時Docker是K8s pod的runtime;目前用戶面臨的問題是。將用戶容器運行在單獨的虛擬機上可以保障租戶間的隔離安全,但是用戶只需要一個容器,虛擬機的其他是多餘的;而Clear Containers和Docker的區別在於,前者不共用內核,基於KVM隔離更安全;
Clear Container與原來的物理機啟動厚重的虛擬機相比,虛擬機上再啟動docker提供服務,現在直接在物理機上啟動輕量的clear container,直接給用戶提供服務,虛擬化層級變小,更節約資源,也更提高性能。
在網路方面,Docker的網路有一個VETH設備,如果你訪問外面,會有一個Docker0網橋,如果你訪問外網,會有Snat。但是是基於KVM的虛擬機,很多廠家都是用QEMU把虛擬機啟動,虛擬機裡面有一個虛擬網路設備,host上更多是一個tap設備,也就是說虛擬機不支持VETH設備。如果要復用Docker生態,所以又有一個VETH設備,這裡就有一個cc-bridge網橋,網路就通過到host的tap0—cc-bridge—eth0—veth0—Docker0,再進協議棧,這樣出去。
圖片
Clear container比Kubernetes更注重技術細節,其技術實現包含cc-runtime、cc-shim、cc-proxy、cc-agent、miniOS(kernel和rootfs);並且只實現runtime,把原來runc拆分成cc-runtime和cc-agent,再加上VM帶來的額外通信機制。
圖片
Clear Containers原來是每個容器都會起一個虛擬機, pod有多個容器的概念,難道每個pod裡面每個容器都要起一個虛擬機,一個pod有若干個虛擬機嗎?
事實上並不需要如此。Clear Containers可以藉助CRI-O和K8s進行對接。在過去,如果要創建pod,直接是Kubelet和Docker進行訪問,然後把這個容器創出來。加了CRI-O這個組件之後,Kubelet作為cri-o client,對cri-o server控制一個run client,基於Docker的pod就起來了。當然,如果是Clound Containers或者Clear Containers,就要調用cc-runtime,需要根據應用編排安全的需要選擇
Tencent Hub技術架構與DevOps實踐
DevOps的概念從2009年至今已經過去了近十年的時間。DevOps應當以業務敏捷為中心,構造適應快速發布軟體的工具和文化。那麼Tencent Hub是什麼?Tencent Hub核心是兩部分,第一部分,是一個多功能的存儲倉庫,包含了Docker鏡像存儲功能以及helmcharts等存儲;第二部分,Tencent Hub是一個DevOps引擎,通過workflow工作流的編排,去幫助大家建立自己的DevOps流程。
Tencent Hub技術架構
Tencent Hub的總體架構, Tencent Hub在鏡像倉庫的存儲是基於COS存儲,因為COS可靠性非常高,能達到11個9的可靠性;Tencent Hub有一個自研workflow引擎,使用YAML定義DevOps流程,讓DevOps本身達到Program的方式;基於容器的插件機制(Component),最大限度復用已有DevOps任務;Tencent Hub使用容器去實現插件機制,來封裝用戶自定義的DevOps任務。使用Kubernetes作為job執行引擎,具有良好的可擴展性;在Docker存儲方面,加入了Docker鏡像漏洞掃描等。
在Tencent Hub,最核心的存儲還是Docker鏡像。Tencent Hub除了公共的鏡像存儲之外,還支持私有的鏡像存儲。在私有鏡像存儲裡面,需要通過登錄才能獲取或者上傳自己的Docker鏡像。
首先,客戶端發起push/pull操作,client連接Registry檢查許可權;Registry返回401,並且返回了獲取Token的服務地址;client請求授權服務獲取Token(OAuth2或Basic Authentication);client返回一個Token表示客戶端的訪問授權列表;client攜帶Token重新請求Registry獲取資源;Registry校驗Token以及其中的許可權列表通過後, 與client建立pull/push會話,開始上傳/下載數據。
圖片
Tencent Hub pull 的授權流程大體如下, Docker服務端首先會去訪問webhook,客戶端會根據當前是否有Token來返回一個授權的地址,即hub.tencentyun.com/token這個地址。然後客戶端就會自動訪問/Token的URL,帶上當前的狀況以及申請的許可權範圍,最後生成階段再返回。最後,當前面都申請完成之後,就會進入Docker鏡像拉取流程。
Docker鏡像是分層組織形式,每個Docker鏡像包含多個Layer和一個Config文件,每個Layer構建一個Docker鏡像文件系統裡面出現的差異,Config文件包含當前Docker鏡像能運行的一些環境要求。這些文件被一個Manifest文件引用起來,形成可以一直拉取Manifest,通過它可以找到所有的Docker鏡像內容。
設計好處主要有三點。首先,由於所有數據可以被校驗,安全性高;第二,相同內容的layer只需存儲一份,所以冗餘少;第三,整個Docker鏡像里無論哪個Layer有改變,都會最終影響到Manifest的改變,所以Docker鏡像並不是重新修改一個Layer,而是重新生成,因此做緩存的時候就可以在不同環境下部署緩存。
圖片
Tencent Hub鏡像的存儲核心是利用了Docker官方實現的distribution。distribution的實現在這個圖裡面描述得比較清楚,代碼層次結構也幾乎相同。最上面有API root層分發,第二層會有一個許可權控制的一層。在許可權控制下面有實現API協議的函數處理,提供主要的業務邏輯實現。最終是distribution的實現,提供了一套存儲的插件機制,有一個標準的存儲介面,規定了文件上傳、文件移動。
圖片
目前騰訊雲容器服務的倉庫是CCR,而並不是Tencent Hub。CCR有兩個問題,第一是不同地域的鏡像是不通的,直接依賴了COS提供的分發能力,COS是無法跨區域的,所以會存在問題。第二是拉取多個鏡像時,對延時不敏感,但是對吞吐量很敏感。
在Docker鏡像的存儲完成之後,還是提供了一個Docker鏡像的靜態掃描。通過對比包管理(apt, yum)記錄的軟體版本與本地漏洞資料庫中的軟體版本得出漏洞列表。Scanner 周期性地與漏洞資料庫進行同步獲取最新的漏洞信息;鏡像上傳完成後發送到掃描中心進行非同步漏洞掃描;而當新漏洞被發現時,Registry也會受到通知,同時可以通過webhook將信息投遞給開發者
workflow引擎設計與實現
為什麼要去做Tencent Hub的DevOps引擎呢?因為很多客戶在上雲的時候遇到了操作重複性的問題。而且DevOps的自動化要求還很高,再照顧到一些客戶的需求,因此要做一個DevOps的工具,去幫用戶來建立自己的DevOps流程。
這就需要考慮很多事情,第一,把DevOps任務編排起來,需要做到一個能盡量覆蓋到盡多客戶DevOps需求的編排邏輯,比如Workflow;第二,DevOps任務是差別較大,需要把這些任務交給客戶自己去完成,需要設計一個插件機制Component;第三,用戶的DevOps流程運行在Tencent Hub裡面,需要做很簡單的任務調度,最終還是選擇Kubernetes來省去很多運維工作,監控都可以去復用。
按業界通用的方法把workflow設計成三級結構,每個workflow包含多個stage來完成,每個stage裡面會有很多job。job這裡會有並行和串列的執行方式。stage有一個類型叫past+prst。在DevOps流程當中,在合適的時候是需要人工介入的,設計可以暫停的stage就能適應這樣的場景。
圖片
workflow的設計生命周期對流程推動十分重要。workflow可以被觸發執行,有三種方式。一,把某一條workflow和代碼關聯起來,當提交代碼的時候,可以觸發這條workflow的執行;二,可以和Tencent Hub的鏡像存儲關聯起來,不需要代碼去觸發,可以通過push一個鏡像去觸發;三,通過調API直接觸發某一條workflow。
被觸發後,就可以系統把它置成一個pending狀態。Workflow被觸發執行,一個新建的workflow實例被置於pending狀態,經過配額檢查,scheduler調用k8s API執行第一個job,workflow實例進入scheduling狀態;StatusFetcher檢測job在k8s中的狀態,如果不是pending,workflow實例進入running狀態;
Scheduler遇到可暫停的stage(type=break),待stage中任務執行成功後,workflow實例中的job被暫停調度,workflow進入paused狀態,等待外部API調用喚醒workflow的執行;end是一組狀態的描述,實際上包括timeout、failure、success、canceled四種狀態。處於paused狀態的workflow可以被終止。
workflow上job在設計時需要考慮四點。第一,job可以都考慮成一個函數去處理輸入,在內部做一些業務邏輯,通過定義的標準輸出處理完的信息;第二,job可以從workflow全局環境變數中去讀取,傳進來做一些邏輯。第三,每個component都需要和外界接觸,因此workflow里會去提供cache和artifact指令。第四,workflow沒有辦法去循環執行,只是一個DAG構成的關係去一條一條向前執行。
關於artifact和cache的實現和作用是不同的,設計Cache是用來在不同的job之間共享和傳遞數據;Artifacts則可以保存在提供的倉庫裡面。Cache的具體實現如保存文件夾,它會把指定的文件目錄進行壓縮,上傳到Tencent Hub的圖形存儲裡面。當下面有一個Job依賴它的時候,會在Component內部下載下來。
為什麼要選擇用容器來做DevOps呢?第一,面對的所有用戶是公共服務,隔離性是第一要務。用容器可以非常方便的幫我們實現不同用戶的任務隔離,有些用戶可能對自己任務的安全性要求非常好,後期還會考慮和CIS做結合,直接用Clear Container來提供更高的隔離性。第二是復用,在不同的部門之外,它們的技術段可能會有相似的,後台有一些公共的DevOps任務需要去使用,通過容器Docker鏡像可以共享這樣的邏輯;第三則是標準,組件的開發維護可用本地Docker進行測試;第四是平滑,從而能讓已有的DevOps任務可通過容器快速進行封裝。
Component函數一樣會有涉及到Input和Output。Input方面,輸入值以環境變數的方式傳入到Component中,包括workflow全局變數和上游Job的輸出變數;而output方面,輸出值寫入到stdout,workflow通過分析日誌進行提取;輸出值格式為: JOB_OUT key=value ,可以通過輸出多行Log來輸出多個值;Component進程執行成功後以狀態碼0退出。
圖片
Workflow是採用了TKE去執行的,選擇用DevOps做workflow引擎的執行集群是基於以下三大特性考慮的。首先,Kubernetes的可靠性使得TKE非常可靠,從而不必去擔心運維難題;第二,workflow跑的很多任務可能會佔用不同的資源,而TKE可以做到自動擴縮容,能為客戶提供構建的能力,不需要人工介入;第三的資源分配更靈活,客戶的workflow資源佔用大小不同,這對Kubernetes來講解決並不難。
關於job的兩個hook,在實現的時候需要注意到這些事情。Flow引擎通過分析Component的config,保存Component定義的Entrypoint和Command;實現CommandWrapper程序,Job運行指定該程序為Pod的Command;CommandWrapper啟動後處理PreStart動作,如下載依賴的Cache;CommandWrapper fork子進程運行Component定義的Entrypoint和command;子進程退出後,CommandWrapper處理PostStop動作,如上傳Artifact、Cache等;最後,CommandWrapper以子進程的返回碼作為返回碼退出。
每一個構建的workflow的job需要去關心它的Log。Job是一次性任務,利用k8s api讀取日誌,比獨立的日誌收集通道更簡單;dispatcher讀取日誌之後,使用multi writer將日誌交給StatusFetcher保存,同時可以通過websocket將日誌推送給web頁面。
圖片
到此,workflow引擎實現和設計就基本完成。通過Tencent Hub,經過思考,如何搭建自己的DevOps流程是千差萬別的,以上方法站在公有服務的提供商角度,考慮給用戶最大的便利而建立的一套工具。
雲上構建容器化的大規模計算平台
看了這麼多的技術解析後,那麼究竟騰訊雲的容器技術在其用戶的手中是怎樣的狀態呢?晶泰科技是騰訊雲在藥物工業領域的合作夥伴,他們在雲端部署大規模科學計算平台與騰訊雲有著緊密的合作。
晶泰科技是一家以計算驅動的創新藥物研發科技公司,在藥物工業中,一款葯的上市需要經過複雜的研發工序以及10年以上的漫長研發周期,而且越是重磅的藥物,經歷的周期就越長;因此騰訊雲的合作夥伴晶泰科技致力於通過分子模擬平台、藥物動力學等技術,藉助雲端大規模HPC、AI驅動、量子演算法等預測技術,提升藥物工業中臨床前期的研發效率,為患者帶來更優質的藥物。
圖片
科學計算平台通常是跑在像天河這樣的超算上, 但超算上大規模資源的申請需要排隊, 對任務的調度管理, 數據存儲都不太靈活, 而且在計算性價比上優勢也不明顯,綜上我們提出, 能否把傳統的科學計算搬到雲端?目前一些批量計算、高性能計算已經遷移到雲端。在把兩部分技術結合之後,藉助雲端去構建一個大規模的HPC集群,可能會達到百萬核實量級,可能會用到上萬級的機器集群。
晶泰科技的小分子藥物晶型預測流程中,需要用到構像分析、力場訓練、晶體結構預測、結構聚類及排位演算法等,每個流程都需要大量計算支持,而且越靠後計算需求越高這就需要藉助雲計算,甚至需要多個雲融合在一起以便構建一個比較大規模的計算資源池,在裡面執行大批量科學計算任務。
計算平台演變
圖片
計算平台在這幾年發生了較大的變化。從2015年晶泰成立的時候推出了第一代計算平台,基於PBS調度系統以及NFS文件共享存儲,架構上類似於超算的PBS/LSF+SAN。系統都是使用開源組件搭建,命令行方式對任務進行提交及管理, 基本滿足了前期使用需求。但是隨著業務的發展,計算量需求越來越大,而第一代平台的計算資源利用率不足、PBS動態管理能力有限, 以及NFS的IOPS壓力等問題開始出現。
從第二代平台的迭代更新開始,我們使用Mesos對資源進行管理,自研Mesos的Framework, 使用Docker打包科學計算的軟體以及演算法, 從此開始了雲上科學計算的容器化之路。通過添加不同的計算資源, 計算池得到了進一步擴大。當我們單個資源池突破1000台機器時, 我們使用Golang重構了調度系統,以便支持更高性能的任務分發。接著我們通過接入多個公有雲廠商,實現多公雲資源彈性伸縮與監控。18年開始, 隨著k8s的高速發展, 調度平台也正式開始使用K8s去管理雲上的超算集群。
圖片
第三代平台技術產品上主要是CSP, Faces晶型預測系統服務,以及最終產出計算報告的全自動工具XtalVision。第二層主要是是預測流程中使用到的各種核心演算法,融合了現有的科學計算演算法進行二次開發、封裝,打包成一個Docker鏡像,業務人員只需要去使用這個Docker鏡像,就可以在平台上提交對應的預測計算任務, 如一些能量計算以及一些通用力場的計算。然後是我們支撐大規模科學計算的高性能計算平台,最下面就是公有雲的基礎資源。
騰訊雲容器服務實踐
圖片
需要注意的是,超算和信息服務的計算有較大的差異。科學計算的特點是計算密集型,計算時間長,通常是非同步計算,追求演算法的執行效率並行化,主要以工作站或超算為主;信息服務的特點則是IO 密集型,低延時高可用,利用架構提高系統容量及服務質量,大量使用雲計算。
在開始之前我們簡單介紹一下在雲上構建科學計算的鏡像, 科學計算使用的鏡像跟服務化的鏡像會有一些不太一樣的地方, 一般科學計算的鏡像大小會達到GB級別,因此需要對鏡像進行剪裁和分層優化,以便加速鏡像拉取速度。
下面的參數會涉及到鏡像拉取的性能以及並發率。如:kubelet --serialize-image-pulls=false是串列鏡像拉取,通常情況下是false,如果設置為true,需要更高版本的Docker支持, 同時docker storage需要使用overlay作為鏡像存儲。kubelet --image-pull-progress-deadline=10mins是鏡像拉取超時, Docker本身也會有並發拉取的參數在裡面(如:dockerd --max-concurrent-download=5),以便在任務分發時減少鏡像拉取時間。對於kubelet來說, 目前最新版的K8s已經支持動態修改Kubulet參數。
騰訊雲的TKE容器服務,基本實現了一鍵就可以構建出一個帶有Master的K8s集群。同時騰訊雲打通了TKE和騰訊雲其他雲服務交互通道, 更易於系統的快速集成。TKE會提供一個容器服務API出來,但是它主要還是針對一些信息服務編排, 對於高性能計算批量提交任務還不是特別適用, 因此我們使用了k8s原生API進行平台構建。
現在K8s已經發布到1.11版本,支持不超過五千個節點,在集群裡面不超過1.5萬個pod,以及不超過30萬個容器,單個節點不超過100個pod。K8s官方也提供了一些構建大集群的輔助文檔在裡面,但實際上在構建的時候還是會有形形色色的問題。
K8s主節點集成已經由騰訊雲構建出來,接下來需要要向集群中添加計算節點,TKE提供了彈性伸縮組對集群資源進行動態擴縮容。但出於節約成本的考慮,伸縮組需要是高度彈性, 可以快速擴容大批量資源, 同時也能在任務計算完成時快速回收資源。比如晶泰就會有如下業務場景:
平台一次性提交10萬個任務,每個任務需要8核的cpu去計算, 同時由於案例時間上的要求, 要求幾天之內要把這些任務算完,所以此時需要讓資源池從0擴容到1000/2000個節點一起跑。任務的計算複雜度很多時候都是有相似性的,因此計算的周期也比較相似,某個時間點就會有大批任務同時跑完, 大批量資源被釋放出來, 這個時候又需要快速回收資源。經過與騰訊TKE團隊一起排查, 目前基本在快速擴縮容這塊滿足了計算的需求.
到目前為此利用TKE構建了K8s集群並通過其快速彈性擴縮容組件實現資源的管控, 接下來我們看看計算平台上所支持的HPC任務.
圖片
簡單地從時間維度來看,可以分為短時間任務和長時間任務。從精度來看可以分為低精度和高精度任務。在藥物分子預測中的能力/排位等流程中都會對精度要求有,從右邊圖來說,不同的科學計算演算法在不同的流程中都會有一個精度及時間的差別,通常精度越高需要的計算周期越長。
在支持的HPC多節點並行任務中,一些公有雲的普通網路是沒有辦法滿足像MPI這種多節點並行任務的。通常MPI任務多節點需要有一個高性能的網路, 如IB網路,需要一些專有的網卡去支持遠程的直接內存訪問(RDMA)。
圖片
MPI任務的運行周期會相對長一些,右圖是在晶泰基於K8s實現的MPI任務。剛才提及現有的TKE提供的網路沒有達到通用的MPI的網路要求,但是一些數據並行化的MPI任務還是可以在一般性能的容器網路上面進行運算。它們特點是節點之間的數據交互通常是比較少的,這樣網路數據傳輸也比較少,能避免高性能網路的帶寬限制。其實k8s對構建高性能容器網路也提供了插件支持, 通過k8s Device Plugins可實現NVIDIA/AMD GPU及RDMA/Solarflare等外部組件接入。
圖片
容器雲TKE提供了健全的服務監控,能夠實時監控pod CPU以及內存。同時也提供了定製化的接入的方案,通過heapster+influxdb+grafana架構可以收集計算任務的cpu/memory信息,對於高性能計算關注的核心演算法效率問題來說, 這些監控數據對我們平台演算法的不斷改進提供了很好的指導方向 。
值得一提的是, kubelet 10250埠的參數,在安全組方面不能大意,如果沒有把計算節點10250埠封掉,容易導致入侵,因為在開啟了enable-debugging-handlers=true 的情況下,外部可以直接通過這個埠,到pod裡面進行集群調試。
綜合來看,Kubernetes的出現降低了容器服務的入門門檻和複雜性,解放了企業的技術精力,使之能夠完全投入到行業所處的技術領域之中。而如CIS、Tencent Hub等技術工具的發展,容器服務的部署、監控、運維和管理都在變得更加高效,無論是醫藥交通,還是科算超算,都已開始享受技術發展的紅利。可以看到的是,2018年的Kubernetes技術,就如繁星之上的皓月,望眼可見,普照各地。
_______________END _______________
請轉發、點贊,以示鼓勵!
歡迎分享到朋友圈,做一個有影響力的讀者!
※這7大工具引爆了第三次零售革命-智慧零售
※你應該了解的AI演算法,樹搜索和演化演算法
TAG:雲加社區 |