隨着社會的進步與技術的發展,人們對資源的高效利用有了更爲迫切的需求。近年來,互聯網、移動互聯網的高速發展與成熟,大應用的微服務化也引發了企業的熱情關注,而基於Kubernetes+Docker的容器雲方案也隨之進入了大衆的視野。開普勒雲是一個基於Kubernetes+Docker+Istio的微服務治理解決方案。git
如今各大企業都在談論微服務,在微服務的大趨勢之下技術圈裏逢人必談微服務,及微服務化後的各類解決方案。github
使用微服務架構有不少充分的理由,但天下沒有免費的午飯,微服務雖有諸多優點,同時也增長了複雜性。團隊應該積極應對這種複雜性,前提是應用可以受益於微服務。數據庫
固然這不是本文主要討論的問題,我不講微服務具體要如何拆分,每一個企業每一個應用的狀況都不太同樣,適合本身的方案就是最好的拆分方案。咱們主要來解決微服務化後所帶來的一些問題。編程
以上都是大應用微服務化所須要解決的基礎問題,若是還按照傳統的方式使用虛擬機來實現,資源開支將會很是大。那麼這些問題要怎麼解決呢?好比:api
固然面對上述這些問題咱們廣大的猿友們確定是有解決方案的。緩存
假設咱們是Java體系的應用,那解決起來就很方便了,好比咱們能夠考慮使用SpringCloud全家桶系列。也能夠拆分使用:網絡
Java體系下能很方便的作以咱們微服務化後的基礎部分,但依然不能很是舒服地解決環境一致性,而且若是有其餘語系的服務將很難融入進去。架構
咱們來看基礎編程語言通常有什麼組合方式來解決基礎問題。負載均衡
假設咱們是使用Golang語言,這裏再捧一下Golang語言。go語言簡直就是天生爲微服務而生的語言,實在不要太方便了。高效的開發速度及至關不錯的性能,簡單精悍。框架
跑題了~咱們使用上面這些工具也能夠組成一套還不錯的微服務架構。
可是這種方案也有問題,對服務的侵入性太強了,每一個服務都須要嵌入大量代碼,這仍是很頭疼的。
基於Docker+k8s搭建平臺的實踐方案。
Docker 是一個很是強大的容器。
使用了Docker以後,咱們發現可玩的東西變多了,更加靈活了。不只僅是資源利用率提高、環境一致性獲得了保證,版本控制也變得更加方便了。
之前咱們使用Jenkins進行構建,須要回滾時,又須要從新走一次jenkins Build過程,很是麻煩。若是是Java應用,它的構建時間將會變得很是長。
使用了Docker以後,這一切都變得簡單了,只須要把某個版本的鏡像拉下來啓動就完事了(若是本地有緩存直接啓動某個版本就好了),這個提高是很是高效的。
(圖片來源網絡)
既然使用了Docker容器做爲服務的基礎,那咱們確定須要對容器進行編排,若是沒有編排那將是很是可怕的。而對於Docker容器的編排,咱們有多種選擇:Docker Swarm、Apache Mesos、Kubernetes,在這些編排工具之中,咱們選擇了服務編排王者Kubernetes。
咱們來對比這三個容器編排工具。
Mesos的目的是創建一個高效可擴展的系統,而且這個系統可以支持各類各樣的框架,無論是如今的仍是將來的框架,它都能支持。這也是現今一個比較大的問題:相似Hadoop和MPI這些框架都是獨立開的,這致使想要在框架之間作一些細粒度的分享是不可能的。
但它的基礎語言不是Golang,不在咱們的技術棧裏,咱們對它的維護成本將會增高,因此咱們首先排除了它。
Docker Swarm是一個由Docker開發的調度框架。由Docker自身開發的好處之一就是標準Docker API的使用。Swarm的架構由兩部分組成:
(圖片來源網絡)
它的使用,這裏再也不具體進行介紹。
Kubernetes是一個Docker容器的編排系統,它使用label和pod的概念來將容器換分爲邏輯單元。Pods是同地協做(co-located)容器的集合,這些容器被共同部署和調度,造成了一個服務,這是Kubernetes和其餘兩個框架的主要區別。相比於基於類似度的容器調度方式(就像Swarm和Mesos),這個方法簡化了對集羣的管理.
不只如此,它還提供了很是豐富的API,方便咱們對它進行操做,及玩出更多花樣。其實還有一大重點就是符合咱們的Golang技術棧,而且有大廠支持。
Kubernetes 的具體使用這裏也再也不過多介紹,網站上有大把資料能夠參考。
kubernetes(k8s)是自動化容器操做的開源平臺,這些操做包括部署、調度和節點集羣間擴展。
到這裏咱們解決了如下問題:
固然還有監控,這個咱們後面再說。咱們先來看要解決一些更高層次的問題該怎麼辦呢?
在不對服務進行侵入性的代碼修改的狀況下,服務認證、鏈路追蹤、日誌管理、斷路器、流量管理、錯誤注入等等問題要怎麼解決呢?
這兩年很是流行一種解決方案:Service Mesh。
處理服務間通訊的基礎設施層,用於在雲原生應用複雜的服務拓撲中實現可靠的請求傳遞。
在雲原生應用中可靠地傳遞請求可能很是複雜,經過一系列強大技術來管理這種複雜性: 鏈路熔斷、延遲感知、負載均衡,服務發現、服務續約及下線與剔除。
市面上的ServiceMesh框架有不少,咱們選擇了站在風口的Istio。
鏈接、管理和保護微服務的開放平臺。
由於有大廠支持~其實主要仍是它的理念是至關好的。
雖然它纔到1.0版本,咱們是從 0.6 版本開始嘗試體驗,測試環境跑,而後0.7.1版本出了,咱們升級到0.7.1版本跑,後來0.8.0LTS出了,咱們開始正式使用0.8.0版本,而且作了一套升級方案。
目前最新版已經到了1.0.4, 但咱們並不許備升級,我想等到它升級到1.2以後,再開始正式大規模應用。0.8.0LTS在如今來看小規模仍是能夠的。
咱們先來看一下Istio的架構。
其中Istio控制面板主要分爲三大塊,Pilot、Mixer、Istio-Auth。
每一個Pod都會被注入一個Sidecar,容器裏的流量經過iptables所有轉到Envoy進行處理。
Istio能夠獨立部署,但顯然它與Kuberntes結合是更好的選擇。基於Kubernetes的小規模架構。有人擔憂它的性能,其實通過生產測試,上萬的QPS是徹底沒有問題的。
在資源緊缺的狀況下,咱們的k8s集羣是怎麼樣的?
Master Cluster:
Node:
(圖片來源網絡)
咱們所調用的Master的API都是經過 keepalived 進行管理,某一master發生故障,能保證順滑的飄到其餘master的API,不影響整個集羣的運行。
固然咱們還配置了兩個邊緣節點。
邊緣節點的主要功能是讓集羣提供對外暴露服務能力的節點,因此它也不須要穩定,咱們的IngressGateway 就是部署在這兩個邊緣節點上面,而且經過Keeplived進行管理。
最外層是DNS,經過泛解析到Nginx,Nginx將流量轉到集羣的VIP,VIP再到集羣的HAproxy,將外部流量發到咱們的邊緣節點Gateway。
每一個VirtualService都會綁定到Gateway上,經過VirtualService能夠進行服務的負載、限流、故障處理、路由規則及金絲雀部署。再經過Service最終到服務所在的Pods上。
這是在沒有進行Mixer跟策略檢測的狀況下的過程,只使用了Istio-IngressGateway。若是使用所有Istio組件將有所變化,但主流程仍是這樣的。
日誌收集咱們採用的是低耦合、擴展性強、方便維護和升級的方案。
Filebeat會跟應用容器部署在一塊兒,應用也不須要知道它的存在,只須要指定日誌輸入的目錄就能夠了。Filebeat所使用的配置是從ConfigMap讀取,只須要維護好收集日誌的規則。
上圖是咱們能夠從Kibana上看到所採集到的日誌。
目前咱們支持的報警有Wechat、kplcloud、Email、IM。全部報警均可在平臺上配置發送到各個地方。
整個架構由外圍服務及集羣內的基礎服務組成,外圍服務有:
集羣有:
集羣內部的監控有:
有沒有一種傻瓜式的,不須要學習太多的技術,能夠方便使用的解決方案?
開普勒雲平臺是一個輕量級的PaaS平臺。
爲了下降學習成本及部署難度,在開普勒平臺上部署應用很簡單,只須要增長一個Dockerfile 就行了。
Dockerfile 參考:
以上是普通模式,Jenkins代碼Build及Docker build。
這是一種相對自由的部署方式,能夠根據本身的需求進行定製,固然有學習成本。
其實徹底能夠作到自動生成Dockerfile,但每一個服務的要求可能不同,有些須要增長文件、有些在Build時須要增長參數等等。咱們不能要求全部的項目都是同樣的,這會阻礙技術的發展。因此退而求其次,咱們給出模版,研發根據本身的需求調整。
用戶把本身的Dockerfile跟代碼提交到Gitlab,而後在開普勒雲平臺填寫一些參數建立本身的應用。
應用建立完後會在Jenkins建立一個Job,把代碼拉取下來並執行Docker build(若是沒有選擇多階構建會先執行go build或mvn),再把打包好的Docker image推送到鏡像倉庫,最後回調平臺API或調用k8s通知拉取最新的版本。
用戶只須要在開普勒雲平臺上管理好本身的應用就能夠,其餘的所有自動化處理。
咱們從建立一個服務開始介紹平臺。
平臺主界面:
點擊「建立服務」後進入建立頁面。
填寫基本信息:
填寫詳細信息:
基本信息以Golang爲例,當選擇其餘語言時所需填寫的參數會略有不一樣。
若是選擇了對外提供服務的話,會進入第三步,第三步是填寫路由規則,如沒有特殊需求直接默認提交就好了。
Build 升級應用版本:
調用服務模式,能夠在普通跟服務網格之間調整。
服務是否提供對外服務的能力:
擴容調整CPU、內存:
調整啓動的Pod數量:
網頁版本的終端:
管理員建立StorageClass跟PersistentVolumeClaim,用戶只須要在本身服務選擇相關的PVC進行綁寫就好了。
存儲使用的是NFS。
Consul看成配置中心來使用,而且咱們提供Golang的客戶端。
$ go get github.com/lattecake/consul-kv-client
它會自動同步consul的目錄配置存在內存,獲取配置只須要直接從內存拿就好了。
做者:王聰首發:宜技之長