應(yīng)用開發(fā)的先鋒:容器和Kubernetes的故事
本文介紹了容器和Kubernetes的底層概念,以及它們?nèi)绾谓o應(yīng)用開發(fā)提供了新的模式。
容器就是新的進程
讓我們從計算機開聊。 當計算機啟動時,它會運行一個叫init的程序,然后init會啟動其他所需的程序:服務(wù)器、終端、窗口管理器等。 Init能做幾件有趣的事情, 例如讓一個程序開機啟動, 隔一段時間運行一個程序, 還有確保一個程序沒有失敗或者crash,如果有就重啟它。 正在運行的程序可以看到這臺機器上的所有東西: 其它在運行的程序,所有的文件,以及網(wǎng)絡(luò)。
多個進程同時跑在一臺計算機上。所有的進程可以自由的互相之間交互,或者與常規(guī)的資源交互。
通過將進程進行劃分, 程序員可以有一個更加簡單的模型來方便理解, 所以創(chuàng)建命名空間(namespace)的工具也被開發(fā)出來了。 程序或者進程只能看到運行在同一個命名空間下的其他進程。 如果它們尋找文件,那么只能看見硬盤上分配到這個命名空間的那一部分。 從安全的角度而言,一個命名空間里面的某個進程被黑掉了影響的僅僅也只是這個命名空間而已。
類似于Docker和Rkt這樣的工具被開發(fā)出來以后使得我們能系統(tǒng)化地使用這些特性。 這些工具提供了打包的功能,將一個命名空間打包成一個容器,使得我們可以很方便的將它搬到另一臺機器上運行,不出意外的它會跟之前完全一致的方式繼續(xù)運行,因為它本身的隔離特性。 事實上,通常可以很容易的將容器想象為可以完全獨立的運行的小計算機. 因為這些新的工具非常易用,它們漸漸成為一種流行的構(gòu)建軟件方式。
容器就是新的進程。
容器中的進程。 在這里,一個進程僅僅能夠與所在同一個容器里面的其他進程和資源交互。
擴展: 一個好“難題”
一臺計算機的資源是有限的,而且同時僅能處理有限的數(shù)據(jù)和運行有限的進程。 當面臨增長的負載時(比如更多用戶,更大的數(shù)據(jù)集)一個簡單的應(yīng)對方式是垂直擴展,也即是增加更多的處理能力和內(nèi)存給到這臺計算機,但是很快這個代價就會非常昂貴,而且本身擴展的空間也相當有限。 另一種方式就是通過增加更多的計算機來水平擴展。 這些計算機一起就組成了集群。
為了能跑在集群上,應(yīng)用也需要以不同的方式架構(gòu)。 例如,如果我們確認同一個程序的兩份拷貝可以不需要訪問對方的數(shù)據(jù)就能運行,那么我們就能放心的將它的多份拷貝放到不同的計算機上運行。
水平擴展:在這里集群里,三臺計算機每臺運行兩個容器。 一共有兩個app server的實例來處理大的負載。
雖然容器本身并沒有給我們?nèi)魏纹渌墓ぞ邅順?gòu)建分布式應(yīng)用,但是考慮一下這個級別上的抽象能讓構(gòu)建集群的應(yīng)用方便一些。容器模型所鼓勵的假設(shè)情形是:
- 可以有多份拷貝同時運行(架構(gòu)要考慮并發(fā)性)。
- 容器可以在集群中的任意一臺機器上動態(tài)啟動和停止(***是無狀態(tài)或者臨時的),而且
- 計算機或者進程可能會在任意的時間點失敗或者不可用但是整個系統(tǒng)仍然保持工作(架構(gòu)要考慮失敗和恢復)。
由于在集群里面有這么多的計算機要管理,我們面臨一些額外挑戰(zhàn):
- 首先,我們需要管理計算機上的資源,比如處理能力和存儲。這意味著我們不得不有效地分發(fā)和調(diào)度進程到不同的計算機上去執(zhí)行。
- 我們也需要“親和性”和方法將相關(guān)的進程放在一起跑,以便高效利用共享存儲;而同時“反親和性”的要求又需要保證對同一個資源有競爭性的進程不能運行在同一臺機器上。例如,如果我們想要將應(yīng)用服務(wù)器的進程跑兩份來服務(wù)兩倍的請求,我們可能希望他們跑在集群里兩臺不同的服務(wù)器上。
- 當許多的進程跑在不同的地方時,我們需要一種方式讓他們互相發(fā)現(xiàn)和溝通。我們只需要某個進程運行所在的機器ip就可以與這個進程通信。
在只有一臺計算機的時候,只有一個ip地址就可以了。 在有多個計算機之后,我們需要維護一個進程到ip的映射,例如像etcd這樣的分布式數(shù)據(jù)庫。 當一個進程在一臺機器上啟動時,這個信息就被加入到數(shù)據(jù)庫中。 如果進程掛掉或者機器宕機,也需要將這個條目從數(shù)據(jù)庫中刪除。
程序員對于開發(fā)跑在一臺計算機上的應(yīng)用很得心應(yīng)手了。 理想狀態(tài)下,我們想要的是有一個工具能將集群里面所有的計算機管理起來,而展現(xiàn)給程序員的就像一臺“巨型”的計算機。
這個方向上的一個進展是CoreOS的Fleet項目,它的基本思想就是像一臺計算機上的init進程那樣延伸做整個集群的init。
Google 貢獻的Kubernetes項目則讓我們更加接近我們想要一臺”巨型”計算機的模型。
Kubernetes:pod就是新的計算機
Kubernetes做的***件事情就是拿走你的所有計算機,然后還回給你一個”巨型”計算機--一個Kubernetes的集群。
一個Kubernetes的pod指定一組需要運行Docker或者rkt容器。
之前我們描述的是一個集群里面不同計算機上跑著不同進程,現(xiàn)在我們看到的是Kubernetes集群里面的不同pod里跑著不同進程。
一個Kubernetes集群圍繞著pod也就是容器組構(gòu)建了一個模型. 這些pod基于資源和”親和度”的約束被動態(tài)分配到底層節(jié)點上。
之前,我們考慮的是什么進程需要在一臺機器上一起運行。 現(xiàn)在,我們考慮將哪些進程組構(gòu)造成什么pod;pod已經(jīng)成為一種優(yōu)美的方式來對一個應(yīng)用的一個功能單元構(gòu)造模型。我們甚至可以直接使用社區(qū)構(gòu)造的pod,直接將他們跑起來,例如日志和監(jiān)控。
一個pod里面的所有進程跑在同一臺機器上,這樣解決了類似掛載磁盤這樣的資源共享的問題。 背后是Kubernetes將pod分配到不同的計算節(jié)點也就是kubernetes node上,我們可以給pod或者node設(shè)置發(fā)生的條件例如資源約束、親和性等。
計算機就是資源的集合:計算能力、內(nèi)存、磁盤和網(wǎng)絡(luò)接口。與之類似,一個pod可以從底層的資源池中分配一定量的資源. 它也會有自己的網(wǎng)卡和pod所在的虛擬網(wǎng)絡(luò)的ip。
所以,pod就是新的計算機。
如果我們需要某個特定功能進行擴展,我們只需要在集群中多跑幾個這個pod的拷貝。 當硬件不足,我們就往集群里面增加更多的計算和存儲。 通過將資源與它所承載的功能解耦,調(diào)度器可以保證所有的可用資源會被盡可能高效利用。
Kubernetes復制控制器用來保證任意時間某個pod的一定數(shù)量的拷貝在運行。 就像一個分布式的init,如果一個pod掛了: 起因可能是里面的一個進程失敗了,或者pod 的依賴掛了,或者它所在的節(jié)點down了; kubernetes會探測到并在另一個可用的節(jié)點上啟動一個新的拷貝。
一個Kubernetes的service會跟蹤集群里某種特定type的pod的所有實例。 例如,我們有一個ap server service,它會跟蹤cluster里面所有的app server的pod。service是一個非常簡便的抽象;我們的應(yīng)用可以非常快的找到某種類型服務(wù)的所有功能單元然后將工作分發(fā)給他們。
一個完整的Kubernetes集群圖
Pod被動態(tài)分配到節(jié)點上。 每一種pod對應(yīng)的服務(wù)都有服務(wù)發(fā)現(xiàn)和負載均衡,同時也描繪了pod和服務(wù)的虛擬網(wǎng)絡(luò)。
Kubernetes既是一個在集群里面管理和調(diào)度進程的框架,也是一種構(gòu)建應(yīng)用的新的思維模型,基于的是pod里面的進程分組和service所提供的服務(wù)發(fā)現(xiàn)。
整個生態(tài)以及未來發(fā)展
管理一臺計算機已經(jīng)是一個難題了。 管理一大群互相通訊的機器更是復雜得多. 感謝發(fā)明了像Docker、Kubernetes這樣非凡工具的好心人,我們現(xiàn)在有了容器這樣的簡單模型,也有工具將集群管理起來就像一臺計算機。 構(gòu)建可擴展的應(yīng)用也從沒像現(xiàn)在這樣如此簡單。
容器和集群管理軟件業(yè)也影響了人們構(gòu)建應(yīng)用的方式。 他們創(chuàng)造了新的模式和抽象,很多的可能性仍在探索中, 例如, 使用容器來構(gòu)建可重用的應(yīng)用組件或者庫可能也會很有意思。 在Hasura,我們正為數(shù)據(jù)庫、搜索、用戶管理、文件管理等等創(chuàng)建組件,構(gòu)建應(yīng)用就只需將它們快速組裝起來。
總的來說,在追求創(chuàng)造更簡模型的道路上我們已經(jīng)前進了一大步。 當今的所有軟件本質(zhì)就是運行代碼,執(zhí)行功能。 從這個角度,我們做的所有的事情僅僅是管理這些功能:將它們分組,運行它們的多份拷貝,找到并與它們交互,然后處理失敗的情況。 由此推出一個邏輯結(jié)論, 或許某一天我們會有這樣一個系統(tǒng),我們只需要描述我們需要的功能,余下的交給系統(tǒng)按照描述完成即可。 那確實是求之不得啊!
Akshaya Acharya
Akshaya領(lǐng)導著Hasuar的平臺工程團隊。 他曾經(jīng)在Intellectual Ventures的一個咨詢團隊與敏捷開發(fā)團隊一起工作過,也曾經(jīng)作為Tech mentor在MEST、Ghana工作過。