真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

構(gòu)建制品不一致,后續(xù)工作都是白費(fèi) | 研發(fā)效能提升36計(jì)

成都創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的汕尾網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

專欄策劃|雅純

志愿編輯|馮朝凱、橙蜂


之前我們舉了《集裝箱改變世界》(作者:馬克.萊文森)中的一個(gè)例子,書(shū)中提到上世紀(jì)五六十年代,集裝箱的使用,使得整體貨運(yùn)成本降低了95%,大部分的碼頭工人都面臨著失業(yè)。

這件事情看起來(lái)很簡(jiǎn)單,但卻給經(jīng)濟(jì)全球化帶來(lái)了非常大的影響。后面美國(guó)企業(yè)的訂單可以下到中國(guó)、以及中國(guó)成為“世界工廠”,都與之有很大的關(guān)系。集裝箱的背后是標(biāo)準(zhǔn)化和基于統(tǒng)一標(biāo)準(zhǔn)的產(chǎn)業(yè)鏈,這里有兩點(diǎn)比較重要的,一個(gè)是標(biāo)準(zhǔn)化,另外一個(gè)是不可變。

那么,在軟件開(kāi)發(fā)的過(guò)程中,我們?cè)鯓硬拍芟硎墚a(chǎn)業(yè)生態(tài)的紅利,實(shí)現(xiàn)軟件交付過(guò)程的標(biāo)準(zhǔn)化呢?軟件交付當(dāng)中的集裝箱應(yīng)該是什么樣的?

如何保證軟件交付過(guò)程的標(biāo)準(zhǔn)化

近十幾年,軟件交付形態(tài)發(fā)生了很大的變化,從最開(kāi)始買物理機(jī)、建機(jī)房到虛擬機(jī)再到現(xiàn)在的容器。這中間為什么會(huì)產(chǎn)生這樣的變化呢?

容器本身的底層技術(shù)是namespace和cgroup,然而這兩個(gè)東西在十幾二十年前就出現(xiàn)了。最早應(yīng)用這些技術(shù)的是對(duì)資源利用率和隔離有明確訴求的云廠商,比如說(shuō)阿里云不希望跑在機(jī)器上不同用戶的東西互相串,最好的辦法就是能限制每個(gè)用戶的資源,如CPU、內(nèi)存等。有了這個(gè)訴求,就會(huì)用LXC等方式去隔離,去限制資源。但是這還是沒(méi)有產(chǎn)生容器。為什么呢?問(wèn)題是各個(gè)云廠商只能在自己內(nèi)部做,但是不能對(duì)外分發(fā)。所以Docker的偉大之處并不是在底層做了多大地創(chuàng)新,而是提供了一個(gè)可以對(duì)外分發(fā)的容器鏡像。

容器鏡像是一個(gè)分發(fā)的形式,我們可以把容器鏡像分發(fā)給別人,或者是讓別人繼承我們的鏡像。同時(shí)Docker又提供了Dockerfile。Dockerfile允許我們通過(guò)一個(gè)文件的形式去描述鏡像。一旦能夠定義鏡像就可以協(xié)作了。有了這樣的能力以后,容器就很快被大家所接受了。所以容器的接受看起來(lái)好像是技術(shù)發(fā)展的過(guò)程,其實(shí)是隨著云原生、云市場(chǎng)的發(fā)展必然帶來(lái)的結(jié)果。

我們很多人認(rèn)為的“集裝箱”就是容器,這個(gè)容器很多時(shí)候我們都認(rèn)為是docker容器。在K8s里面支持很多個(gè)容器運(yùn)行,大部分的情況都是用docker容器。docker容器的優(yōu)勢(shì)就是剛才說(shuō)的兩點(diǎn):鏡像和Dockerfile。這兩點(diǎn)使得docker鏡像可以像集裝箱一樣做分發(fā)。

此外,容器還提供了很好的資源隔離,可以在比較小的粒度上進(jìn)行隔離。虛擬機(jī)雖然也做了隔離,但是它的粒度比較大。不僅如此,容器還提供了非常彈性的資源管理方式,這點(diǎn)比虛擬機(jī)和物理機(jī)都有非常大的改善。本質(zhì)上它就是物理機(jī)上的一個(gè)進(jìn)程,這是它和虛擬機(jī)的本質(zhì)的差別。

了解了軟件集裝箱是什么后,然后我們?cè)賮?lái)了解下容器鏡像的組成。

