<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          現(xiàn)代 Web CI/CD 系統(tǒng)的搭建

          共 10395字,需瀏覽 21分鐘

           ·

          2021-08-11 10:24

          本次直播錄播鏈接:https://live.juejin.cn/4354/595741[1]

          作者:王圣松

          https://juejin.cn/post/6993676240603316231

          開始



          歡迎大家來到掘金小冊(cè)8月的首場(chǎng)直播,我是本次直播的主講人王圣松

          今天給大家?guī)淼闹黝}是:如何系統(tǒng)搭建CICD。話不多說,咱們就立刻開始

          自我介紹




          那么在開始之前呢,我先做個(gè)自我介紹。我叫 Janlay,目前任職于 Gitee Devops產(chǎn)品前端團(tuán)隊(duì),是一位前端開發(fā)工程師,主要負(fù)責(zé)參與團(tuán)隊(duì) Devops 產(chǎn)品的前端開發(fā)。曾經(jīng)主導(dǎo)過 CI/CD 相關(guān)產(chǎn)品的前端開發(fā),同時(shí)也是掘金小冊(cè)《從 0 到 1 實(shí)現(xiàn)一套 CI/CD 流程》的作者。


          現(xiàn)狀與困境




          在開始之前呢,我們先來聊一聊前端的CICD掌握現(xiàn)狀。


          現(xiàn)狀




          這是我在之前和其他的一個(gè)前端開發(fā)工程師的聊天??梢钥吹剑岸斯こ處煂?duì)于 CI/CD 的方向的興趣還是比較大的。但是也比較焦慮。并且有的大廠面試還會(huì)問到相關(guān)的問題,里面也有涉及 Kubernetes 相關(guān)的技術(shù)。

          那么大家對(duì)此的掌握度又如何呢?


          對(duì) 162 個(gè)前端 CI/CD 工具的掌握度調(diào)查




          我在去年寫小冊(cè)之前,對(duì) 162 個(gè)中高級(jí)前端做了個(gè)關(guān)于 CI/CD 工具的一個(gè)掌握調(diào)查。其中有一部分同學(xué)已經(jīng)在大廠,或者已經(jīng)是一個(gè)前端的一個(gè) leader 了。

          大家 Docker 的實(shí)踐程度以及掌握度是非常非常低的,兩成都不到只有19%。這其中對(duì)于 Kubernetes 的掌握程度甚至不到 1%。162 個(gè)人里面,僅僅只有一個(gè)人實(shí)踐過。

          對(duì)于制品庫這類比較新鮮的概念了解更少了,不了解的人有很多,自研的人也有一部分。構(gòu)建工具,部署工具,這些大家可能聽的比較多,常見的比較多,掌握程度還算好。但是也有相當(dāng)一部分同學(xué)對(duì)這部分還不是很清楚,或者說在采用手動(dòng)部署。其實(shí)不是很適應(yīng)時(shí)代發(fā)展和不利于提高效率的。

          Devops 工具鏈


          這個(gè)是某咨詢公司對(duì)于 Devops 工具鏈的一個(gè)統(tǒng)計(jì)圖譜。從全貌上來看呢,這些工具其實(shí)還是比較多的。除了持續(xù)構(gòu)建持續(xù)部署之外,還有像監(jiān)控運(yùn)維,自動(dòng)化測(cè)試,流程管理,容器編排這些內(nèi)容。

          代碼托管 Git 庫就有七種。CI 也不止 Jenkins,Gitlab CI 這幾個(gè)。里面還存在著其他的一些工具鏈,其實(shí)是比較多比較雜的,這些都是 CI/CD 相關(guān)的一個(gè)工具生態(tài)。有了這些工具生態(tài),我們才能夠?qū)I/CD的價(jià)值完全釋放出來。

          那么這樣看來,CICD只是作為自動(dòng)化工具。那么它的意義有多大呢


          為什么要有自動(dòng)化?




          那么為什么要自動(dòng)化呢?大家可能聽說過一個(gè)開發(fā)模式,叫做瀑布流。

          左上角就是瀑布流開發(fā)的方式。傳統(tǒng)瀑布流的開發(fā)方式是:把需求的排期給固定住,中間是不允許修改需求的,直到最后完全上線。測(cè)試的流程也是比較復(fù)雜的,上線流程也是比較復(fù)雜的。

          我們大家可以看到,在這個(gè)圖里面開發(fā)和測(cè)試之間隔著一堵墻,測(cè)試和運(yùn)維之間也隔著一堵墻。那么在所有的功能開發(fā)完畢之后才能交給測(cè)試,測(cè)試測(cè)完所有功能之后才能再交給運(yùn)維上線。那么這種開發(fā)模式在今天的互聯(lián)網(wǎng)時(shí)代的話,其實(shí)已經(jīng)嚴(yán)重脫節(jié)了。

          互聯(lián)網(wǎng)時(shí)代的產(chǎn)品需求變動(dòng)是很頻繁的,瀑布流是根本適應(yīng)不了的,所以就有了敏捷開發(fā)這么一種方式。將原有瀑布流的一大塊的需求,進(jìn)行了一個(gè)拆分,拆成了一個(gè)一個(gè)迭代。每個(gè)迭代里面,有這個(gè)迭代相關(guān)的需求,一次迭代的需求開發(fā)完畢之后,交給測(cè)試,原有的一個(gè)整個(gè)大的流程變成了一個(gè)小步快跑的方式。研發(fā)做一部分需求測(cè)試,測(cè)試就測(cè)一部分,上線就上一部分。產(chǎn)品在早期的話就可以得到一個(gè)市場(chǎng)的快速驗(yàn)證。

          當(dāng)然需求的頻繁變化,在當(dāng)今是迫不得已。因?yàn)闀r(shí)代發(fā)展是比較快的。如果要是說大家都能看到未來的市場(chǎng)走向和用戶需求的話,可能京東淘寶也不會(huì)允許拼多多存在。

          但是敏捷的劣勢(shì)隨即而來了。由于上線的流程不是自動(dòng)化且是比較復(fù)雜的,所以當(dāng)開發(fā)和測(cè)試完成了之后,需求依然要等到固定的時(shí)間去進(jìn)行上線。因?yàn)榘l(fā)布流程較多且復(fù)雜,還是無法把第一時(shí)間把需求統(tǒng)一驗(yàn)證,因?yàn)樽詣?dòng)化而這道門檻卡在了這里。

          于是 Devops 就來了,他把運(yùn)維和開發(fā)測(cè)試的墻也打破了。我們上線部署構(gòu)建的事情??梢匀?shí)現(xiàn)一個(gè)自動(dòng)上線,自動(dòng)構(gòu)建,自動(dòng)部署。這樣的話,我們發(fā)布的成本就變小了,產(chǎn)品發(fā)布的周期也加快了。上線的權(quán)利從運(yùn)維就轉(zhuǎn)變成了研發(fā),轉(zhuǎn)變?yōu)榱藰I(yè)務(wù)方。這也就是自動(dòng)化構(gòu)建部署的意義,它可以讓需求更快的投入市場(chǎng)驗(yàn)證。

          所以說,自動(dòng)化不僅是在研發(fā)層面提效,更可以影響業(yè)務(wù)的快速發(fā)展迭代。所以從研發(fā)同學(xué)角度來講,掌握自動(dòng)化構(gòu)建和部署比較吃香。


          演進(jìn)歷程



          在剛才,我們了解了自動(dòng)化在業(yè)務(wù)中的意義。接下來我們就看下 CI/CD 的演進(jìn)歷程,看下為了盡可能地自動(dòng)化,技術(shù)層面都是如何一步步演進(jìn)發(fā)展的


          遠(yuǎn)古時(shí)代 FTP + Tomcat / Nginx



          首先是遠(yuǎn)古時(shí)代的構(gòu)建部署。其實(shí)說早也不是很早,我在 18 年參加某次技術(shù)分享時(shí),與一位后端工程師有聊到這部分,他告訴我就是在使用 FTP 方式進(jìn)行部署。很多學(xué)校教材中甚至還會(huì)教學(xué)這部分。的確,在早期的網(wǎng)站部署中,F(xiàn)TP 的確比較常見。

          首先是在本地將代碼構(gòu)建。

          在 FTP 盛行的年代,Webpack 那個(gè)時(shí)候可能都沒有,可能只有幾個(gè) JQuery 頁面,或者是靜態(tài)頁面,將頁面文件直接扔到服務(wù)器。

          很多的做法都是和后端的代碼都放一塊兒。比如像 Tomcat、Apache。


          隨著時(shí)代的發(fā)展,F(xiàn)TP 的方式實(shí)在是太落后了。我之前有講到:產(chǎn)品需求需要快速投入市場(chǎng)驗(yàn)證,除了需求要進(jìn)行拆分之外,上線的流程也要做到自動(dòng)化,才能實(shí)現(xiàn)快速投入的市場(chǎng)的這么一個(gè)目標(biāo)。

          沒有自動(dòng)化的操作,風(fēng)險(xiǎn)也是比較大的。比如說有時(shí)候眼花沒有操作好、不小心誤觸、或者不小心刪除了文件,導(dǎo)致服務(wù)和系統(tǒng)出現(xiàn)問題。這種情況在歷史上發(fā)生了 n 多次。而且自動(dòng)化也解決了很多重復(fù)的一些人力。

          一個(gè)操作,機(jī)器可以自動(dòng)化去執(zhí)行,但人去執(zhí)行,這個(gè)對(duì)于成本而言就是一個(gè)浪費(fèi)。


          自動(dòng)化序章 Shell + Nginx



          于是人們對(duì)于自動(dòng)化最初的探索就是寫 Shell 腳本,可以通過編寫 Shell 腳本來實(shí)現(xiàn)自動(dòng)化操作。首先在腳本里面我們將代碼拉下來,這里面少了一步 git fetch 的命令,上面大家可以腦補(bǔ)一下哈哈。將代碼拉取下來之后,進(jìn)行一個(gè) npm run build,編譯之后扔到對(duì)應(yīng)的服務(wù)目錄。

          上圖這個(gè)就是有獨(dú)立部署服務(wù)器,我們可以考慮采用 SCP 的方式將編譯后的壓縮包扔到目標(biāo)服務(wù)器。使用 SSH 命令遠(yuǎn)程操控服務(wù)器進(jìn)行一個(gè)解壓。比如上面第10行: tar zxvf,將 tar 包解壓后,再 mv 移動(dòng)到對(duì)應(yīng)目錄。

          這就是我們對(duì)于自動(dòng)化最初的一個(gè)探索,那么在今天也有相當(dāng)一部分業(yè)務(wù)還是在使用這種方式。包括像我們之前的一些內(nèi)部的、一些小的業(yè)務(wù),也是在使用這些方式進(jìn)行部署。這也側(cè)面印證這部分方式的成本還是比較低的。


          那么,這方面成本是比較低的,而且不需要額外的服務(wù)依賴,不需要多么復(fù)雜的操作。也不需要多么復(fù)雜的架構(gòu)。

          但是隨著業(yè)務(wù)增長(zhǎng)和團(tuán)隊(duì)人數(shù)擴(kuò)張,就可能變得不是多么很友好。

          首先你可以在服務(wù)器上執(zhí)行這個(gè)腳本,就說明了你有服務(wù)器的權(quán)限。那么大家都想去構(gòu)建的話,密碼公鑰的泄密的風(fēng)險(xiǎn)就加大。人人都可以去訪問服務(wù)器,萬一有人想使壞刪庫跑路;或者說不小心刪除了某個(gè)文件,不小心誤操作導(dǎo)致了服務(wù)模塊,也是一個(gè)災(zāi)難性的問題。

          其次,他的操作交互也不是很友好。那么我們是不是可以利用軟件開發(fā)的一個(gè)思想,將這些真實(shí)的操作去做一個(gè)上層的封裝呢?提供給用戶一個(gè)統(tǒng)一的入口,用戶只能夠執(zhí)行你給的一個(gè)操作范圍,可以在界面上進(jìn)行一鍵執(zhí)行。


          于是像很多公司,選用了 Jenkins,這個(gè)是非常經(jīng)典的一個(gè)構(gòu)建工具,擁有像可視化操作。而且它是有賬號(hào)體系的,你可以根據(jù)賬號(hào)去分配權(quán)限。不同的人看到不同的任務(wù),可以去執(zhí)行不同的任務(wù)。當(dāng)然他也有豐富的插件也可以進(jìn)行一個(gè)拓展,比如說像 git plugin、node plugin。也有非常開放的 API,可以去做一個(gè)自定義拓展。


          可視化執(zhí)行 Jenkins + Nginx



          我們用進(jìn)行一個(gè)自動(dòng)化改造之后呢,一切看起來是比較美好的。在提前寫好 Shell 之后呢,我們一鍵執(zhí)行就可以完成你想執(zhí)行的腳本。

          甚至 Jenkins,還給你提供給你像定時(shí)執(zhí)行這樣的一個(gè)功能。你還可以去搭配 Git 平臺(tái)的 Webhook 鉤子,在你提交代碼,或者說合并某個(gè) pull request 的時(shí)候,Git 就會(huì)利用 Webhook,去調(diào)用你 Jenkins 的構(gòu)建觸發(fā)鏈接,對(duì)代碼進(jìn)行一個(gè)構(gòu)建觸發(fā)。

          大家可以看到上面兩張圖片:左上角就是 Shell 腳本的編寫區(qū)域,右邊就是編譯的一個(gè)日志,這些都是可以在網(wǎng)頁中進(jìn)行編寫和實(shí)現(xiàn)的。

          那么下面就是這個(gè)整體的流程。當(dāng)我們把代碼提交到倉庫時(shí),這時(shí)候打開 Jenkins,去點(diǎn)擊這樣的一個(gè)構(gòu)建按鈕,接著就構(gòu)建完成了?;蛘哒f我們直接 push 到倉庫,觸發(fā) Webhook 鉤子,最后直接構(gòu)建完成。這是更加便捷的一種方式。


          可是,有一天服務(wù)。不止你們自己用。例如現(xiàn)在很多公司在做 tob,你的服務(wù)不只是你自己在用,你要把你的服務(wù)拿到客戶那里進(jìn)行部署。

          在這種情況下,如果你的服務(wù)需要非常復(fù)雜的環(huán)境安裝的話,是比較頭疼的。尤其在客戶變多的情況下,安裝環(huán)境也是非常的費(fèi)時(shí)費(fèi)力的,甚至說還會(huì)遇到說操作系統(tǒng)不一致的問題。例如在你自己的開發(fā)環(huán)境上是 Ubuntu,到了客戶那里就變成了 CentOS,有些環(huán)境依賴的安裝方式是不兼容的。

          版本歸納也是一個(gè)大問題。尤其是每次版本包非常大,安裝部署都需要拉去特別重的安裝包,也非常費(fèi)時(shí)間。最理想的情況,是說我拿一個(gè)虛擬機(jī)一樣的東西,直接到客戶現(xiàn)場(chǎng)直接跑了起來。

          Docker 在這個(gè)地方就派上用場(chǎng)了。它可以將你的運(yùn)行環(huán)境、服務(wù)代碼等之類的東西高度集成為一個(gè)鏡像。在你想要的地方,如果那個(gè)地方有 Docker 運(yùn)行環(huán)境,我們可以將 Docker 鏡像跑起來,就擁有了全套的一個(gè)運(yùn)行環(huán)境體驗(yàn)。

          而且 Docker 的每個(gè)鏡像的更新都是增量的,只拿去拉取修改的那一部分,不需要每次都拉取全量的鏡像,也非常省空間省時(shí)省力。


          容器時(shí)代 Jenkins + Docker + Nexus + Nginx 容器



          于是我們將原有的服務(wù)用 Docker 鏡像跑了起來,然后構(gòu)建編譯構(gòu)建包變成了編譯鏡像。在這里還會(huì)引入一個(gè)新東西 —— 制品庫,右邊這張圖就是制品庫。我們將每次編譯后的產(chǎn)出都被稱為制品,存放這些制品的文件存儲(chǔ)系統(tǒng)就叫制品庫。

          右上角這張截圖是 Nexus 的一個(gè)制品庫。像Java也有自己的包規(guī)范 Maven、Node 的包規(guī)范 NPM、Docker 的鏡像,這些 Nexus 都可以去進(jìn)行一個(gè)創(chuàng)建和托管。所以對(duì)于一些中小團(tuán)隊(duì)而言,Nexus 還是比較萬能的,也是比較省成本的。有這么一套東西前后端都可以去用。

          于是流程就變成了:當(dāng)我們?nèi)?gòu)建鏡像的時(shí)候,構(gòu)建完畢,接著就會(huì)去 push 鏡像到鏡像庫。原有的構(gòu)建代碼變成構(gòu)建鏡像,push 到鏡像庫后告訴遠(yuǎn)程服務(wù)器你要拉取鏡像。

          像左邊這張圖最下面里面有一個(gè) SSH 命令:這時(shí)候它就會(huì)操作 151 服務(wù)器利用 Docker 命令將鏡像拉下來,然后將容器停止掉,刪掉,再跑一個(gè)新鏡像。那么這樣的話,我們的服務(wù)和它所需要的運(yùn)行環(huán)境是高度集成的,你不需要擔(dān)心去分發(fā),也不需要受到操作系統(tǒng)的一個(gè)影響。


          可是問題也來了。有一天用戶量變大了,你需要加服務(wù)器,一臺(tái)服務(wù)器不夠就要去加。最頭疼的莫過于我要批量對(duì)服務(wù)器進(jìn)行新版本更新,或者說要去加新服務(wù)器。如果我們加一臺(tái)還好,如果加 5 臺(tái)、加 10 臺(tái)呢?擴(kuò)展下去的話,總會(huì)變得無邊無際。

          我們需要一種通用的策略去解決問題,不僅可以批量操作這個(gè)服務(wù)器,更希望說在我們?nèi)ヌ砑舆@個(gè)服務(wù)器的時(shí)候,也可以去變得特別的便捷。就好像寫個(gè)配置文件一樣,寫個(gè)清單我們就可以寫一個(gè)操作。

          那么在這里有一個(gè)非常知名的工具叫 Ansible。Ansible 是紅帽推出的一個(gè)自動(dòng)化運(yùn)維工具,它可以去根據(jù)你提前預(yù)制好的服務(wù)器清單,對(duì)服務(wù)器進(jìn)行一個(gè)批量的操作和部署。

          你可以去像寫一個(gè)記事本一樣,寫一個(gè) yaml 文件,json 文件一樣去寫入:你的第一個(gè)服務(wù)器的 IP 多少,賬號(hào)密碼多少、第二個(gè)服務(wù)器賬號(hào)密碼是多少....這樣就形成了一個(gè)清單。把這個(gè)清單交給它后,他就會(huì)按照你清單上面寫好的賬號(hào)和密碼、服務(wù)器地址去對(duì)我們遠(yuǎn)程服務(wù)器去操作腳本執(zhí)行任務(wù)。

          本質(zhì)上還是一個(gè)自動(dòng)化一個(gè)運(yùn)維工具,它是可以自動(dòng)化幫你去執(zhí)行命令的一個(gè)工具,不僅僅是用來部署。包括像后面我們有提到說 Kubernetes 去安裝 Node 的時(shí)候,如果你的 Node 的機(jī)器比較多,都需要安裝環(huán)境的話,Ansible 是能夠派上用場(chǎng)的,用場(chǎng)還很大。而且這個(gè)是 Python 寫的,性能比較快一些。


          基于配置清單服務(wù)器批量操作 Ansible



          那么這個(gè)就是 Ansible 操作的 Playbook 腳本集。

          右邊這張圖大家可以看到:這是一個(gè)樣本文件,里面有一個(gè) task 字段。Ansible,他將你的腳本里面每一條要執(zhí)行的命令都產(chǎn)生了一條條 task。并且第一條 task,第二條 task 之間還可以去支持異步執(zhí)行,還可以支持錯(cuò)誤中斷。比如說我中間的執(zhí)行出錯(cuò)退出,我還可以去忽略這個(gè)錯(cuò)誤繼續(xù)執(zhí)行。

          整個(gè) Playbook 腳本集還可以根據(jù)變量去進(jìn)行一個(gè)實(shí)例化。比如我這個(gè)地方在用 timestamp 變量,上面可以通過 var 字段去定義一個(gè)是 timestamp,后面的 value 就是給它的變量默認(rèn)值。我在左邊去執(zhí)行 ansible-playbook 命令的時(shí)候,用 -e 這個(gè)參數(shù)就可以去把 timestamp 變量可以傳進(jìn)來,每次都會(huì)生成一個(gè)新的構(gòu)建的操作實(shí)例。

          那么在這種情況下,我們對(duì)原有的服務(wù)器替換鏡像,也變成了去操作 Ansible,讓 Ansible 去操作對(duì)應(yīng)的機(jī)器進(jìn)行一個(gè)鏡像的替換。那么大家可以看到:鏡像 push 到鏡像庫之后,接著去操作 Ansible 批量操作服務(wù)器,受控的服務(wù)器去拉取鏡像,然后再把原有的容器刪除掉,基于新版本運(yùn)行新容器。



          那么,Ansible 幫我們實(shí)現(xiàn)了批量操作服務(wù)器的夢(mèng)想,但是它的做法是比較生硬的,因?yàn)樗皇且粋€(gè)自動(dòng)化的運(yùn)維工具。

          我們運(yùn)行的是一個(gè)容器,有的時(shí)候可能會(huì)碰到說負(fù)載均衡需要配置 upstream,環(huán)境變量的情況。尤其像 toB,大家在做微前端,或者說服務(wù)之間有互相引用的地方,都少不了一系列的環(huán)境變量。比如這些 nginx upstream 的值其實(shí)都是不固定的。

          舉個(gè)例子,我現(xiàn)在有一個(gè)系統(tǒng),前端頁面我們要訪問 /user 的時(shí)候,要去訪問 /user 配置的機(jī)器;那么訪問 /a 的時(shí)候,要去訪問 /a 的容器。這個(gè)時(shí)候如果你只有自己用還好,假設(shè)到了客戶現(xiàn)場(chǎng)的話,客戶現(xiàn)場(chǎng)的環(huán)境是比較復(fù)雜的,你根本不知道他會(huì)用什么情況去部署。Nginx 的 upstream 那么在這種情況下,你把具體的值寫死,完全不利于后面的部署。這個(gè)值真正部署是不固定的,環(huán)境的網(wǎng)段和 DNS 都會(huì)去影響這個(gè)值。

          所以我們希望有一個(gè)給運(yùn)容器運(yùn)行的環(huán)境生態(tài),容器高度隔離的一個(gè)土壤。容器在自己的生態(tài)里面就能去解決這些繁雜的七七八八的一些問題。那么我們?cè)偃ソo客戶部署的時(shí)候,只需要帶著這一套環(huán)境生態(tài)去客戶那里部署,這個(gè)環(huán)境生態(tài)就可以去完美的去實(shí)現(xiàn) 1:1 的一個(gè)還原。

          其實(shí)在我們前面去更新容器的時(shí)候,都會(huì)將原有的容器刪掉,再創(chuàng)建新容器。中間的時(shí)間如果用戶去訪問,就是宕機(jī),服務(wù)沒有起來就訪問不到。這種情況下,其實(shí)相對(duì)而言還算是好一些的。如果連你的新版本的容器因?yàn)槌鲥e(cuò)都沒有起來,那么你這個(gè)時(shí)候問題就大了,就算是一個(gè)事故了?;貪L也是一個(gè)比較麻煩的事情。

          所以說我們希望服務(wù)發(fā)布的時(shí)候不要停機(jī)。新發(fā)布失敗了,還可以自動(dòng)終止新版本發(fā)布,回滾到舊版本。

          在保證上面的一個(gè)運(yùn)行生態(tài)的時(shí)候,還希望去做一個(gè)最大化的機(jī)器資源利用。比如說我們有多套環(huán)境,而且之間都是隔離的,互相不受影響。例如我們?nèi)粘i_發(fā)有測(cè)試環(huán)境,開發(fā)環(huán)境。希望服務(wù)器資源利用最大化,一組高配置的服務(wù)器就可以去部署解決這兩套環(huán)境。

          我們希望去達(dá)到這樣一種理想的狀態(tài)。在這種情況下,選擇了 Kubernetes,簡(jiǎn)稱 k8s。

          Kubernetes 是一個(gè)容器編排工具,他給你容器提供一個(gè)很好的環(huán)境生態(tài),就像提供一個(gè)完整的家一樣,所以說它叫容器編排工具。在 Kubernetes 里面是以它去管理你要運(yùn)行容器的服務(wù)器,是以集群的方式去管理的。你的每一臺(tái)服務(wù)器都是一個(gè)節(jié)點(diǎn),它可以根據(jù)你集群內(nèi)的節(jié)點(diǎn)的一個(gè)剩余資源,還有你人工給他的標(biāo)簽等影響因素,對(duì)服務(wù)的部署進(jìn)行了自動(dòng)的調(diào)度,最大化的利用我們的服務(wù)器資源。

          對(duì)于應(yīng)用更新,也可以采用滾動(dòng)發(fā)布服務(wù)的方式,在發(fā)布期間不會(huì)影響新版和舊版的一個(gè)訪問,也就是說不會(huì)宕機(jī)。這個(gè)技術(shù)也是比較熱門的,現(xiàn)在很多公司大廠也是在用。


          容器集群編排 Jenkins + K8S + Docker + Nginx



          那么左上角就是 k8s 運(yùn)行時(shí)的情況。左上角圖是滾動(dòng)發(fā)布,可以看到,k8s 在啟動(dòng)一個(gè)全新的容器之后,他會(huì)確保說新容器沒有問題有待殺死原有的一個(gè)容器。這樣保證了一個(gè)可訪問性,保證不會(huì)因?yàn)榉?wù)重啟而導(dǎo)致宕機(jī)。

          左下角圖是 k8s 加入一個(gè)新節(jié)點(diǎn)的方式??梢钥吹?,只需要通過 API 操作一個(gè)遠(yuǎn)程訪問,就可以加入集群,而且都是服務(wù)化。基于密鑰、IP、端口加入就可以。它和集群內(nèi)的其他節(jié)點(diǎn)和集群內(nèi)的主控制節(jié)點(diǎn)其實(shí)都是解耦的。想刪除就刪除,想添加就添加,只是把它當(dāng)成了一個(gè)服務(wù)。

          右邊是 k8s 集成后的一個(gè)流程圖。從最下面可以看到,當(dāng)用戶提交代碼到 Git 了之后,這時(shí)候會(huì)去觸發(fā) Webhook?;蛘吣闶謩?dòng)去觸發(fā) Jenkins。這時(shí)候 Jenkins 就構(gòu)建鏡像,上傳鏡像到了制品庫,接著去調(diào)用了 k8s 集群進(jìn)行一個(gè)制品的部署。

          這時(shí)候告訴 k8s:我的鏡像版本更新了,給你新版本的鏡像地址。這時(shí)候 k8s 就把鏡像版本在配置文件中進(jìn)行一個(gè)修改。這個(gè)時(shí)候就會(huì)拿新版本去鏡像庫拉取新鏡像,拉取之后就會(huì)對(duì)原有的 pod 進(jìn)行刪除替換。

          你可以大致理解為,pod 約等于一個(gè)容器,但是它其實(shí)不等于容器。k8 s當(dāng)中的 pod 不只是擁有容器的這個(gè)概念,它里面還可以擁有多個(gè)容器,他也是 k8s 當(dāng)中可調(diào)度的一個(gè)最小節(jié)點(diǎn),也擁有網(wǎng)絡(luò)的分配權(quán)限,所以它不等于一個(gè)容器。

          可以看到滾動(dòng)升級(jí)的策略。左邊這個(gè)圖原有是 4 個(gè)藍(lán)色的 pod,我們先把其中 1 個(gè)藍(lán)色的給下掉,那么下來之后把新的給創(chuàng)建進(jìn)來,ok 完成;然后剩下三個(gè),再把其中一個(gè)給干掉,再上一個(gè)新的;再剩下兩個(gè)再把其中一個(gè)干掉,再上新的,最后完成全部的部署,這就是滾動(dòng)發(fā)布的這么一個(gè)方式。

          升級(jí)完畢之后,k8s 當(dāng)中還帶來了一種概念 ingress,這個(gè)有點(diǎn)類似于 Nginx 的負(fù)載均衡。大家可以看到這張圖,瀏覽器去訪問的時(shí)候,經(jīng)過一堆轉(zhuǎn)發(fā),走到了 k8s 集群;k8s 集群進(jìn)來之后,首先是走到了 ingress。根據(jù)路徑左邊是 path = /,然后去根據(jù)路徑走到了 service。右邊這個(gè)不僅有 path = /,還有灰度的 cookie。說明他是灰度用戶,給他了灰度的一個(gè)服務(wù)的訪問。ingress 的作用就是在這里,他可以去做灰度發(fā)布,也可以做 path 轉(zhuǎn)發(fā)。

          k8s 就給容器去提供了這么一個(gè)完整的運(yùn)行生態(tài)。國(guó)內(nèi)大廠基本上都有在使用 k8s 包括像 serverless,也有的通過 k8s 進(jìn)行一個(gè)底層實(shí)現(xiàn)。這種編排方式比較省時(shí)省力省心的。


          當(dāng)然 k8s 也不是最好的解決方案。未來 Serverless 的部署會(huì)更加便捷。

          例如左下角的彈性伸縮,按需付費(fèi)。我們現(xiàn)有k8s的 Node 節(jié)點(diǎn)還是需要去手動(dòng)加入、手動(dòng)刪除。它并不能根據(jù)你的服務(wù)的流量情況對(duì)節(jié)點(diǎn)進(jìn)行一個(gè)自動(dòng)的增加伸縮。不過在 Serverless 里是可以做到的,因?yàn)檎嬲膶?duì)物理資源進(jìn)行一個(gè)伸縮的時(shí)候,這個(gè)時(shí)候才會(huì)真正達(dá)到省錢的目的。無服務(wù)器的函數(shù)計(jì)算,也應(yīng)對(duì)了一部分的一個(gè)無狀態(tài)的操作和服務(wù),也是比較省錢且快速方便的。當(dāng)然,他的基礎(chǔ)也是Docker

          國(guó)內(nèi)的云服務(wù)器廠商也對(duì)一些常用的前后端框架進(jìn)行了一個(gè)快速部署的支持。比如像 Next.js、Koa.js、Egg.js 這些都支持實(shí)現(xiàn)一個(gè)常用框架的快速部署。部署起來會(huì)更加的方便。


          回到開始



          以上是我們的一個(gè)演進(jìn)流程。可以看到,前人為了提升工程效能,想盡了一切辦法來優(yōu)化提升。

          接著讓我們回到主題:為什么要用自動(dòng)化?

          自動(dòng)化不是為了偷懶,也不是為了做而做,更不是為了刷KPI/OKR。而是為了讓產(chǎn)品和需求可以更快速上線驗(yàn)證,更加早期地分析用戶信息,需求更加匹配用戶。那么這就是我們要做自動(dòng)化的一個(gè)目標(biāo)。


          現(xiàn)實(shí)很殘酷



          現(xiàn)實(shí)是比較殘酷的。上線實(shí)現(xiàn)了自動(dòng)化,然而需求從開發(fā)到上線的時(shí)間絲毫沒有一點(diǎn)影響。那么這時(shí)候你就要考慮:像測(cè)試的時(shí)間占了多少?有沒有大量的人工測(cè)試?

          無法打通上線的最后一公里,就像比較經(jīng)典的小程序。小程序的上線就不同于以往的開發(fā)上線,最后一公里怎么打通?

          投入和產(chǎn)出不成正比,本來你的業(yè)務(wù)不是多么很熱門的業(yè)務(wù),一個(gè)月部署不了幾次,還有必要去做 CI/CD 嗎?它的意義有多大呢?

          對(duì)于一些特殊的場(chǎng)景,目前的開源工具依然沒法去打通這么一個(gè)構(gòu)建。最后一公里還是要去手動(dòng)操作。而且自動(dòng)化做了,影響有時(shí)候也是不大。所以我們就要根據(jù)業(yè)務(wù)進(jìn)行一個(gè)對(duì)癥下藥,選擇合適的工具進(jìn)行一個(gè)改造,包括像不限于對(duì)現(xiàn)有的工具進(jìn)行拓展,或者說可以考慮到自研。


          做平臺(tái),而不是做工具



          那么還是那句話,做平臺(tái)而不是做工具。我分別來舉個(gè)例子,像 IDE 集成:就小程序 ide 支持的一鍵發(fā)布,就是一個(gè)很好的例子。它把 IDE 和 CI/CD 進(jìn)行了一個(gè)聯(lián)動(dòng),包括像很多大廠也在研發(fā) WebIDE,也是出于這方面的一個(gè)考慮。還有我們?nèi)粘H蝿?wù)卡片進(jìn)行一個(gè)關(guān)聯(lián)和綁定,可以更好的追蹤需求的開發(fā)情況。

          像自動(dòng)化測(cè)試:我們的上線時(shí)間有縮短,但是測(cè)試時(shí)間沒有變短。大量的人工測(cè)試還是比較浪費(fèi)成本的,這個(gè)我們也可以考慮去優(yōu)化;

          根據(jù)不同用戶的灰度發(fā)布的一個(gè)策略:比如說基于用戶畫像的地域,基于其他的一些因素進(jìn)行灰度發(fā)布;還有像服務(wù)的一個(gè)監(jiān)控,告警。

          像數(shù)據(jù)度量平臺(tái):比如我們可以統(tǒng)計(jì)構(gòu)建時(shí)長(zhǎng)、發(fā)布時(shí)長(zhǎng)等等,為了更好地去做優(yōu)化。甚至非常 nice 的流程可視化的拖動(dòng):CI/CD 的流程編排現(xiàn)在也是比較火的。這些都是說 CI/CD 去適應(yīng)業(yè)務(wù)的一些例子。

          工具是一個(gè)比較抽象的平臺(tái),但業(yè)務(wù)場(chǎng)景是復(fù)雜多變的,我們需要使用工具去演變成自己的平臺(tái)。之前我們所說的  Docker、Jenkins、Nexus、Kubernetes 都有自己的 OpenAPI,你完全可以根據(jù)自己的業(yè)務(wù)需求進(jìn)行一個(gè)自定義的封裝。


          持續(xù)精進(jìn)




          那么總結(jié)一下:自動(dòng)化是解決問題的手段,而不是一個(gè)結(jié)果;適當(dāng)?shù)娜プ鰯?shù)據(jù)度量統(tǒng)計(jì),可以更好的幫助你去對(duì)流程的一個(gè)改進(jìn);要選擇自己合適的工具去做自動(dòng)化。


          Q&A



          接下來是問答:

          移步至錄播:https://live.juejin.cn/4354/595741[2] 39分53秒


          小冊(cè)推廣


          然后在這里推廣一下我寫的小冊(cè)。傳送門:https://juejin.cn/book/6897616008173846543[3]



          推薦書籍


          這里推薦兩本書。

          第一本是 k8s 的進(jìn)階實(shí)戰(zhàn),個(gè)人在查閱相關(guān)知識(shí)點(diǎn)的時(shí)候經(jīng)常用,不過官網(wǎng)的文檔還要看的

          第二本是《Devops 實(shí)驗(yàn)指南》,對(duì)于你的一些自動(dòng)化的流程的建設(shè),Devops 文化的建設(shè),度量平臺(tái)建設(shè)也是非常有幫助的。


          推薦平臺(tái) & 項(xiàng)目



          這是一個(gè)推薦參考的平臺(tái)和項(xiàng)目。這里沒有打廣告,大家如果有自研興趣需求的話,可以參考上面這些平臺(tái)的功能設(shè)計(jì)。

          第一個(gè)是華為云的 DevCloud。個(gè)人感覺他們的 CI/CD 方面做的還比較全的,包括像 CI/CD 可視化拖拽,還支持流水線的中斷執(zhí)行。我們一條條的任務(wù)就可以去組成一個(gè)流水線,就像工廠流水線一樣。流水線里面的 task 還可以支持并行執(zhí)行。

          第二個(gè)百度效率云。這個(gè)維護(hù)的頻率比較低,它們的特點(diǎn)是研發(fā)數(shù)據(jù)鏈。比如提交代碼時(shí)候,commit 的 message 填入卡片 ID,這時(shí)候在卡片里面可以監(jiān)控到,需求的代碼已經(jīng)提交到代碼庫里面了。接下來進(jìn)行構(gòu)建的時(shí)候,也會(huì)去和需求卡片進(jìn)行一個(gè)綁定。業(yè)務(wù)方就可以去清楚的看到需求的一個(gè)開發(fā)和上線的一個(gè)狀態(tài)與進(jìn)度。一個(gè)卡片就可以去串聯(lián)所有的進(jìn)度狀態(tài)。

          第三個(gè) KubeSphere 是針對(duì)于 k8s 的一個(gè)集群管理。包括對(duì) k8s 的服務(wù)監(jiān)控,CI/CD 的編排。這個(gè)是開源的,也是國(guó)產(chǎn)的。


          Thanks



          我的分享就到這里,感謝大家!


          參考資料

          [1]

          https://live.juejin.cn/4354/595741: https://live.juejin.cn/4354/595741

          [2]

          https://live.juejin.cn/4354/595741: https://live.juejin.cn/4354/595741

          [3]

          https://juejin.cn/book/6897616008173846543: https://juejin.cn/book/6897616008173846543


          瀏覽 64
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  永久免费无码中文字幕 | 国产AV 无码 乱噜噜 | 狠狠亲狠狠操 | 国产亲子乱淫一级a片 | 久久黄色樱桃视频 |