最近在反思,爲何在支撐容器平臺和微服務的競爭中,Kubernetes會取得最終的勝出。由於在不少角度來說三大容器平臺從功能角度來講,最後簡直是一摸同樣,具體的比較能夠參考本人前面的兩篇文章。算法
《Docker, Kubernetes, DCOS 不談信仰談技術》
《容器平臺選型的十大模式:Docker、DC/OS、K8S誰與當先?》數據庫
通過一段時間的思索,並採訪了從早期就開始實踐Kubernetes的網易雲架構師們,從而有了今天的分享。後端
一切都從企業上雲的三大架構開始。緩存
如圖所示,企業上的三大架構爲IT架構,應用架構和數據架構,在不一樣的公司,不一樣的人,不一樣的角色,關注的重點不一樣。網絡
對於大部分的企業來說,上雲的訴求是從IT部門發起的,發起人每每是運維部門,他們關注計算,網絡,存儲,試圖經過雲計算服務來減輕CAPEX和OPEX。架構
有的公司有ToC的業務,於是累積了大量的用戶數據,公司的運營須要經過這部分數據進行大數據分析和數字化運營,於是在這些企業裏面每每還須要關注數據架構。併發
從事互聯網應用的企業,每每首先關注的是應用架構,是否可以知足終端客戶的需求,帶給客戶良好的用戶體驗,業務量每每會在短時間內出現爆炸式的增加,於是關注高併發應用架構,並但願這個架構能夠快速迭代,從而搶佔風口。負載均衡
在容器出現以前,這三種架構每每經過虛擬機雲平臺的方式解決。
當容器出現以後,容器的各類良好的特性讓人眼前一亮,他的輕量級、封裝、標準、易遷移、易交付的特性,使得容器技術迅速被普遍使用。less
然而一千我的心中有一千個哈姆雷特,因爲原來工做的關係,三類角色分別從自身的角度看到了容器的優點給本身帶來的便捷。運維
對於原來在機房裏面管計算、網絡、存儲的IT運維工程師來說,容器更像是一種輕量級的運維模式,在他們看來,容器和虛擬機的最大的區別就是輕量級,啓動速度快,他們每每引覺得豪的推出虛擬機模式的容器。
對於數據架構來說,他們天天都在執行各類各樣的數據計算任務,容器相對於原來的JVM,是一種隔離性較好,資源利用率高的任務執行模式。
從應用架構的角度出發,容器是微服務的交付形式,容器不只僅是作部署的,而是作交付的,CI/CD中的D的。
因此這三種視角的人,在使用容器和選擇容器平臺時方法會不同。
從IT運維工程師的角度來看:容器主要是輕量級、啓動快。並且自動重啓,自動關聯。彈性伸縮的技術,使得IT運維工程師彷佛不用再加班。
Swarm的設計顯然更加符合傳統IT工程師的管理模式。
他們但願可以清晰地看到容器在不一樣機器的分佈和狀態,能夠根據須要很方便地SSH到一個容器裏面去查看狀況。
容器最好可以原地重啓,而非隨機調度一個新的容器,這樣原來在容器裏面安裝的一切都是有的。
能夠很方便的將某個運行的容器打一個鏡像,而非從Dockerfile開始,這樣之後啓動就能夠複用在這個容器裏面手動作的100項工做。
容器平臺的集成性要好,用這個平臺原本是爲了簡化運維的,若是容器平臺自己就很複雜,像Kubernetes這種自己就這麼多進程,還須要考慮它的高可用和運維成本,這個不划算,一點都沒有比原來省事,並且成本還提升了。
最好薄薄得一層,像一個雲管理平臺同樣,只不過更加方便作跨雲管理,畢竟容器鏡像很容易跨雲遷移。
Swarm的使用方式比較讓IT工程師以熟悉的味道,其實OpenStack所作的事情它都能作,速度還快。
然而容器做爲輕量級虛擬機,暴露出去給客戶使用,不管是外部客戶,仍是公司內的開發,而非IT人員本身使用的時候,他們覺得和虛擬機同樣,可是發現了不同的部分,就會不少的抱怨。
例如自修復功能,重啓以後,原來SSH進去手動安裝的軟件不見了,甚至放在硬盤上的文件也不見了,並且應用沒有放在Entrypoint裏面自動啓動,自修復以後進程沒有跑起來,還須要手動進去啓動進程,客戶會抱怨你這個自修復功能有啥用?
例若有的用戶會ps一下,發現有個進程他不認識,因而直接kill掉了,結果是Entrypoint的進程,整個容器直接就掛了,客戶抱怨大家的容器太不穩定,總是掛。
容器自動調度的時候,IP是不保持的,因此每每重啓原來的IP就沒了,不少用戶會提需求,這個能不能保持啊,原來配置文件裏面都配置的這個IP的,掛了重啓就變了,這個怎麼用啊,還不如用虛擬機,至少沒那麼容易掛。
容器的系統盤,也即操做系統的那個盤每每大小是固定的,雖然前期能夠配置,後期很難改變,並且沒辦法每一個用戶能夠選擇系統盤的大小。有的用戶會抱怨,咱們原來原本就不少東西直接放在系統盤的,這個都不能調整,叫什麼雲計算的彈性啊。
若是給客戶說容器掛載數據盤,容器都啓動起來了,有的客戶想像雲主機同樣,再掛載一個盤,容器比較難作到,也會被客戶罵。
若是容器的使用者不知道他們在用容器,當虛擬機來用,他們會以爲很難用,這個平臺一點都很差。
Swarm上手雖然相對比較容易,可是當出現問題的時候,做爲運維容器平臺的人,會發現問題比較難解決。
Swarm內置的功能太多,都耦合在了一塊兒,一旦出現錯誤,不容易debug。若是當前的功能不能知足需求,很難定製化。不少功能都是耦合在Manager裏面的,對Manager的操做和重啓影響面太大。
從大數據平臺運維的角度來說,如何更快的調度大數據處理任務,在有限的時間和空間裏面,更快的跑更多的任務,是一個很是重要的要素。
因此當咱們評估大數據平臺牛不牛的時候,每每以單位時間內跑的任務數目以及可以處理的數據量來衡量。
從數據運維的角度來說,Mesos是一個很好的調度器,既然可以跑任務,也就可以跑容器,Spark和Mesos自然的集成,有了容器以後,能夠用更加細粒度的任務執行方式。
在沒有細粒度的任務調度以前,任務的執行過程是這樣的。任務的執行須要Master的節點來管理整個任務的執行過程,須要Worker節點來執行一個個子任務。在整個總任務的一開始,就分配好Master和全部的Work所佔用的資源,將環境配置好,等在那裏執行子任務,沒有子任務執行的時候,這個環境的資源都是預留在那裏的,顯然不是每一個Work老是所有跑滿的,存在不少的資源浪費。
在細粒度的模式下,在整個總任務開始的時候,只會爲Master分配好資源,不給Worker分配任何的資源,當須要執行一個子任務的時候,Master才臨時向Mesos申請資源,環境沒有準備好怎麼辦?好在有Docker,啓動一個Docker,環境就都有了,在裏面跑子任務。在沒有任務的時候,全部的節點上的資源都是可被其餘任務使用的,大大提高了資源利用效率。
這是Mesos的最大的優點,在Mesos的論文中,最重要闡述的就是資源利用率的提高,而Mesos的雙層調度算法是核心。
原來大數據運維工程師出身的,會比較容易選擇Mesos做爲容器管理平臺。只不過原來是跑短任務,加上marathon就能跑長任務。可是後來Spark將細粒度的模式deprecated掉了,由於效率仍是比較差。
調度在大數據領域是核心中的核心,在容器平臺中是重要的,可是不是所有。因此容器還須要編排,須要各類外圍組件,讓容器跑起來運行長任務,而且相互訪問。Marathon只是萬里長征的第一步。
因此早期用Marathon + Mesos的廠商,可能是裸用Marathon和Mesos的,因爲周邊不全,於是要作各類的封裝,各家不一樣。你們有興趣能夠到社區上去看裸用Marathon和Mesos的廠商,各有各的負載均衡方案,各有各的服務發現方案。
因此後來有了DCOS,也就是在Marathon和Mesos以外,加了大量的周邊組件,補充一個容器平臺應有的功能,可是很惋惜,不少廠商都本身定製過了,仍是裸用Marathon和Mesos的比較多。
並且Mesos雖然調度牛,可是隻解決一部分調度,另外一部分靠用戶本身寫framework以及裏面的調度,有時候還須要開發Executor,這個開發起來仍是很複雜的,學習成本也比較高。
雖而後來的DCOS功能也比較全了,可是感受沒有如Kubernetes同樣使用統一的語言,而是採起大雜燴的方式。在DCOS的整個生態中,Marathon是Scala寫的,Mesos是C++寫的,Admin Router是Nginx+lua,Mesos-DNS是Go,Marathon-lb是Python,Minuteman是Erlang,這樣太複雜了吧,林林總總,出現了Bug的話,比較難本身修復。
而Kubernetes不一樣,初看Kubernetes的人以爲他是個奇葩所在,容器還沒建立出來,概念先來一大堆,文檔先讀一大把,編排文件也複雜,組件也多,讓不少人望而卻步。我就想建立一個容器玩玩,怎麼這麼多的前置條件。若是你將Kubernetes的概念放在界面上,讓客戶去建立容器,必定會被客戶罵。
在開發人員角度,使用Kubernetes絕對不是像使用虛擬機同樣,開發除了寫代碼,作構建,作測試,還須要知道本身的應用是跑在容器上的,而不是當甩手掌櫃。開發人員須要知道,容器是和原來的部署方式不同的存在,你須要區分有狀態和無狀態,容器掛了起來,就會按照鏡像還原了。開發人員須要寫Dockerfile,須要關心環境的交付,須要瞭解太多原來不瞭解的東西。實話實說,一點都不方便。
在運維人員角度,使用Kubernetes也絕對不是像運維虛擬機同樣,我交付出來了環境,應用之間互相怎麼調用,我才無論,我就管網絡通不通。在運維眼中作了過多他不應關心的事情,例如服務的發現,配置中心,熔斷降級,這都應該是代碼層面關心的事情,應該是SpringCloud和Dubbo關心的事情,爲何要到容器平臺層來關心這個。
容器,倒是Dev和Ops融合的一個橋樑。
Docker是微服務的交付工具,微服務以後,服務太多了,單靠運維根本管不過來,並且很容易出錯,這就須要研發開始關心環境交付這件事情。例如配置改了什麼,建立了哪些目錄,如何配置權限,只有開發最清楚,這些信息一方面很難經過文檔的方式,又及時又準確的同步到運維部門來,就算是同步過來了,運維部門的維護量也很是的大。
因此,有了容器,最大的改變是環境交付的提早,是每一個開發多花5%的時間,去換取運維200%的勞動,而且提升穩定性。
而另外一方面,原本運維只管交付資源,給你個虛擬機,虛擬機裏面的應用如何相互訪問我無論,大家愛咋地咋地,有了Kubernetes之後,運維層要關注服務發現,配置中心,熔斷降級。
二者融合在了一塊兒。
在微服務化的研發的角度來說,Kubernetes雖然複雜,可是設計的都是有道理的,符合微服務的思想。
微服務有哪些要點呢?第一張圖是SpringCloud的整個生態。
第二張圖是微服務的12要素以及在網易雲的實踐。
第三張圖是構建一個高併發的微服務,須要考慮的全部的點。
接下來細說微服務的設計要點。
在實施微服務的過程當中,難免要面臨服務的聚合與拆分,當後端服務的拆分相對比較頻繁的時候,做爲手機App來說,每每須要一個統一的入口,將不一樣的請求路由到不一樣的服務,不管後面如何拆分與聚合,對於手機端來說都是透明的。
有了API網關之後,簡單的數據聚合能夠在網關層完成,這樣就不用在手機App端完成,從而手機App耗電量較小,用戶體驗較好。
有了統一的API網關,還能夠進行統一的認證和鑑權,儘管服務之間的相互調用比較複雜,接口也會比較多,API網關每每只暴露必須的對外接口,而且對接口進行統一的認證和鑑權,使得內部的服務相互訪問的時候,不用再進行認證和鑑權,效率會比較高。
有了統一的API網關,能夠在這一層設定必定的策略,進行A/B測試,藍綠髮布,預發環境導流等等。API網關每每是無狀態的,能夠橫向擴展,從而不會成爲性能瓶頸。
影響應用遷移和橫向擴展的重要因素就是應用的狀態,無狀態服務,是要把這個狀態往外移,將Session數據,文件數據,結構化數據保存在後端統一的存儲中,從而應用僅僅包含商務邏輯。
狀態是不可避免的,例如ZooKeeper, DB,Cache等,把這些全部有狀態的東西收斂在一個很是集中的集羣裏面。
整個業務就分兩部分,一個是無狀態的部分,一個是有狀態的部分。
無狀態的部分能實現兩點,一是跨機房隨意地部署,也即遷移性,一是彈性伸縮,很容易的進行擴容。
有狀態的部分,如DB,Cache,ZooKeeper有本身的高可用機制,要利用到他們本身的高可用的機制來實現這個狀態的集羣。
雖然說無狀態化,可是當前處理的數據,仍是會在內存裏面的,當前的進程掛掉數據,確定也是有一部分丟失的,爲了實現這一點,服務要有重試的機制,接口要有冪等的機制,經過服務發現機制,從新調用一次後端的服務的另外一個實例就能夠了。
數據庫是保存狀態,最重要的也是最容易出現瓶頸的。有了分佈式數據庫可使得數據庫的性能能夠隨着節點的增長線性的增長。
分佈式數據庫最最下面是RDS,是主備的,經過MySql的內核開發能力,咱們可以實現主備切換數據零丟失,因此數據落在這個RDS裏面,是很是放心的,哪怕是掛了一個節點,切換完了之後,你的數據也是不會丟的。
再往上就是橫向怎麼承載大的吞吐量的問題,上面有一個的負載均衡NLB,用LVS,HAProxy, Keepalived,下面接了一層Query Server。Query Server是能夠根據監控的數據進行橫向的擴展的,若是出現了故障,能夠隨時進行替換的修復的,對於業務層是沒有任何感知的。
另一個就是雙機房的部署,DDB這面開發了一個數據運河NDC的組件,可使得不一樣的DDB之間在不一樣的機房裏面進行同步,這時候不但在一個數據中內心面是分佈式的,在多個數據中內心面也會有一個相似雙活的一個備份,高可用性有很是好的保證。
在高併發場景下緩存是很是重要的。要有層次的緩存,使得數據儘可能靠近用戶。數據越靠近用戶能承載的併發量也越大,響應時間越小。
在手機客戶端App上就應該有一層緩存,不是全部的數據都每時每刻都從後端拿,而是隻拿重要的,關鍵的,時常變化的數據。
尤爲是對於靜態數據,能夠過一段時間去取一次,並且也不必到數據中心去取,能夠經過CDN,將數據緩存在距離客戶端最近的節點上,進行就近的下載。
有的時候CDN裏面沒有,仍是要回到數據中心去下載,稱爲回源,在數據中心的最外層,咱們稱爲接入層,能夠設置一層緩存,將大部分的請求攔截,從而不會對後臺的數據庫形成壓力。
若是是動態數據,仍是須要訪問應用,經過應用中的商務邏輯生成,或者去數據庫中讀取,爲了減輕數據庫的壓力,應用可使用本地的緩存,也可使用分佈式緩存,如Memcached或者Redis,使得大部分的請求讀取緩存便可,沒必要訪問數據庫。
固然動態數據還能夠作必定的靜態化,也即降級成靜態數據,從而減小後端的壓力。
當系統扛不住,應用變化快的時候,每每要考慮將比較大的服務拆分爲一系列小的服務。
這樣首先的好處就是開發比較獨立,當很是多的人在維護同一個代碼倉庫的時候,每每對代碼的修改就會相互影響,經常會出現,我沒改什麼測試就不經過了,並且代碼提交的時候,常常會出現衝突,須要進行代碼合併,大大下降了開發的效率。
另一個好處就是上線獨立,物流模塊對接了一家新的快遞公司,須要連同下單一塊兒上線,這是很是不合理的行爲,我沒改還要我重啓,我沒改還讓我發佈,我沒改還要我開會,都是應該拆分的時機。
另外再就是高併發時段的擴容,每每只有最關鍵的下單和支付流程是核心,只要將關鍵的交易鏈路進行擴容便可,若是這時候附帶不少其餘的服務,擴容即便不經濟的,也是頗有風險的。
再就是容災和降級,在大促的時候,可能須要犧牲一部分的邊角功能,可是若是全部的代碼耦合在一塊兒,很難將邊角的部分功能進行降級。
固然拆分完畢之後,應用之間的關係就更加複雜了,於是須要服務發現的機制,來管理應用相互的關係,實現自動的修復,自動的關聯,自動的負載均衡,自動的容錯切換。
當服務拆分了,進程就會很是的多,於是須要服務編排,來管理服務之間的依賴關係,以及將服務的部署代碼化,也就是咱們常說的基礎設施即代碼。這樣對於服務的發佈,更新,回滾,擴容,縮容,均可以經過修改編排文件來實現,從而增長了可追溯性,易管理性,和自動化的能力。
既然編排文件也能夠用代碼倉庫進行管理,就能夠實現一百個服務中,更新其中五個服務,只要修改編排文件中的五個服務的配置就能夠,當編排文件提交的時候,代碼倉庫自動觸發自動部署升級腳本,從而更新線上的環境,當發現新的環境有問題的時候,固然但願將這五個服務原子性的回滾,若是沒有編排文件,須要人工記錄此次升級了哪五個服務。有了編排文件,只要在代碼倉庫裏面revert,就回滾到上一個版本了。全部的操做在代碼倉庫裏面都是能夠看到的。
服務拆分之後,服務的數量很是的多,若是全部的配置都以配置文件的方式,放在應用本地的話,很是難以管理,能夠想象當有幾百上千個進程中,有一個配置出現了問題,你很難將它找出來,於是須要有統一的配置中心,來管理全部的配置,進行統一的配置下發。
在微服務中,配置每每分爲幾類,一類是幾乎不變的配置,這種配置能夠直接打在容器鏡像裏面,第二類是啓動時就會肯定的配置,這種配置每每經過環境變量,在容器啓動的時候傳進去,第三類就是統一的配置,須要經過配置中心進行下發,例如在大促的狀況下,有些功能須要降級,哪些功能能夠降級,哪些功能不能降級,均可以在配置文件中統一的配置。
一樣是進程數目很是多的時候,很難對成千上百個容器,一個一個登陸進去查看日誌,因此須要統一的日誌中心來收集日誌,爲了使收集到的日誌容易分析,對於日誌的規範,須要有必定的要求,當全部的服務都遵照統一的日誌規範的時候,在日誌中心就能夠對一個交易流程進行統一的追溯。例如在最後的日誌搜索引擎中,搜索交易號,就可以看到在哪一個過程出現了錯誤或者異常。
服務要有熔斷,限流,降級的能力,當一個服務調用另一個服務,出現超時的時候,應及時的返回,而非阻塞在那個地方,從而影響其餘用戶的交易,能夠返回默認的託底數據。
當一個服務發現被調用的服務,由於過於繁忙,線程池滿,鏈接池滿,或者老是出錯,則應該及時熔斷,防止由於下一個服務的錯誤或繁忙,致使本服務的不正常,從而逐漸往前傳導,致使整個應用的雪崩。
當發現整個系統的確負載太高的時候,能夠選擇降級某些功能或某些調用,保證最重要的交易流程的經過,以及最重要的資源所有用於保證最核心的流程。
還有一種手段就是限流,當既設置了熔斷策略,也設置了降級策略,經過全鏈路的壓力測試,應該可以知道整個系統的支撐能力,於是就須要制定限流策略,保證系統在測試過的支撐能力範圍內進行服務,超出支撐能力範圍的,可拒絕服務。當你下單的時候,系統彈出對話框說「系統忙,請重試」,並不表明系統掛了,而是說明系統是正常工做的,只不過限流策略起到了做用。
當系統很是複雜的時候,要有統一的監控,主要兩個方面,一個是是否健康,一個是性能瓶頸在哪裏。當系統出現異常的時候,監控系統能夠配合告警系統,及時的發現,通知,干預,從而保障系統的順利運行。
當壓力測試的時候,每每會遭遇瓶頸,也須要有全方位的監控來找出瓶頸點,同時可以保留現場,從而能夠追溯和分析,進行全方位的優化。
基於上面這十個設計要點,咱們再回來看Kubernetes,會發現越看越順眼。
首先Kubernetes自己就是微服務的架構,雖然看起來複雜,可是容易定製化,容易橫向擴展。
如圖黑色的部分是Kubernetes原生的部分,而藍色的部分是網易雲爲了支撐大規模高併發應用而定製化的部分。
Kubernetes的API Server更像網關,提供統一的鑑權和訪問接口。
衆所周知,Kubernetes的租戶管理相對比較弱,尤爲是對於公有云場景,複雜的租戶關係的管理,咱們只要定製化API Server,對接Keystone,就能夠管理複雜的租戶關係,而不用管其餘的組件。
在Kubernetes中幾乎全部的組件都是無狀態化的,狀態都保存在統一的etcd裏面,這使得擴展性很是好,組件之間異步完成本身的任務,將結果放在etcd裏面,互相不耦合。
例如圖中pod的建立過程,客戶端的建立僅僅是在etcd中生成一個記錄,而其餘的組件監聽到這個事件後,也相應異步的作本身的事情,並將處理的結果一樣放在etcd中,一樣並非哪個組件遠程調用kubelet,命令他進行容器的建立,而是發現etcd中,pod被綁定到了本身這裏,方纔拉起。
爲了在公有云中實現租戶的隔離性,咱們的策略是不一樣的租戶,不共享節點,這就須要Kubernetes對於IaaS層有所感知,於是須要實現本身的Controller,Kubernetes的設計使得咱們能夠獨立建立本身的Controller,而不是直接改代碼。
API-Server做爲接入層,是有本身的緩存機制的,防止全部的請求的壓力直接到後端的數據庫上。可是當仍然沒法承載高併發請求的時候,瓶頸依然在後端的etcd存儲上,這和電商應用一摸同樣。固然可以想到的方式也是對etcd進行分庫分表,不一樣的租戶保存在不一樣的etcd集羣中。
有了API Server作API網關,後端的服務進行定製化,對於client和kubelet是透明的。
如圖是定製化的容器建立流程,因爲大促和非大促期間,節點的數目相差比較大,於是不能採用事先所有建立好節點的方式,這樣會形成資源的浪費,於是中間添加了網易雲本身的模塊Controller和IaaS的管理層,使得當建立容器資源不足的時候,動態調用IaaS的接口,動態的建立資源。這一切對於客戶端和kubelet無感知。
爲了解決超過3萬個節點的規模問題,網易雲須要對各個模塊進行優化,因爲每一個子模塊僅僅完成本身的功能,Scheduler只管調度,Proxy只管轉發,而非耦合在一塊兒,於是每一個組件均可以進行獨立的優化,這符合微服務中的獨立功能,獨立優化,互不影響。並且Kubernetes的全部組件的都是Go開發的,更加容易一些。因此Kubernetes上手慢,可是一旦須要定製化,會發現更加容易。
好了,說了K8S自己,接下來講說K8S的理念設計,爲何這麼適合微服務。
前面微服務設計的十大模式,其中一個就是區分無狀態和有狀態,在K8S中,無狀態對應deployment,有狀態對應StatefulSet。
deployment主要經過副本數,解決橫向擴展的問題。
而StatefulSet經過一致的網絡ID,一致的存儲,順序的升級,擴展,回滾等機制,能夠保證有狀態應用,很好地利用本身的高可用機制。由於大多數集羣的高可用機制,都是能夠容忍一個節點暫時掛掉的,可是不能容忍大多數節點同時掛掉。並且高可用機制雖然能夠保證一個節點掛掉後回來,有必定的修復機制,可是須要知道剛纔掛掉的究竟是哪一個節點,StatefulSet的機制可讓容器裏面的腳本有足夠的信息,處理這些狀況,實現哪怕是有狀態,也能儘快修復。
在微服務中,比較推薦使用雲平臺的PaaS,例如數據庫,消息總線,緩存等。可是配置也是很是複雜的,由於不一樣的環境須要鏈接不一樣的PaaS服務。
K8S裏面的headless service是能夠很好的解決這個問題的,只要給外部的服務建立一個headless service,指向相應的PaaS服務,而且將服務名配置到應用中。因爲生產和測試環境分紅Namespace,雖然配置了相同的服務名,可是不會錯誤訪問,簡化了配置。
微服務少不了服務發現,除了應用層可使用SpringCloud或者Dubbo進行服務發現,在容器平臺層固然是用Service了,能夠實現負載均衡,自修復,自動關聯。
服務編排,原本K8S就是編排的標準,能夠將yml文件放到代碼倉庫中進行管理,而經過deployment的副本數,能夠實現彈性伸縮。
對於配置中心,K8S提供了configMap,能夠在容器啓動的時候,將配置注入到環境變量或者Volume裏面。可是惟一的缺點是,注入到環境變量中的配置不能動態改變了,好在Volume裏面的能夠,只要容器中的進程有reload機制,就能夠實現配置的動態下發了。
統一日誌和監控每每須要在Node上部署Agent,來對日誌和指標進行收集,固然每一個Node上都有,daemonset的設計,使得更容易實現。
固然目前最最火的Service Mesh,能夠實現更加精細化的服務治理,進行熔斷,路由,降級等策略。Service Mesh的實現每每經過sidecar的方式,攔截服務的流量,進行治理。這也得力於Pod的理念,一個Pod能夠有多個容器,若是當初的設計沒有Pod,直接啓動的就是容器,會很是的不方便。
因此K8S的各類設計,看起來很是的冗餘和複雜,入門門檻比較高,可是一旦想實現真正的微服務,K8S是能夠給你各類可能的組合方式的。實踐過微服務的人,每每會對這一點深有體會。
下面咱們來看一下,微服務化的不一樣階段,Kubernetes的使用方式。
也即沒有微服務化的階段,基本上一個進程就能搞定,兩個進程作高可用,不須要使用容器,虛擬機就很是好。
當微服務開始拆分了,如何保證拆分後功能的一致性,須要持續集成做爲保證,如前面的論述,容器是很是好的持續集成工具,是解決CI/CD中D的,因此一開始用host網絡就能夠,這樣能夠保證部署方式和原來兼容。
若是想用私有云進行部署,直接部署在物理機上,在性能要求沒有很高,可是又要和其餘物理機很好的通訊的狀況下,能夠用bridge打平網絡的方式比較好。經過建立網橋,將物理網卡,容器網卡都鏈接到一個網橋上,能夠實現全部的容器和物理機在一樣的一個二層網絡裏面。
若是性能要求比較高,例如要部署相似緩存,則可使用sr-iov網卡。
若是想實現租戶的簡單隔離,則每每使用各類Overlay的網絡模式,這是最經常使用的部署方式。圖中的數據來自網絡。Flannel,Calico都是很是好的網絡插件,雖然Flannel一開始使用用戶態的模式性能很差,後來使用內核態,性能大大改善,使用gw模式後,和Calico性能至關。
網易雲採用了Kubernetes和IaaS深度融合的方式,相似AWS的Fargate的模式,一方面可使得原來使用虛擬機的用戶平滑地遷移到容器,另外一方面能夠實現公有云的租戶隔離。
如圖是融合的網易雲容器服務的架構,這個管理OpenStack和Kubernetes的管理平臺,也是用的微服務架構,有API網關,熔斷限流功能,拆分紅不一樣的服務,部署在K8S上的,因此到處是微服務。