如上圖所示,這張圖非常形象地展示了容器鏡像的內(nèi)部結(jié)構(gòu)。當(dāng)我們自己執(zhí)行dockerbuild構(gòu)建鏡像的時(shí)候,你會(huì)發(fā)現(xiàn)它出來(lái)的日志有很多hash值,一層一層的。實(shí)際上它是由很多層組成的,我們通過(guò)LXC或者其他的技術(shù),把容器的進(jìn)程創(chuàng)建出來(lái),這個(gè)進(jìn)程通過(guò)namespace和cqroup做了資源隔離和限制。容器鏡像都有一個(gè)BaseImage,我們知道運(yùn)行一個(gè)程序,對(duì)操作系統(tǒng)的環(huán)境是要求的,比如依賴的library等。這個(gè)程序如果隨便在一臺(tái)物理機(jī)和虛擬機(jī)部署,會(huì)隨著機(jī)器的環(huán)境不同而不同,有可能導(dǎo)致風(fēng)險(xiǎn)。所以容器鏡像給了一個(gè)基本鏡像,把這個(gè)東西放里面了。再往上是Addemacs和Addapache,這兩層我們會(huì)在Dockerfile中去寫(xiě)。然后最上面的是Writable,就是我們?cè)谌萜鰿ontainer運(yùn)行的時(shí)候真正可以去寫(xiě)的東西。

那么容器鏡像的特點(diǎn)是什么呢?它是分層的,每一層都是可以復(fù)用的,我們?cè)谀硞€(gè)機(jī)器上有很多個(gè)容器,如果Base鏡像一樣,只要下一次就行了??梢钥吹界R像的大小是所有的層堆起來(lái)的,堆的東西越少,這個(gè)鏡像就會(huì)越小。容器鏡像有一個(gè)最小的鏡像叫scratch,就是一個(gè)最原始的基礎(chǔ)鏡像。這里面幾乎什么都沒(méi)有,基于它構(gòu)建一個(gè)非常非常小的容器的話,可能就是幾兆的大小。但是如果你基于CentOS基礎(chǔ)鏡像可能就是上G的大小。

容器鏡像有一個(gè)非常重要的概念叫“One process per container”(容器生命周期=進(jìn)程生命周期)。我們可以認(rèn)為容器就是K8s上的一個(gè)進(jìn)程,如果把K8s比作操作系統(tǒng),那么容器就是它上面運(yùn)行的一個(gè)進(jìn)程。進(jìn)程的生命周期是可以被管理的。雖然容器有這么多的優(yōu)點(diǎn),但實(shí)際在用的時(shí)候也會(huì)遇到很多的問(wèn)題。

下面我們聊一聊容器鏡像的一些常見(jiàn)的問(wèn)題和建議。

容器鏡像常見(jiàn)問(wèn)題及實(shí)踐建議

容器鏡像常見(jiàn)的問(wèn)題:

  • 把所有的東西都裝到一個(gè)容器里面,把容器當(dāng)虛擬機(jī)來(lái)用。
  • 把ENTRYPOINT設(shè)置為systemd:systemd管理的進(jìn)程運(yùn)行的結(jié)果和狀態(tài)和的容器狀態(tài)是不一致的,有可能里面的進(jìn)程已經(jīng)僵死了,或者Crash了,但是systemd還活著,從外部看起來(lái)這個(gè)容器沒(méi)問(wèn)題。
  • 私有化部署的時(shí)候帶一堆導(dǎo)出的鏡像tar包。tar包是不分層的,它不知道里面是有很多層。
  • 每次把基礎(chǔ)鏡像下發(fā)到整個(gè)集群,導(dǎo)致網(wǎng)絡(luò)變得特別擁堵

我們的實(shí)踐建議是:

  • 盡量采用輕量的基礎(chǔ)鏡像和確定的鏡像版本。
  • 通過(guò)分層來(lái)復(fù)用鏡像內(nèi)容,避免重復(fù)拉取。
  • 避免采用systemd,包括supervisord和類似這樣的daemon管理服務(wù)來(lái)做ENTRYPOINT。
  • 采用本地的dockerregistry等以層為粒度來(lái)離線拷貝鏡像。
  • 避免同時(shí)要做大量的pull,可采用P2P的方式(如使用dragonfly)提升鏡像分發(fā)效率。

容器鏡像可以實(shí)現(xiàn)軟件交付過(guò)程的標(biāo)準(zhǔn)化。標(biāo)準(zhǔn)化是手段不是目的,標(biāo)準(zhǔn)化是幫助我們更高效的復(fù)用的技術(shù)。

回到軟件交付的終態(tài),我們的目的是希望提供一個(gè)穩(wěn)定可預(yù)期的系統(tǒng)。

而達(dá)成這個(gè)目標(biāo)的前提是,要有確定的運(yùn)行環(huán)境和軟件制品。確定的環(huán)境是指代碼(及其依賴)、構(gòu)建環(huán)境、構(gòu)建腳本與預(yù)期一致的產(chǎn)出軟件制品,這一點(diǎn)如何做到我們后面再作分享。我們先看如何保證軟件制品的一致性。

