然而相比起Kubernetes的熱度和知名度,這個被人們寄予厚望的工具在企業(yè)中成功落地的著名案例卻少的多了。尤其是在傳統(tǒng)的企業(yè)之中,不管是開發(fā)和運維都在反映Kubernetes有點難,不容易使用。為什么會這樣?
原因很簡單,Kubernetes不是設計來直接使用的。我們先來看看Google自己是怎么說的吧:
Kelsey Hightower 是谷歌云非常資深的布道師,可以說他的聲音也就代表了谷歌官方的思路,而這個思路對于Kubernetes的定位很明確:Kubernetes本身并不是一個直接可用的平臺,而是一個用來構建平臺的基礎。
也可以打個比方,如果我們把現(xiàn)代的云平臺看成是一個操作系統(tǒng)的話,那么Kubernetes只是這個操作系統(tǒng)的內核。從一個操作系統(tǒng)的內核到一個企業(yè)級操作系統(tǒng)還差多少東西?相信讀者們都應該很清楚。
所以,不管是開發(fā)還是運維,若想把“傳說中”Kubernetes的各種威力發(fā)揮出來,只是靠Kubectl而沒有其他合適的工具,那是非常困難的。例如,我們來看看以下幾個場景:
- 某公司A有幾個應用軟件開發(fā)商與其長期合作,目前都是通過容器鏡像的方式為該公司提供最新的軟件版本。但是由于歷史原因,各開發(fā)商提供的鏡像中的操作系統(tǒng),中間件或者軟件工具各不相同,經常出現(xiàn)因為安全或者合規(guī)問題無法部署到生產環(huán)境而引起項目交付延遲的情況;
- 某公司B基于某個版本的操作系統(tǒng)已經在生產環(huán)境中部署了幾百個容器,并且運行良好。最近該公司的IT部門得知該公司當前版本的操作系統(tǒng)發(fā)現(xiàn)了嚴重的安全漏洞,需要立即打上安全補丁,但是這些應用絕大多數(shù)是要求不間斷運行的,怎么辦?
- 某公司C為了提高生產效率,已經在內部建立起了CI/CD管道來自動化軟件的開發(fā)測試部署過程,并且一直在根據使用效果做持續(xù)改進。最近該公司發(fā)現(xiàn)一年前部署的一個軟件版本出現(xiàn)了bug需要修復,但是現(xiàn)在的CI/CD管道已經做了幾次修改,其中依賴的軟件版本都已經有了變化,已經無法重新構建出原來的軟件環(huán)境,只有重新手工操作或者重新配置CI/CD管道…
這些例子在日常工作中可能都非常常見,他們集中體現(xiàn)了在企業(yè)環(huán)境中使用Kubernetes的一個典型的難點:如何同時滿足開發(fā)團隊對于“高效率”和運維團隊對于“安全可控”的需求?
而這正是kpack所要解決的問題。
Kpack,其全名是Kubernetes Native Container Build Service,如其英文名所示,是一個Kubernetes原生的容器構建工具。Kpack具體能做什么事情?它又能為我們日常的開發(fā)和運維工作帶來哪些助益?下面容我為大家細細道來。
什么是Kpack?
Kpack是由原來的Pivotal,也就是現(xiàn)在的VMWare開源的軟件工具。簡單來講,kpack其實就是Kubernetes的一組擴展的資源定義(CRD),它通過聲明式的方式來配置一個符合OCI標準的容器鏡像,然后可以直接通過源代碼來自動化地構建這個鏡像并上傳到指定的鏡像倉庫。
廢話不多說,我們先通過一個動畫來看看Kpack是怎么使用的:
在動畫中,演示人員首先創(chuàng)建了一個容器鏡像的描述文件image.yaml,然后直接執(zhí)行kubectl apply -f image.yaml,我們可以看到容器鏡像就已經構建成功并且上傳到了鏡像倉庫中!
為了了解清楚整個過程都發(fā)生了什么事情,我們不妨把整個動畫一幀一幀地再重放一遍。
首先我們看一下演示人員使用的image.yaml都包含哪些內容:
在這個描述文件中,最關鍵的就是兩個配置項:tag和source。其中,“tag”指的就是生成的容器鏡像,而“source”則是軟件版本管理系統(tǒng)中源代碼的位置(url)和版本(revision)。這里假設版本管理用的是git。
當然,在執(zhí)行命令kubectl apply -f image.yaml之前,這個Kubernetes集群已經已經配置好了鏡像倉庫例如Harbor等,并且這里配置的serviceAccount可以訪問該鏡像倉庫。
然后我們再看看接下來的幾個命令在做什么。
- Kubectl get images: kpack會對每個構建出來的鏡像進行記錄,調用這個命令會列出當前所有kpack構建的鏡像。當然,如果想查看某個鏡像的詳細信息,可以調用命令kubectl describe image 。
- Kubectl get builds: 除了構建的容器鏡像以外,kpack也同樣會對每一次鏡像構建的build過程做記錄,用kubectl get builds就可以獲得過去所有構建鏡像的build操作。為了很明顯地看出每一次build具體對應于哪一個鏡像,build的名稱都是用鏡像的名字做開頭,后面加上隨機數(shù)字,就如上圖所顯示的那樣。同樣,用kubectl describe build也可以看到具體build的詳細信息。
- Logs -image=demo-image: 查看鏡像構建的日志。“logs”是kpack提供的一個日志工具,可以專門用來查看kpack打印出來的日志,可以用于鏡像構建的調試。
那么日志究竟打印出來了什么內容?如下可以看到日志開頭的一小部分:
沒錯,對PaaS產品有一定了解的讀者可能已經猜到了,kpack的核心,真正執(zhí)行容器構建操作的其實就是著名的Buildpacks,現(xiàn)在也是CNCF中最受關注的開源項目之一:Cloud Native Buildpacks。
為了讓大家對Buildpack和其工作機制有一些了解,這里有必要先來簡單介紹一下Buildpack和Cloud Native Buildpacks的關系。
BuildPacks和Cloud Native Buildpacks
Cloud Native Buildpacks是從早年Pivotal和Heroku提出的buildpack的概念演化而來。Buildpack的主要思路就是:在多數(shù)情況下,把軟件從源碼打包到容器鏡像的過程是一個重復性操作,因此應該完全是自動化的。
為了完全實現(xiàn)這個自動化過程,Buildpack里面包含了構建一個容器鏡像所需要的主要組件,如操作系統(tǒng),容器化的中間件,開源組件,主流編程語言的運行環(huán)境和通用服務等。例如,早期的Buildpacks支持的語言包括Java,Windows(托管Web Core)上的。NET,。NET Core,Node.js,Go,PHP,Python和Ruby等。
使用Buildpack方法,在部署應用程序時,Buildback程序將自動生成,容器化和運行應用程序所需的所有框架和運行時支持匯總在一起。它通過“讀取”代碼并下載運行它所需的依賴項來實現(xiàn)。比如說,如果發(fā)現(xiàn)push上來的文件當中包含了。jar文件,那么就選擇用Java Buildpacks來構建容器鏡像;如果包含了。php文件,那么則會用PHP Buildpack來構建容器鏡像,等等。除此之外, Buildpack還會配置該應用程序所需的網絡服務。
作為Buildpack的聯(lián)合發(fā)起者,自然Heroku和Pivotal都把Buildpack集成到了自己的PaaS平臺當中,例如Pivotal主導開發(fā)的開源PaaS平臺Cloud Foundry以及自己的商業(yè)產品Pivotal Application Service(Pivotal Cloud Foundry的2.0版本),就是依賴于Buildpacks打造了廣受企業(yè)開發(fā)者喜愛的應用一鍵部署的體驗“cf push”,如下所示:
cf push是Cloud Foundry的一個命令,開發(fā)人員通過這個命令,可以把自己編譯好的應用“扔到”PAS平臺上,然后PAS平臺就會為應用自動選擇合適的Buildpack,將應用封裝到容器里面,并自動完成以上列出的所有上線步驟(部署容器,加載環(huán)境變量,配置負載均衡,配置防火墻和安全策略,配置APM,配置日志等等)。
更重要的是,很多已經大規(guī)模用于生產環(huán)境的Buildpack是由一些公司定期維護和更新的。因此,開發(fā)和運維人員都不用擔心他們所使用的軟件和庫是否是最新和最安全的,因為它們已經內嵌到Buildpacks中了。這正像大型Buildpack支持者Pivotal也就是現(xiàn)在的VMware所說的那樣,“您不必考慮依賴庫,中間件或運行時組件,平臺可以為您完成。”
而在近年來隨著Kubernetes逐漸發(fā)展成為標準基礎設施的一部分,業(yè)界對于將Buildpacks用于Kubernetes平臺的呼聲越來越高。因此,Pivotal(VMWare)和Heroku又將Buildpacks在Kubernetes平臺之上做了適配和優(yōu)化,并且啟動了一個新的CNCF項目Cloud Native Buildpack(以下簡稱CNB)。相比之前的Buildpacks,CNB的能力又得到了進一步的提升:開發(fā)人員甚至都不用自己去編譯代碼了,CNB已經支持了源代碼在線編譯的能力,所以開發(fā)人員可以直接把應用的源代碼“扔”給CNB,CNB就可以自動對源碼進行編譯并打包成容器鏡像!
那么下面我們就對Kpack的引擎CNB做一下深入的分解,看看它究竟是如何工作的。
Cloud Native Buildpacks的工作原理
我們可以用多種方式來集成CNB,不過對于CNB來說,不管如何被集成,它的工作總是從接收到應用的源碼開始的。
我們還是看一下Kpack的場景。Kpack會從指定的url下載應用的源碼,然后將這些源碼交給CNB。在CNB接收到了源代碼之后,會通過如下四個步驟完成它自己的全部任務:
- Detection(檢測): 查找系統(tǒng)中可以用于應用構建的Buildpack,例如Java Buildpack, .Net Buildpack, Go Buildpacks等等,然后按照默認的順序逐個判斷哪個Buildpack可以用于當前代碼的構建;
- Analysis(分析): 確定具體的Buildpack之后,將Buildpack解包,找到那些可以用于優(yōu)化構建和導出階段的文件,以備稍后使用;
- Build(構建): 將應用程序源代碼轉換為可打包到容器中的可運行工件;
- Export(打包): 創(chuàng)建最終的符合OCI標準的容器鏡像。
注意,雖然Docker鏡像在日常工作中使用最多,但是CNB旨在支持所有符合OCI標準的鏡像格式。
那么我們還是看看剛才kpack打印出來的日志,就大概了解這四部分是怎么工作的了。
首先,從日志的第一行,我們看到Kpack將示例應用源代碼clone下來,然后交給了CNB。訪問一下這個應用所在的url,我們會發(fā)現(xiàn)這個應用是一個Node.js應用。
然后,CNB開始啟動第一步,檢測自己現(xiàn)有的Buildpack哪一個能夠支持這個代碼的構建。
1、檢測
為了便于Buildpack的管理,我們看CNB將Buildpack按照編程語言分成了不同的組,如果開發(fā)人員不指定具體的Buildpack,那么CNB就會把每個組都拿出來逐個與源碼進行匹配,下面的日志顯示了第一組所包含的Buildpack。
很明顯第一組里面包含的都是支持Java的buildpack,因為Java在企業(yè)應用中最為常見,所以在這里檢測時把這一組放在最前面。但是由于這個應用是node.js的,所以第一組不合適。(如果開發(fā)人員用Spring Boot去開發(fā)應用,從最新的2.3版本開始,其實還有更簡單的方法使用Java Buildpacks,后面我們會提到。)
第二組和第三組都有Node Engine Buildpack,不同的第二組的包管理用的是Yarn,而第三組用的是NPM。由于CNB在源碼當中發(fā)現(xiàn)了package.json而沒有yarn的關鍵文件yarn.lock,所以CNB判斷這個需要用NPM Buildpack來支持。所以,第三組的兩個buildpack全部檢測通過 ,第一個步驟完成,開始進行第二步的操作。
2、分析
在確定了Buildpack之后,可以看到日志里面有這樣一句:“Cache ‘/cache’: metadata not found, nothing to restore”。這是在分析Buildpack之前,kpack首先要先看看對于這個應用源代碼,系統(tǒng)內部有沒有緩存的直接可用的鏡像層的緩存。這個緩存機制非常重要,因為隨著應用的不斷迭代,每天都需要不斷地修改源碼并且進行測試,如果有這樣一個cache將之前已經構建好的鏡像層在內部進行緩存,那么在應用的首次構建之后,以后的構建就無需再一遍遍重新“拼接”出這個鏡像層,在完成第一步檢測之后直接使用cache中的鏡像層就可以了。
在本例中,因為是第一次構建,所以Kpack沒有發(fā)現(xiàn)cache中有已經構建過的鏡像層,所以就需要對鏡像的配置(主要基于image.yaml)進行分析,并依次調用兩個Buildpack進行鏡像的構建工作。
看到這里我們一定要說清楚一個很重要的問題:對每一個編程語言就用一個Buildpack不就行了嗎?這樣多方便,干嘛要分解成多個Buildpack來完成?
靈活性肯定是這個問題的答案之一,但是其實這里面還有另外一個更重要的因素,那就是這個平臺的可維護性。
我們可以回想一下文章開頭提到的B公司的例子。如果一家公司基于某個版本的操作系統(tǒng)已經部署了很多容器,而后來這個版本的操作系統(tǒng)出現(xiàn)嚴重的安全漏洞需要打安全補丁,那該怎么辦?把所有的這些應用的鏡像全部重新構建,測試,升級部署嗎?如果這樣的容器有幾百個甚至幾千個,這得需要多少工作量?!多長時間才能完成?只怕是還沒等完成,黑客就已經入侵系統(tǒng)了…
而在CNB里面,每一個Buildpack都被設計成可以構建為鏡像的一個layer,這樣當每一個buildpack中包含的軟件出現(xiàn)了新版本,需要打安全補丁,或者需要進行定制,我們只需要修改這個buildpack就好,正如下圖所示:
即便是對于已經用原來的Buildpack已經構建并已經運行的容器鏡像,也無需重新對原來的鏡像全部重新構建,因為CNB提供了rebase的功能,通過這個功能,CNB會檢查應用當前的基礎鏡像是不是有最新版本可用,如果有的話,可以將已經構建好的容器中的基礎鏡像直接替換掉。對于那些未來要開發(fā)運維幾百,幾千甚至幾萬容器的企業(yè)來說,這個功能不管是對于開發(fā)人員還是運維人員來說,無疑都是一個福音。
說清楚了這一點,我們也就很容易看懂例子中這兩個Buildpack在做什么了:
- Node Engine Buildpack會下載Node.js的運行時環(huán)境,并進行配置;
- NPM Buildpack會根據package.json中的內容,下載編譯運行本應用所需要的所有的依賴庫;
這兩部分分別構成了容器鏡像中的兩層。這樣構建容器鏡像的材料都已經齊備,可以開始build image了。
3、構建
對于Node.js來說,因為代碼不需要編譯就可以運行,所以這一步很簡單,只是需要把源代碼copy過來就可以了。
如果是其他需要編譯的語言比如說Java,這里可能就需要Maven或者Gradle的Buildpack(根據應用源代碼的配置)來對源碼進行編譯了。
4、打包
從日志當中我們可以看出,這個image構建成功,共由5個layer組成,分別是app,config,launcher,以及分別由兩個Buildpack所構建的node engine和node modules。
這里特別需要注意的是日志打印出的最后一行:“Caching layer …”。正如之前提到的,在這次構建完成之后,node engine這一層的layer將會被緩存在系統(tǒng)中,這樣以后再重新構建該應用的鏡像的時候,就無須再重新下載node.js的運行時并構建這層layer了。
至此,鏡像已經構建完成。我們也已經了解了CNB是如何通過一系列自動化的操作將應用的源代碼直接構建成容器鏡像的。事實上,Buildpack的技術體系經過近10年的不斷發(fā)展和優(yōu)化到今天,已經兼?zhèn)淞顺墒煨院挽`活性,除了今天我們所介紹的KPack以外,通過把它和其他的技術相結合,可以開發(fā)出各種高效的新平臺,或者是推動現(xiàn)有工具的創(chuàng)新發(fā)展。
例如,就如前文所提到的,在企業(yè)最常用的微服務開發(fā)框架Spring Boot的2.3版本中,已經預集成了Cloud Native Buildpacks,而且使用起來非常簡單。具體來說,通過在Maven中使用新的spring-boot:build-image goal,或者是在Gradle中使用bootBuildImage task,都可以通過我們剛剛介紹的CNB的能力直接將源碼構建成為容器鏡像。有興趣的讀者不妨一試,體驗一下無需安裝任何工具便可以實現(xiàn)的全自動化的鏡像構建過程。
Kpack的使用
所有的開源項目,包括像Kpack這樣的項目,如果真的想要在實際工作中使用,都會有一些特別的問題需要注意,下面我們就了解一下幾個比較重要的問題。
從哪里可以找到Buildpacks?
其實對于我們一般的用戶來說,不用關心哪里去找Buildpacks,因為我們可能常用的Buildpacks已經內置在Kpack當中以套件的方式存在,可以直接使用了,正像上面的例子當中所描述的那樣。但是,我們最好還是應該了解Buildpacks具體是怎樣被組織和管理的,這樣我們才能用它完成日常工作中更加復雜的需求比如說它的定制和升級。
在Kpack中,還有一個很重要的組件我們沒有提及,那就是Builder,而這個Builder就是Buildpacks的組合套裝。根據在K8s當中的使用習慣,我們可以將Builder設定為供某一個namespace使用,或者供整個K8s全局使用的ClusterBuilder,這些都是通過yaml文件的配置實現(xiàn),非常簡單,不再贅述。
關鍵是Builder里面的結構是怎么樣的?
Kpack的Builder其實是Cloud Native Buildpacks中Builder組件的CRD封裝,下面就是CNB中Builder組成的示意圖:
我們可以看到,Builder主要由三部分組成:Buildpacks,lifecycle以及build image。其中的lifecycle其實上面我們已經詳細分析過,就是檢測,分析,構建和打包這四個步驟,而build image則是build源代碼所需要的基礎鏡像環(huán)境。
我們在圖中的左邊也可以看到一個run image,從名字當中可以得知,其實這個run image就是應用打包好之后可以去部署的運行環(huán)境。我們上面所提到的rebase的操作其實替換的就是這個run image:
由于CNB是公開的標準,所以Kpack可以使用任何滿足這樣規(guī)范的Builder。目前市場上面最為成熟和廣泛使用的builder是Packto Builders。而下面就是Packto Builder當中包含的Java的Buildpacks:
Packto目前主要是由VMWare(Pivotal)來維護和發(fā)展。
當然除了Packto的Builder,還有另外兩個Builder也是CNB官方推薦的,一個是來自于Google的用于GCP的Builder(gcr.io/buildpacks/builder),另外一個則是來自于Salesforce的Heroku(heroku/buildpacks:18)。
Buildpack需要升級怎么辦?
Buildpack需要升級這是一個非常明顯的需求,并且因為現(xiàn)在技術迭代的速度越來越快,軟件版本更新的頻率也越來越快,這樣在一年里面升級幾次Buildpack是很正常的事情。
目前CNB官方推薦的builder,比如說像Packto Builder,會實時跟蹤所包含的Buildpacks里面是否有任何新的升級或者安全補丁,并及時對這些Buildpack進行更新。所以,如果在Kpack里面選擇使用像Packto這樣比較成熟的Builder,用戶自己并不需要對Buildpack的升級做操作,只是需要考慮自己本地的升級策略和配置就可以了。
比如說下面是Kpack里面一個Builder的定義,也是一個CRD:
- apiVersion: build.pivotal.io/v1alpha1
- kind: ClusterBuilder
- metadata:
- name: cluster-sample-builder
- spec:
- image: gcr.io/paketo-buildpacks/builder:base
- updatePolicy:polling
在builder的配置里面,有一個updatePolicy的配置項,這個配置項可以有兩個選擇,一個是“polling”,如果選擇這個選項,Kpack會每隔5分鐘去查看一下正在使用的builder有沒有變化;也可以選擇“external”,在這種情況下是由用戶自己負責去升級替換Buildpack。
定制自己的Builder
下面我們把難度再提高一點:如何定制自己的Builder?
Kpack提供了另外一個CRD – CustomBuilder來支持用戶自定義CNB builder的需求。但是在定義自己的Builder之前,首先需要在Kpack里面定義兩個關鍵的資源:Store和Stack。
- Store的定義
首先是一個Store定義的例子:
apiVersion: experimental.kpack.pivotal.io/v1alpha1
kind: Store
metadata:
name: sample-store
spec:
sources:
- image: gcr.io/cf-build-service-public/node-engine-buildpackage@sha256:95ff756f0ef0e026440a8523f4bab02fd8b45dc1a8a3a7ba063cefdba5cb9493
- image: gcr.io/cf-build-service-public/npm-buildpackage@sha256:5058ceb9a562ec647ea5a41008b0d11e32a56e13e8c9ec20c4db63d220373e33
- image: gcr.io/paketo-buildpacks/builder:base
Store其實就是一個Buildpack的庫,在這個庫里面包含了可以用于定義CustomBuilder的所有的Buildpacks。例如,如果我們想從幾個Builder里面選出一些滿足自己需求的Buildpacks拼接成一個CustomBuilder,那么我們首先就需要把這些Buildpacks都列在這個Store對象里面,正如上面yaml文件所展示的那樣。
- Stack的定義
在上文已經提過,其實Stack就是定義基礎鏡像的地方。Stack會包含兩個基礎鏡像,一個是用于Build的,另外一個是用于應用的運行時環(huán)境的。下面就是一個示例的Stack的定義:
- apiVersion: experimental.kpack.pivotal.io/v1alpha1
- kind: Stack
- metadata:
- name: bionic-stack
- spec:
- id: "io.buildpacks.stacks.bionic"
- buildImage:
- image: "gcr.io/paketo-buildpacks/build@sha256:84f3eb6655aa126d827c07a3badbad3192288a50986be1b28ad2526bd38c93c7"
- runImage:
- image: "gcr.io/paketo-buildpacks/run@sha256:e30db2d9b15e0da9f4171e48430ce9249319c126ce6b670b68443e6c13e91aa5"
其中,id是這個stack的定義,當然企業(yè)可以根據自己的需求定義多個stack。BuildImage和runImage分別對應于構建和運行所使用的基礎鏡像模版。
由于很多企業(yè)對自己的基礎鏡像都有自己的要求,因此使用Stack來定義這些基礎鏡像是一個很好的辦法,因為這實際上是在企業(yè)內部建立起了一個標準鏡像,來自不同團隊的開發(fā)人員或者應用軟件供應商,通過使用Kpack生成容器鏡像的過程中,默認就已經遵循了企業(yè)安全和合規(guī)性等的要求,從而很好的解決了開發(fā)/測試/生產環(huán)境差異性的問題。
有了Buildpack和基礎鏡像,下面就可以定義自己的Builder了。比如說,如果一個企業(yè)的某個開發(fā)團隊主要基于Node.js和Java來開發(fā)應用,那么可以為他們定制如下的一個CustomBuilder:
- apiVersion: experimental.kpack.pivotal.io/v1alpha1
- kind: CustomBuilder
- metadata:
- name: my-custom-builder
- spec:
- tag: gcr.io/sample/custom-builder
- serviceAccount: default
- stack: bionic-stack
- store: sample-store
- order:
- group:
- id: paketo-buildpacks/node-engine
- id: paketo-buildpacks/yarn
- group:
- id: paketo-buildpacks/adopt-openjdk
- id: paketo-buildpacks/gradle
optional: true
- id: paketo-buildpacks/maven
optional: true
- id: paketo-buildpacks/executable-jar
optional: true
- id: paketo-buildpacks/apache-tomcat
optional: true
- id: paketo-buildpacks/spring-boot
optional: true
- id: paketo-buildpacks/dist-zip
optional: true
我們看,這個CustomBuilder使用了上面的store和stack,然后定義了兩個group,分別對應于編譯Node.js應用所需要的Buildpack和Spring Boot應用所需要的Buildpack。
我們再回到本文一開始提到的那個例子,在例子中鏡像的定義image.yaml文件中是這樣指定所用的builder的:builderRef: demo-builder。我們也可以把這個配置改成如下這樣:
- builder:
- name: my-custom-builder
- kind: CustomBuilder
這樣,Kpack就會用我們剛才定義的builder來構建這個鏡像了。
定制自己的Buildpack
Builder可以定制,Buildpack也同樣可以。比如說,對于文章開頭提到的公司C的例子,即便都是在用Java開發(fā)應用,但是不同的應用依賴的JDK版本有可能個不相同,這種情況下我們可能就需要對每一個JDK版本定制一個Buildpack,并且保存在系統(tǒng)中以用于后面軟件的更新和升級。這種情形可能相對比較簡單,我們可以拷貝一個現(xiàn)有的Java Buildpack,然后對配置做相應的修改,重新打包就可以了。
但是有的時候,Buildpack的定制可能會很復雜。比如說如果需要在Buildpack中加入公司要求的APM或者日志管理的agent,或者應用要滿足一些合規(guī)性要求,這樣就需要對Buildpack的結構作比較多的修改,甚至有可能需要完全重新做一個自己的Buildpack才能完全滿足要求。這一部分涉及到的的內容可能也會比較復雜,在本文中就不詳述,以后有機會可以用一個單獨的主題來分享。
Kpack的展望
一直以來,開發(fā)人員對效率的追求和運維人員對環(huán)境的控制始終是以尖銳的矛盾形式存在,而Buildpack技術體系在過去十年在世界各大領軍企業(yè)的大規(guī)模生產實踐中,成功證明了它可以作為開發(fā)和運維需求的橋梁,把這對矛盾巧妙地轉化為了雙方一致的目標:在安全可控環(huán)境之內的應用快速開發(fā)和部署。
而伴隨著Kubernetes逐漸成為基礎設施的新標準,Kubernetes社區(qū)也急需要類似Buildpack這樣的技術來大大降低Kubernetes在企業(yè)落地的難度。這正是VMware(Pivotal)開源Kpack的主要原因:我們希望將世界范圍內廣受認可的Buildpack的技術體系和Kubernetes的聲明式資源管理方式結合在一起,把過去成功的經驗移植到K8s平臺上面來,為社區(qū)提供一個基礎和參考去做更多的創(chuàng)新。
當然,我們首先自己就有基于Kpack的企業(yè)級版本,那就是VMWare Tanzu產品家族中的Tanzu Build Service和Tanzu Application Service for K8s。下面我們可以分別來簡單了解一下這兩個企業(yè)級版本。
Tanzu Build Service:企業(yè)級容器鏡像構建流水線
與很多開源軟件的企業(yè)級版本一樣,Tanzu Build Service(以下簡稱TBS)致力于將kpack與其相關的工具集成在一起,例如默認的Buildpacks和Kubernetes權限模型,這樣大大減少手工的配置工作,使平臺更加容易使用。
另外,我們深知很多研發(fā)和運維工程師都不喜歡寫yaml文件,所以TBS還將提供一個稱為kp的可選專用CLI,以幫助工程師更快地工作,并更輕松地管理團隊的多租戶。
當然,最重要是我們提供Buildpacks的支持和維護工作,這將會使TBS的用戶放心使用安全和穩(wěn)定的軟件棧來部署自己的應用。
TBS比較適合于已經建立了自己的CI/CD管道的企業(yè),因為TBS解決了最繁瑣的從代碼到容器鏡像的自動化過程,可以直接與企業(yè)后面的應用自動部署整合在一起,形成端到端的應用部署管道。
您可以通過https://tanzu.vmware.com/build-service來進一步了解TBS。
然而,很多企業(yè)的要求可能更高,他們希望自己有一個全自動化的平臺,不但整個應用的構建環(huán)境和運行環(huán)境完全可控,同時希望平臺可以提供從代碼到部署完成的全自動化服務,就像是上文提到的Pivotal Application Service的“一鍵部署”那樣的體驗。
這就要用到我們另外一個基于Kpack的商業(yè)產品:Tanzu Application Service for K8s了。
TAS for K8s:實現(xiàn)Kubernetes平臺上面的應用一鍵部署
TAS for K8s,全名是Tanzu Application Services for K8s,是VMWare Tanzu產品家族里面的PaaS平臺,正是來源于原來的Pivotal Application Service在K8s平臺上面的實現(xiàn)(原來的Pivotal Aplication Service現(xiàn)在名稱為TAS for VM)。
雖然從原來的基于虛擬機運行的構架重構為現(xiàn)在面向K8s的構架,TAS for K8s上面提供的一鍵部署的產品體驗仍然會和原來的Pivotal Application Service類似,甚至連CLI工具都保持不變(仍然是cf push)。
在實際工作場景中TAS for K8s是怎么用的?
如果從一個開發(fā)工程師的角度來看,他只需在自己的源代碼目錄里面直接執(zhí)行一個cf push命令,一兩分鐘之后,他的應用已經部署在K8s集群里面可以直接訪問了!在整個流程中,Kpack會負責從代碼構建為鏡像的部分,然后鏡像構建好之后會觸發(fā)鏡像的自動化部署過程,這個過程主要是由另外一個開源項目Eirini來實現(xiàn),它會自動生成yaml文件,并將鏡像部署為K8s服務供外部訪問。
而從運維團隊的角度來看,他們也不用再擔心每次應用上線的時候晝夜鏖戰(zhàn)的痛苦經歷了,因為通過在開發(fā)/測試/生產環(huán)境中維護同一套滿足安全,合規(guī)以及開發(fā)團隊需求的Buildpacks,環(huán)境差異已經不再存在,因此在生產環(huán)境上線已經沒有多少需要手工準備的工作,上線過程已經簡化成了幾條命令;同時也不用再擔心開源軟件可能帶來的安全漏洞,因為所有的漏洞都會在第一時間在Buildpacks里面被補上!
當然,為了對這個平臺有全面的管理,我們也集成了很多K8s的工具來支撐微服務治理,日志,監(jiān)控,APM,高可用等方面的能力,也是通過自動化配置的方式來減輕運維人員的負擔。
您可以通過https://tanzu.vmware.com/application-service來了解更多關于TAS的詳細信息。
總結
未來的企業(yè)應該需要什么樣的工具來使用Kubernetes?從我個人看來,其實答案很簡單:這個工具應該使工程師們,不管是開發(fā)還是運維,忘記Kubernetes的存在,而不是成為Kubernetes的專家。因為企業(yè)的主要目標是自己核心業(yè)務的創(chuàng)新,而不是要開發(fā)IT基礎設施的產品。
過去的Pivotal一直是圍繞著這個目標為企業(yè)提供產品,今天的VMWare也正在繼續(xù)為此而努力。不論是開源的Kpack,Cloud Native Buildpacks,還是商業(yè)產品TBS和TAS,都已經開始展示出實現(xiàn)這樣目標的能力,提供了一條從開源的Kubernetes到現(xiàn)代化的企業(yè)云平臺的最短實現(xiàn)路徑。但是與云原生技術的快速發(fā)展同步,這些產品也仍然還是處于快速發(fā)展之中,在未來還會有各種各樣令人興奮的新功能加入其中。所以歡迎各位讀者對這些產品保持關注,如果愿意試用并提出寶貴意見,我們將不勝感激,并且很愿意與您做深入探討。
楊海濤
Email: ypaul@vmware.com
WeChat: yanghaitao1979
作者介紹:楊海濤現(xiàn)任VMWare資深云平臺架構師,對于應用現(xiàn)代化,云原生平臺以及DevOps等領域有深入的理解和豐富的實踐經驗,目前主要負責VMWare Tanzu產品的解決方案設計,咨詢和推廣等工作,是Spring認證工程師,Kubernetes認證管理員以及AWS認證架構師。在超過15年的職業(yè)經歷中,一直專注于軟件行業(yè)。從事過與軟件相關的多種工作,包括:技術研發(fā)、項目管理、技術支持、團隊管理和系統(tǒng)架構等,據有多個不同行業(yè)的大型項目經驗。來源:VMware中國