本篇文章為大家展示了Kubernetes實(shí)踐彈性的CI/CD系統(tǒng)現(xiàn)狀分析,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
成都創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比豐澤網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式豐澤網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋豐澤地區(qū)。費(fèi)用合理售后完善,10年實(shí)體公司更值得信賴。首先簡(jiǎn)單解釋一下何為 Kubernetes 來(lái)幫助大家理解。Kuberentes 是一個(gè)生產(chǎn)可用的容器編排系統(tǒng)。Kuberentes 一方面在集群中把所有 Node 資源做一個(gè)資源池,然后它調(diào)度的單元是 Pod,當(dāng)然 Pod 里面可以有多個(gè)容器。 就像一個(gè)人左手抓著 ECS 資源或計(jì)算資源,右手抓容器,然后把它們兩個(gè)匹配起來(lái),這樣它就可以作為一個(gè)容器的編排系統(tǒng)。
而 Cloudnative 這個(gè)概念現(xiàn)在會(huì)經(jīng)常被大家提起,很多人迷惑 Cloudnative 又與 Kuberentes 有什么關(guān)聯(lián)?我們又該如何判斷一個(gè)應(yīng)用是 Cloudnative 呢?我認(rèn)為有以下三個(gè)判斷標(biāo)準(zhǔn):
第一,它能夠給資源做池化;
第二,應(yīng)用可以快速接入池的網(wǎng)絡(luò)。在 Kuberentes 里面有一層自己的獨(dú)立網(wǎng)絡(luò),然后只需要知道我要去訪問(wèn)哪個(gè)服務(wù)名就可以,就是各種服務(wù)發(fā)現(xiàn)的一些功能,它可以通過(guò) service mesh 去做一個(gè)快速地訪問(wèn);
第三是有故障轉(zhuǎn)移功能,如果一個(gè)池子里面有一臺(tái)主機(jī),或者某一個(gè)節(jié)點(diǎn) down 掉了,然后整個(gè)應(yīng)用就不可用了,這肯定不算是 Cloudnative 的應(yīng)用。
比較這三點(diǎn)就可以發(fā)現(xiàn) Kuberentes 做的非常好。首先我們看一個(gè)資源池的概念,Kuberentes 一個(gè)大的集群就是一個(gè)資源池,我們?cè)僖膊挥萌リP(guān)心說(shuō)我這個(gè)應(yīng)用要跑在哪臺(tái)主機(jī)上了,我只要把我們部署的 yaml 文件往 Kuberentes 上發(fā)布就可以了,它會(huì)自動(dòng)做這些調(diào)度,并且它可以快速地接入我們整個(gè)應(yīng)用的網(wǎng)絡(luò),然后故障轉(zhuǎn)移也是自動(dòng)。接下來(lái)我就來(lái)分享如何基于 Kuberentes 實(shí)現(xiàn)一個(gè)彈性的 CI/CD 系統(tǒng)。
CI/CD 的現(xiàn)狀
首先了解一下 CI/CD 的現(xiàn)狀。CI/CD 這個(gè)概念實(shí)際上已經(jīng)提出很多年了,但是隨著技術(shù)地演進(jìn)和新工具地不斷推出,它在整個(gè)流程和實(shí)現(xiàn)方式上逐漸豐富。而我們通常最早接觸 CI/CD 就是代碼提交,隨之觸發(fā)一個(gè)事件,然后在某個(gè) CI/CD 系統(tǒng)上做自動(dòng)構(gòu)建。
下圖可以反映目前 CI/CD 的現(xiàn)狀:
然后做了一個(gè)壓測(cè)(性能上的壓測(cè)),這只是在開(kāi)發(fā)測(cè)試環(huán)境做了一層處理。然后它可以在 QA 環(huán)境,最終延伸到 UAT 環(huán)境,整個(gè) pipeline 是一個(gè)非常長(zhǎng)的過(guò)程。CI/CD 的使用范圍很廣,它可以把整個(gè) IT 從代碼編寫(xiě)提交到代碼倉(cāng)庫(kù)為起點(diǎn),從這兒開(kāi)始往后做,各個(gè)步驟都可以納入 CI/CD 的范圍。但是隨著它的管控范圍越來(lái)越多,整個(gè)流程越來(lái)越復(fù)雜,它對(duì)資源的占用也是越來(lái)越高。
大家如果了解 C++的話,就會(huì)知道 C++ 以前是一門(mén)著名的、構(gòu)建時(shí)間特別長(zhǎng)的語(yǔ)言。Go 語(yǔ)言的作者之一,也是 C 語(yǔ)言的作者, 談及當(dāng)時(shí)寫(xiě) Go 完全是因?yàn)椴幌雽?xiě)一次代碼,編譯那么久。所以,Go 語(yǔ)言剛出現(xiàn)時(shí)的一大優(yōu)勢(shì)就是編譯時(shí)間非常短。Go 的編譯時(shí)間確實(shí)非常短。
我曾用一個(gè) I5 的筆記本編譯 Kubernetes 源碼做一次完整地構(gòu)建,大概編譯了 45 分鐘左右,這是一個(gè)非常漫長(zhǎng)的過(guò)程。所以,即便已經(jīng)對(duì)編譯過(guò)程做了很大優(yōu)化和改進(jìn),只要項(xiàng)目大了之后,只是構(gòu)建階段就已經(jīng)很長(zhǎng)了,更不要說(shuō)包括后面的一些自動(dòng)化測(cè)試了。包括所有東西之后,CI/CD 流程對(duì)資源地消耗和占用的時(shí)間是非常大的。
CI/CD 工具的選擇
接下來(lái),我們看一下 CI/CD 這些工具的選擇和他們的發(fā)展。首先最老牌的肯定是 Jenkins。實(shí)際上在容器技術(shù)興起之前,CI/CD 簡(jiǎn)直約等于 Jenkins。但是在出現(xiàn)容器技術(shù)之后,很多新生 CI/CD 的工具也應(yīng)運(yùn)而生,比如 Drone 工具,它是一個(gè)完全基于容器來(lái)實(shí)現(xiàn)的 CI/CD 工具。它與容器地結(jié)合地非常好,并且它的構(gòu)建過(guò)程是完全在容器中實(shí)現(xiàn)的。
另外還有 Gitlab CI,它主要特點(diǎn)是與 Gitlab 代碼管理工具結(jié)合地比較好。Jenkins 2.0 開(kāi)始引入 pipeline as code 特性,pipeline as code 可以幫我們自動(dòng)生成一個(gè) jenkins file。
在 Jenkins 1.0 時(shí),如果我們想要配置一條流水線,需要先登錄 Jenkins 建一個(gè)項(xiàng)目,然后在里面寫(xiě)一些 shell。這樣雖然能達(dá)到同樣的效果,但是它有一個(gè)大的弊端,就是可復(fù)制性和遷移性不好。而且它與 Devops 有天然地割裂,比如一般是由運(yùn)維人員來(lái)管理 Jenkins 系統(tǒng),開(kāi)發(fā)人員編寫(xiě)代碼,但是這個(gè)代碼怎么去構(gòu)建,發(fā)布到哪里,開(kāi)發(fā)人員完全不知道。這就造成了開(kāi)發(fā)和運(yùn)維地割裂。但 pipeline as code 方式出現(xiàn)了之后,jenkins file 與代碼源碼可以放在同樣的倉(cāng)庫(kù)里面。
首先它有一個(gè)非常大的好處是發(fā)布的流程也可以納入版本管理,這樣對(duì)一個(gè)錯(cuò)誤就可追溯。這是一個(gè)非常大地改動(dòng),但是實(shí)際上我們?cè)谂c客戶溝通中發(fā)現(xiàn),雖然很多人在 Jenkins 上都已經(jīng)升到 2.0 系列了,但是它們的用法還是完全在 1.0 系列,很多用戶都沒(méi)有把 jenkins file 這種方式用起來(lái)。另外一個(gè)就是對(duì)容器地支持,大概 2016 年左右,那時(shí)對(duì)容器的支持是非常弱的,在容器里面運(yùn)行 Jenkins,同時(shí)構(gòu)建的產(chǎn)物也是 Docker 會(huì)非常麻煩。
但是, Drone 對(duì)容器的支持力度就非常好。首先它完全用 Docker 方式來(lái)運(yùn)行,就是說(shuō)你的構(gòu)建環(huán)境也在一個(gè)容器里,你需要構(gòu)建一個(gè) Docker build 鏡像,然后在推送出去的時(shí)候,它也在容器里面運(yùn)行,然后它需要一個(gè) privilege 權(quán)限。它這種方式有幾個(gè)特別好的地方,首先它不會(huì)對(duì)宿主機(jī)產(chǎn)生任何殘留,比如說(shuō)你這個(gè)容器一銷(xiāo)毀,構(gòu)建中產(chǎn)生的一些中間文件完全都跟著銷(xiāo)毀了,但是你如果用 Jenkins 的話,隨著用的時(shí)間越來(lái)越久會(huì)沉淀出很多臨時(shí)文件,它占的空間會(huì)越來(lái)越大。你需要定期做一些清理,而且清理過(guò)程中你又不能直接一鍵清空,所以這是很麻煩的過(guò)程。
然后插件的管理 Jenkins 還有一個(gè)特別讓人頭疼的地方,就是它的插件升級(jí)。首先你在 Jenkins 登錄進(jìn)去,然后就做插件升級(jí)。如果說(shuō)我想臨時(shí)在一個(gè)新的環(huán)境里面,起一個(gè) Jenkins 先測(cè)試一下或做一些調(diào)試可能每新建一個(gè)環(huán)境,都需要把這些插件升級(jí)一次。而且剛才我們說(shuō)的在 Jenkins 里面做的所有配置,也都需要重新配置一遍,這是一個(gè)非常繁瑣的一個(gè)過(guò)程。
但是 Drone 這個(gè)工具它有一個(gè)特別好的地方,就是所有的插件都是 Docker 容器,比如說(shuō)你在 pipeline 里用這個(gè)插件,你只要聲明用這個(gè)插件就可以了,你不用去自己管理把插件下載到哪里,然后怎么安裝,它這個(gè)一切都是全自動(dòng),只要說(shuō)你網(wǎng)絡(luò)能把插件容器鏡像訪問(wèn)到就可以了,這非常便利。
然后關(guān)于生態(tài)的構(gòu)建,Jenkins 的大的優(yōu)勢(shì)就是它的插件非常多,就是你想用的各種東西都有,而且它基礎(chǔ)的底座非常好,你的插件可以實(shí)現(xiàn)的能力非常的強(qiáng)。比如說(shuō) pipeline 就是這種方式,它從 1.0 到 2.0 雖然有了,但是它完全是通過(guò)插件來(lái)實(shí)現(xiàn)的。但是現(xiàn)在 Jenkins 的發(fā)展又開(kāi)始有點(diǎn)第二春的感覺(jué)。他開(kāi)始對(duì) Kuberentes 的支持力度明顯的加大了很多,首先從 JenkinsX 開(kāi)始,它融合了一些 Kuberentes 生態(tài)相關(guān)的一些工具,比如 Harbor、Helm 它可以非常便利地在 Kuberentes 集群上來(lái)做一些構(gòu)建,并且把一些做服務(wù)的固化的一些編排文件放到 Helm 里面。
另外,現(xiàn)在它有一個(gè)新的子項(xiàng)目叫 config as code,也就是說(shuō)他把所有 Jenkin 里面做了一些配置,都可以輸出成一個(gè) code 的形式,就是對(duì)整個(gè) Jenkins 的遷移,或者說(shuō)復(fù)制都是一個(gè)很便利的改進(jìn)。
講了那么多,實(shí)際上最后我們選擇的東西還是 Jenkins,因?yàn)樽钪匾氖巧鷳B(tài)的構(gòu)建,他們已經(jīng)很好了。今天我們要講的在做一個(gè)彈性在 CI/CD 這個(gè) Jenkins 上已經(jīng)有這個(gè)插件了,但是在 Drone 的社區(qū)里面,有人提這個(gè)事,但是現(xiàn)在還沒(méi)有看到。
CI/CD 的系統(tǒng)業(yè)務(wù)場(chǎng)景
然后我們看一下 CI/CD 它的系統(tǒng)的業(yè)務(wù)場(chǎng)景,它有一個(gè)比較典型的場(chǎng)景與特點(diǎn),首先它面向開(kāi)發(fā)人員,這是比較少見(jiàn)的,因?yàn)殚_(kāi)發(fā)人員一般都比較挑剔一點(diǎn)。所以你要是這個(gè)系統(tǒng)做的不夠穩(wěn)健了,或者說(shuō)響應(yīng)時(shí)間比較長(zhǎng)一點(diǎn)的話,會(huì)被經(jīng)常吐槽。
然后就是有時(shí)效性要求,因?yàn)槲覀兇a寫(xiě)完之后,往上提交,我們都不希望在這個(gè)代碼的構(gòu)建中一直排隊(duì),我們希望馬上就開(kāi)始進(jìn)行構(gòu)建,并且資源足夠豐富。另外一個(gè)就是它的資源占用的波峰波谷是非常明顯的。就因?yàn)殚_(kāi)發(fā)人員不可能時(shí)時(shí)刻刻都在提交代碼,有的人可能一天提交幾次,有的人會(huì)提交很多次。
因?yàn)槲抑翱催^(guò)有一個(gè)分享,有一個(gè)人畫(huà)了一條反映自家公司構(gòu)建任務(wù)的曲線。他們公司大概是每天下午三、四點(diǎn)的時(shí)候代碼提交量最高,其他時(shí)間都比較平緩。這說(shuō)明他們公司三、四點(diǎn)的時(shí)候,程序員提交代碼開(kāi)始劃水了。然后隨著 CI/CD 資源地需求越來(lái)越高,構(gòu)建集群是一個(gè)必須要做的一件事情。就是提高負(fù)載能力,縮短任務(wù)的排隊(duì)時(shí)間。當(dāng)然真正的集群有一個(gè)讓人覺(jué)得很不太好的地方,就是它的 Master 實(shí)際上只有一個(gè),當(dāng)然這個(gè)也可以通過(guò)插件來(lái)做改進(jìn)。
但這不是今天我們要講的重點(diǎn),因?yàn)楹芏鄷r(shí)候 Master 短暫的不可用,然后能快速恢復(fù)也是可以接受的。然后另外它需要來(lái)滿足各種構(gòu)建場(chǎng)景。一個(gè)公司里面可能用到很多的開(kāi)發(fā)環(huán)境,就像雖然我們都用 Java,但可能會(huì)有 1.5、1.6、1.7 的差別。 如果不用 Java,很可能用很多其他語(yǔ)言如 Python、Go、NodeJS 等需要很多的構(gòu)建環(huán)境。而且如果我們不引入容器的話,這些構(gòu)建環(huán)境不能重用,可能一臺(tái)主機(jī)只能給 PHP 在用。
容器可以給我們 CI/CD 系統(tǒng)來(lái)注入新的能力,就是環(huán)境隔離的能力。我們可以通過(guò) Kubernetes 來(lái)為 CI/CD 系統(tǒng)注入更多的能力,然后矛盾點(diǎn)就出現(xiàn)了。開(kāi)發(fā)人員總是希望 CI/CD 系統(tǒng)能夠快速地響應(yīng)代碼提交的一個(gè)事件,但是每個(gè)公司資源都不可能是無(wú)限的。因?yàn)榫拖裆厦嫣岬降模绻刻煜挛缛?、四點(diǎn)的時(shí)候是一個(gè)代碼提交的高峰,這個(gè)時(shí)候可能需要 30 或 40 臺(tái)機(jī)器才能滿足構(gòu)建的任務(wù)。但是我不可能每天就開(kāi)著 30 或 40 臺(tái)機(jī)器在這里,就為了每天下午三、四點(diǎn),可能會(huì)構(gòu)建一、兩個(gè)小時(shí)。
Kubernetes 可以為 jenkins 注入新的能力,讓 CI/CD 系統(tǒng)實(shí)現(xiàn)彈性的能力。我們期望的目標(biāo)是什么呢?有構(gòu)建任務(wù)的時(shí)候,可以自動(dòng)為我們資源增加新的機(jī)器也好,或增加新的運(yùn)計(jì)算能力也好,反正就是當(dāng)我需要的時(shí)候,可以幫我自動(dòng)地做一個(gè)資源擴(kuò)張,但是同時(shí)也在我不需要的時(shí)候,可以自動(dòng)把這些資源釋放掉。
我們期望的目標(biāo)就是這樣,Kuberentes 就可以為 Jenkins 來(lái)做這樣的能力。Kuberentes 作為一個(gè)容器編排的系統(tǒng),它所能提供的能力,它可以快速地彈出一些新的實(shí)例,并且把它們自動(dòng)調(diào)度到空閑的機(jī)器上,做一個(gè)資源池,在資源池里面做一個(gè)調(diào)度,并且他執(zhí)行完任務(wù)之后,它可以做一個(gè)回收。而且如果把這 Jenkins Master 也部署在 Kuberentes 之上,它可以對(duì) Master 做一個(gè)故障轉(zhuǎn)移,就是說(shuō)如果我們系統(tǒng)可以容忍的話,Master 就算掛了,我可以快速把它調(diào)到另外一臺(tái)機(jī)器上,這個(gè)響應(yīng)時(shí)間不會(huì)很長(zhǎng)。
Kubernetes-piugin
這里面也是用一個(gè)插件來(lái)實(shí)現(xiàn),這個(gè)插件名字比較直接叫 Kuberentes-plugin,它這個(gè)插件所能提供的能力就是說(shuō),他直接管理一個(gè) Kuberentes 集群,它在 Jenkins 里面安裝之后,它可以監(jiān)聽(tīng) Jenkins 的構(gòu)建任務(wù)。有構(gòu)建任務(wù),在等待資源的時(shí)候,它就可以向 Kuberenetes 去申請(qǐng)一個(gè)新的資源,申請(qǐng)一個(gè)新的 Pod 去做自動(dòng)地構(gòu)建完之后,它就會(huì)自動(dòng)的清理。
先簡(jiǎn)單介紹一下它的能力,因?yàn)檫@個(gè)插件安裝完之后,它對(duì) pipeline 的語(yǔ)法也有一個(gè)改造,一會(huì)我們來(lái)看一下實(shí)例。但是就算到了這一步,還是不行的。首先,Kuberentes 的集群規(guī)劃還是一個(gè)問(wèn)題。比說(shuō)我有個(gè)集群有 30 個(gè)節(jié)點(diǎn),真正的 master 部署在這上面,然后裝了那些插件,做了一個(gè)管理之后,我們可以發(fā)現(xiàn)來(lái)了一個(gè)新的任務(wù),它就起一個(gè)新的 Pod,把這個(gè)構(gòu)建任務(wù)給執(zhí)行制定完。
執(zhí)行完之后,這 Pod 自動(dòng)銷(xiāo)毀不占集群的資源。 平時(shí)我們可以在這集群上做一些別的任務(wù),但這個(gè)終究還是有一點(diǎn)不好,就是我們這個(gè)集群到底規(guī)劃多大,并且這個(gè)集群我們平時(shí)不做構(gòu)建任務(wù)的時(shí)候,可以在上面做一些別的任務(wù)。但是如果正在做任務(wù),突然來(lái)了一些構(gòu)建任務(wù),它可能會(huì)出現(xiàn)資源的沖突問(wèn)題。
Kubernetes Autoscaler
總的來(lái)說(shuō),還是有一些不完美的地方,那么我們可以利用 Kuberentes 一些比較沒(méi)那么常見(jiàn)的特性,來(lái)解決我們剛才說(shuō)的這個(gè)問(wèn)題。這兩個(gè)東西一個(gè)是叫 Autoscaler,一個(gè)叫 Virtual node。我們先看一下 Autoscaler,Autoscaler 是一個(gè) Kubernetes 官方的一個(gè)組件。在 Kuberentes 的 group 下面支持三種能力:
Cluster Autoscaler,可以對(duì)集群節(jié)點(diǎn)做自動(dòng)伸縮;
Vertical Pod Autoscaler,對(duì)集群的 Pod 豎直方向的資源伸縮。因?yàn)?Kuberentes 本身里面就帶著 HPA 可以做水平方向的 Pod 伸縮、節(jié)點(diǎn)數(shù)量的伸縮;這個(gè)特性還不是生產(chǎn)可用的特性;
Addone Resizer,是 Kuberentes 上那些 addone 比如說(shuō) Ingress Controler、 DNS 可以根據(jù) Node 的數(shù)量來(lái)對(duì)資源的分配做調(diào)整。
我要講的是 Cluster autoscaler,是對(duì)集群 node 節(jié)點(diǎn)數(shù)量做一個(gè)擴(kuò)縮容。 首先我們看一下,這個(gè)是在阿里云我們?nèi)萜鞣?wù)上所實(shí)現(xiàn)的 Autoscaler 的一個(gè)方式。我們看一下這個(gè)圖,這個(gè)是 HPA 和 Autoscler 做結(jié)合使用的一個(gè)場(chǎng)景。
HPA 監(jiān)聽(tīng)監(jiān)控的事件時(shí)發(fā)現(xiàn)資源使用率上升到一定程度了之后,HPA 會(huì)自動(dòng)通知 workload,來(lái)彈出一個(gè)新的 Pod,彈出一個(gè)新的 Pod,可能這時(shí)候集群資源就已經(jīng)不夠了,所以這個(gè) Pod 可能就會(huì) pending 在這里。它就會(huì)觸發(fā) Autoscaler 的事件,Autoscaler 就會(huì)根據(jù)我們之前配置好的 ESS 這個(gè)模板來(lái)去彈出來(lái)一臺(tái)新的 Node,然后自動(dòng)地把 Node 加入到我們集群里面。 它是利用了 ESS 定制的模板功能,并且它可以支持多種的 Node 實(shí)例的類(lèi)型,可以支持普通實(shí)例,支持 gpu,還有搶占式實(shí)例。
然后第二種是 Virtual node,Virtual node 實(shí)現(xiàn)方式是基于微軟開(kāi)源的 Virtual Kubelet 這個(gè)項(xiàng)目。它做了一個(gè)虛擬的 Kubelet,然后向 Kubernetes 集群里面去注冊(cè)上面。但如果不太好理解的話,可以想象一下 MySQL proxy ,然后他把自己偽裝成一個(gè)MySQL server,然后后端可能管理著非常多的 MySQL server,并且它可以幫你自動(dòng)的做一些 SQL 查詢的路由或者拼接。
Virtual kubelet 做的也是類(lèi)似的工作,就是說(shuō)它本身向著 Kubernetes 注冊(cè)說(shuō)我是一個(gè)節(jié)點(diǎn),但實(shí)際上它后端管理的可能是整個(gè)公有云上的非常多的資源,他可能對(duì)接公有云的一些 ECI 或者說(shuō)對(duì)接的這些 VPC,這是一個(gè)它的大體的示意圖。
在阿里云上他們對(duì)接的是阿里云的 ECI 做一個(gè)彈性的容器實(shí)例,它響應(yīng)時(shí)間就非???,因?yàn)樗恍枰?Node 去加入到集群里面,它是大概能夠到一分鐘一百個(gè) Pod 左右這種性能。而且我們可以在 Pod 上聲明這種資源的使用情況,這是一個(gè)非??斓捻憫?yīng)速度時(shí)間。
然后剛才說(shuō)我們利用這兩種方式,就可以對(duì)我們 CI/CD 彈性的系統(tǒng)做出新的改造,我們不用非常早規(guī)劃好我們集群的規(guī)模,我們可以讓集群規(guī)模在需要的時(shí)候自動(dòng)的做一些伸縮的動(dòng)作。但是你做了這些動(dòng)作之后,我們做了這些把真正的放在容器里面的這些動(dòng)作之后,引入了一些新的門(mén)檻:docker-outside-of-docker 和 docker in docker。
我們?cè)?Docker 中運(yùn)行 Jenkins 時(shí),通常有兩種方式,一個(gè)是把宿主機(jī)的 docker.sock 掛載到容器里面,讓 Jenkins 通過(guò)這個(gè)文件來(lái)和本機(jī)的 docker daemon 做一個(gè)通信,然后它在這里面做 docker build 構(gòu)建鏡像,或者把這些鏡像 push 到遠(yuǎn)程的倉(cāng)庫(kù)里面,所以它中間產(chǎn)生的所有鏡像都會(huì)堆積在本機(jī)上,這是一個(gè)問(wèn)題。
在一些 serverless 的那些場(chǎng)景上使用,它就會(huì)有一些限制,因?yàn)?serverless 本身就不允許把 socket 文件給掛在進(jìn)去。另外一個(gè)就是 docker in docker 這種方式,它的優(yōu)點(diǎn)就在于在容器里面它啟動(dòng)一個(gè)新的 Docker daemon,它所有的中間產(chǎn)物、構(gòu)建產(chǎn)物隨著容器都一起銷(xiāo)毀,但是它有問(wèn)題,它就是需要 privilege 的權(quán)限。
很多時(shí)候我們是盡量不要用它。另外一個(gè)就是說(shuō)你做 docker build 的時(shí)候能在宿主機(jī)上做的時(shí)候,它如果有已經(jīng)有鏡像了,它會(huì)直接就使用這個(gè)鏡像,但是你用 docker in docker 這種方式來(lái)使用的,它每次都會(huì)重新拉進(jìn)項(xiàng),拉鏡像也是需要一定時(shí)間,這個(gè)取決于我們各個(gè)使用場(chǎng)景來(lái)判斷。
新的構(gòu)建工具——Kaniko
這時(shí)又引入了一個(gè)谷歌開(kāi)源的新工具——Kaniko。它做的東西是 docker in docker 的方式。它有一個(gè)非常大的好處就是不依賴 Docker,而且所以它不需要 privilege 權(quán)限就可以在容器里面用用戶態(tài)的模式,來(lái)完全構(gòu)建 docker image。用戶態(tài)執(zhí)行 Dockerfile 的命令,它把這個(gè)鏡像完全構(gòu)建出來(lái)。
這算是一個(gè)比較期望的彈性的 CI/CD 系統(tǒng)。然后這個(gè)時(shí)候就是說(shuō)從真正的節(jié)點(diǎn)到底層的計(jì)算資源全部是彈性擴(kuò)縮的,而且滿足交付的需求,可以非常精細(xì)化地管理我們的資源。
Demo 演示
然后我們可以看一下 Demo 演示:
https://github.com/hymian/webdemo 這里是我準(zhǔn)備好的一個(gè)例子,重點(diǎn)在這個(gè) Jenkinsfile 文件,里面定義了agent 的 pod template,包含兩個(gè)容器,一個(gè)用來(lái)做 golang 的 build,一個(gè)用來(lái)做 image 的 build。
然后我們現(xiàn)在構(gòu)建它。開(kāi)始構(gòu)建了,剛開(kāi)始的,因?yàn)槭乾F(xiàn)在我們?cè)谶@環(huán)境里面只有一個(gè),只有一個(gè) master,所以他就是沒(méi)有不會(huì)有構(gòu)建節(jié)點(diǎn)。大家可以看到,它現(xiàn)在新啟動(dòng)了一個(gè) Pod,這個(gè) Pod 是作為節(jié)點(diǎn)加進(jìn)來(lái)的,但是因?yàn)槲以谶@個(gè) Pod 模板里面定義了一個(gè) label,所以它沒(méi)有這個(gè)節(jié)點(diǎn),所以它 Pod 狀態(tài)是 pending 的。所以我們?cè)跇?gòu)建日志里面顯示的這個(gè)是 agent 節(jié)點(diǎn)是離線的。
但是我們?cè)谶@個(gè)集群里面定義了一個(gè)彈性伸縮的一個(gè)東西,當(dāng)沒(méi)有節(jié)點(diǎn)的時(shí)候,它會(huì)自動(dòng)做一個(gè)新節(jié)點(diǎn)分配加入,可以看到有一個(gè)節(jié)點(diǎn)正在加入,這個(gè)我就可以稍等一下。就是說(shuō)這段時(shí)間可能會(huì)有個(gè)一分鐘兩分鐘的時(shí)間。
節(jié)點(diǎn)不夠的時(shí)候,它可以自動(dòng)擴(kuò)容然后加入集群,這個(gè)要稍微等一下。因?yàn)檫@個(gè)時(shí)間會(huì)稍微久一點(diǎn),是因?yàn)槭紫人|發(fā)到我這個(gè)擴(kuò)容,它有一個(gè)輪詢的時(shí)間差。整個(gè)過(guò)程下來(lái)可能有三分鐘左右。我看一下我這個(gè)服務(wù)器,這個(gè)服務(wù)器剛才是三個(gè),現(xiàn)在這個(gè)服務(wù)器是剛剛加入了,這是搶占,這是我剛剛加入的一個(gè)東西。
這個(gè)是異常,是因?yàn)檫@個(gè)節(jié)點(diǎn)正在向集群加入,所以它顯示是異常,這是我們從命令行看一下,好,已經(jīng)是四個(gè)節(jié)點(diǎn)了,加了一個(gè)節(jié)點(diǎn),這時(shí)候我們看 Pod,這時(shí)候在 agent 正在創(chuàng)建,這時(shí)候大家可能有一個(gè)小的細(xì)節(jié),大家可以看一下,就是 0/3 是顯示 Pod,它有三個(gè)容器,但是我剛才在這個(gè)里面定義的,它實(shí)際上是 Pod 里面只有兩個(gè)容器,這就是我們剛才 PPT 上寫(xiě)的一個(gè)地方。
JNLP 那個(gè)容器,是 plugin 自動(dòng)注入的一個(gè)容器,它通過(guò)這個(gè)容器實(shí)時(shí)的向 master 匯報(bào)構(gòu)建的一個(gè)中間的狀態(tài),我把它的日志給發(fā)送出去。這個(gè)是 agent 的節(jié)點(diǎn)在初始化的一個(gè)過(guò)程一個(gè)事情這時(shí)候 slave節(jié)點(diǎn)已經(jīng)在運(yùn)行了。我這邊已經(jīng)輸出完了,構(gòu)建完成。
上述內(nèi)容就是Kubernetes實(shí)踐彈性的CI/CD系統(tǒng)現(xiàn)狀分析,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道。