如何保證軟件制品的一致性

要保證軟件制品的一致性,軟件制品應(yīng)該有確定的格式、唯一的版本、能夠追溯到源碼、能夠追溯到生產(chǎn)和消費(fèi)過(guò)程,這樣才能使持續(xù)交付更好地服務(wù)于企業(yè)的制品管理與開(kāi)發(fā)。

在制品構(gòu)建過(guò)程中,經(jīng)常會(huì)遇到一些問(wèn)題。例如應(yīng)用的代碼庫(kù)里沒(méi)有Makefile,package.json,go.mod而沒(méi)法確定依賴,或者制品能構(gòu)建成功但缺失幾個(gè)依賴,又或是在自己的開(kāi)發(fā)環(huán)境運(yùn)行正常而在生產(chǎn)環(huán)境出現(xiàn)了開(kāi)發(fā)環(huán)境沒(méi)有的bug。導(dǎo)致這些問(wèn)題出現(xiàn)的原因是因?yàn)闃?gòu)建本身是可變的,當(dāng)你構(gòu)建可變時(shí),就會(huì)帶來(lái)一系列的問(wèn)題。為此,我們需要通過(guò)不可變構(gòu)建來(lái)使制品與預(yù)期一致。

要實(shí)現(xiàn)不可變構(gòu)建,我們需要保證有:

  • 相同的代碼
  • 相同的構(gòu)建環(huán)境
  • 相同的構(gòu)建腳本

相同的代碼

例如程序員開(kāi)發(fā)時(shí),不在依賴描述文件(如go.mod,package-lock.json,pom.xml,requirements.txt等)中指定依賴的版本,則會(huì)默認(rèn)使用最新的版本作為依賴,這樣產(chǎn)出的制品會(huì)隨著依賴的更新而不能保持一致,這將帶來(lái)完全不在預(yù)期內(nèi)的風(fēng)險(xiǎn)。

相同的構(gòu)建環(huán)境

對(duì)于構(gòu)建環(huán)境來(lái)說(shuō),Dockerfile可以用來(lái)在容器平臺(tái)下描述環(huán)境,通過(guò)Dockerfile我們能為制品使用一致的環(huán)境。很多時(shí)候我們并不需要在運(yùn)行中使用構(gòu)建環(huán)境的很多依賴,而構(gòu)建鏡像的體積往往比較驚人,這個(gè)時(shí)候我們就需要將構(gòu)建環(huán)境與運(yùn)行環(huán)境分開(kāi),以得到盡可能輕量的鏡像制品。

相同的構(gòu)建腳本

對(duì)應(yīng)的,使用相同的,與代碼實(shí)現(xiàn)無(wú)關(guān)的構(gòu)建腳本也是非常重要的,在Dockerfile的環(huán)境中必須指定確定的環(huán)境依賴版本。

只有在同一份代碼(及同一個(gè)依賴)、同樣構(gòu)建環(huán)境的描述、和同樣構(gòu)建腳本的環(huán)境下,所產(chǎn)生的軟件制品才是相同的。這里強(qiáng)調(diào)的是說(shuō)所有的東西都要保證一致性,如果說(shuō)三者是一樣的話,那產(chǎn)生出來(lái)的制品也是一樣的,即使構(gòu)建時(shí)間不同,產(chǎn)出的制品也是相同的。

做好不可變基礎(chǔ)設(shè)施,首先要標(biāo)準(zhǔn)化最終交付制品的形態(tài),并且明確此交付形態(tài)的運(yùn)維管理方式。而要保證不可變,那首先要做好不可變的構(gòu)建,然后才能有一致的軟件制品。

NOTE:構(gòu)建準(zhǔn)確性,永遠(yuǎn)比構(gòu)建更快重要。制品的構(gòu)建信息不準(zhǔn)確,導(dǎo)致構(gòu)建制品不一致、版本不可控,所有后續(xù)的工作都是浪費(fèi)。

如何提升構(gòu)建效率

在構(gòu)建這塊,一個(gè)需要關(guān)注的點(diǎn)的是如何提升構(gòu)建效率。我們先看一個(gè)簡(jiǎn)單的計(jì)算問(wèn)題:

這是一個(gè)非常大的數(shù)據(jù),也是非常大的損耗。很多時(shí)候一個(gè)項(xiàng)目的工程效率太低的原因就是因?yàn)闃?gòu)建太慢。構(gòu)建耗時(shí)過(guò)長(zhǎng)使得制品迭代非常慢,功能更新和bug修復(fù)也會(huì)受到影響。

那我們?nèi)绾翁嵘龢?gòu)建的效率呢?下面是我們的一些實(shí)踐建議:

1個(gè)基本原則:保證構(gòu)建的準(zhǔn)確性,構(gòu)建的準(zhǔn)確性永遠(yuǎn)優(yōu)于構(gòu)建的效率。只有在保證準(zhǔn)確性的前提下提升效率才有意義。

5點(diǎn)建議

  • 應(yīng)用瘦身:檢查應(yīng)用的依賴情況,應(yīng)用包體積是否過(guò)大,依賴項(xiàng)是否過(guò)多,能否去除不必要的依賴,能否構(gòu)建更小的鏡像。
  • 分層構(gòu)建:底層的東西先構(gòu)建出來(lái)以后被上層所復(fù)用,然后就可以做增量式的了。
  • 構(gòu)建緩存:構(gòu)建過(guò)程中拉取依賴是很耗時(shí)的,要避免重復(fù)拉取。
  • 網(wǎng)絡(luò)優(yōu)化:主要是保證代碼、構(gòu)建機(jī)器和制品庫(kù)之間的低網(wǎng)絡(luò)延時(shí)。代碼和構(gòu)建機(jī)器是否是在同一個(gè)低時(shí)延鏈路中。例如代碼在Github上而使用云效構(gòu)建,此時(shí)的延時(shí)相對(duì)于內(nèi)網(wǎng)會(huì)高出許多。
  • 倉(cāng)庫(kù)鏡像:倉(cāng)庫(kù)鏡像可以極大地減少拉取依賴項(xiàng)的時(shí)間。在國(guó)內(nèi)的網(wǎng)絡(luò)環(huán)境下,如果從源倉(cāng)庫(kù)獲取依賴,可能延時(shí)會(huì)非常長(zhǎng),這時(shí)可以使用鏡像網(wǎng)絡(luò)降低延時(shí)。例如nodejs開(kāi)發(fā)者常使用淘寶的npm鏡像源,而Python開(kāi)發(fā)者使用清華的鏡像源。對(duì)于企業(yè)來(lái)說(shuō)也可以構(gòu)建自己的鏡像倉(cāng)庫(kù)以提升可靠性與降低延時(shí)。云效也使用了鏡像倉(cāng)庫(kù),來(lái)減少拉取的時(shí)間。
(小編推薦:云效流水線Flow 是一款云原生時(shí)代的流水線工具,通過(guò)容器技術(shù)讓企業(yè)擺脫對(duì)虛擬機(jī)構(gòu)建環(huán)境的依賴。您甚至可以根據(jù)您的使用需求,在同一條流水線上使用不同的構(gòu)建環(huán)境。此外,云效流水線Flow 還提供了各種語(yǔ)言的容器環(huán)境,滿足不同的構(gòu)建使用場(chǎng)景。點(diǎn)擊文末閱讀原文,了解詳情)

總結(jié)

本篇文章,我們從軟件交付的終態(tài)出發(fā),提出了不可變構(gòu)建的概念。希望通過(guò):相同的源碼+相同的環(huán)境+相同的構(gòu)建腳本=>帶來(lái)一致的軟件制品。而這些東西都是保存在源代碼里的,所以源代碼的管理非常重要。

下篇文章,我們將分享如何對(duì)源代碼進(jìn)行有效管理。

閱讀上篇:做到這4點(diǎn),才是真正的持續(xù)交付

點(diǎn)擊下方鏈接立即體驗(yàn)云效持續(xù)交付流水線Flow。

https://www.aliyun.com/product/yunxiao/flow?channel=yy_rccb_36

關(guān)于我們

了解更多關(guān)于云效DevOps的最新動(dòng)態(tài),可微信搜索并關(guān)注【云效】公眾號(hào);

福利:公眾號(hào)后臺(tái)回復(fù)【研發(fā)效能】,可獲得精品課程【阿里巴巴研發(fā)效能提升36計(jì)】

ps:本課程將從研發(fā)效能的定義和度量著手,逐漸深入解析來(lái)自不同業(yè)務(wù)部門提升持續(xù)交付能力的實(shí)踐、方法和工具,同時(shí)還將分享如何基于持續(xù)交付能力,切實(shí)提升產(chǎn)品和業(yè)務(wù)創(chuàng)新的效率和效果。

看完覺(jué)得對(duì)您有所幫助別忘記點(diǎn)贊、收藏和關(guān)注呦;


當(dāng)前文章:構(gòu)建制品不一致,后續(xù)工作都是白費(fèi) | 研發(fā)效能提升36計(jì)
本文URL:http://weahome.cn/article/dscggid.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部