自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Docker 持續(xù)集成過(guò)程中的性能問(wèn)題及解決方法

云計(jì)算
本文通過(guò)對(duì)目前常見(jiàn)的利用docker做持續(xù)部署的流程中的時(shí)間消耗分析,剖析在使用docker 搭建流水線之后沒(méi)有直接本地開(kāi)發(fā)測(cè)試效率高的原因、在此過(guò)程中出現(xiàn)的問(wèn)題及解決辦法。

Docker 的出現(xiàn)使開(kāi)發(fā)測(cè)試生產(chǎn)環(huán)境的統(tǒng)一變得更加容易,然而在使用 docker 搭建這一整套流水線之后,卻發(fā)現(xiàn)它運(yùn)行的卻不能像絲般潤(rùn)滑,總是感覺(jué)沒(méi)有直接本地開(kāi)發(fā)測(cè)試來(lái)的效率高。為了能達(dá)到一個(gè)高效流水般的持續(xù)構(gòu)建,我們來(lái)看一下這個(gè)過(guò)程中 docker 的使用以及 docker 自身存在著哪些問(wèn)題,我們又該如何克服這些問(wèn)題,達(dá)到如絲般的潤(rùn)滑。

我們首先來(lái)分解一下現(xiàn)在常見(jiàn)的一種利用 docker 做持續(xù)部署的流程:

  • 開(kāi)發(fā)者提交代碼
  • 觸發(fā)鏡像構(gòu)建
  • 構(gòu)建鏡像上傳至私有倉(cāng)庫(kù)
  • 鏡像下載至執(zhí)行機(jī)器
  • 鏡像運(yùn)行

在這五步中,1 和 5 的耗時(shí)都比較短,主要耗時(shí)集中在中間 3 步,也就是 docker build, push, pull 的時(shí)間消耗,我們就來(lái)分別看一下如何加速這三個(gè)步驟。

Docker build

選擇國(guó)外構(gòu)建

由于 dockerhub 的官方鏡像再國(guó)外,而這些基礎(chǔ)鏡像的軟件源都在國(guó)外,國(guó)內(nèi)構(gòu)建的時(shí)候網(wǎng)絡(luò)會(huì)是很大的瓶頸,有能力在國(guó)外機(jī)器進(jìn)行構(gòu)建,并且可以通過(guò)專(zhuān)線和國(guó)內(nèi)進(jìn)行傳輸?shù)脑?,還是優(yōu)先將構(gòu)建節(jié)點(diǎn)放在國(guó)外,會(huì)省很多無(wú)謂的在網(wǎng)絡(luò)上的糾纏,并且很多軟件源國(guó)外的也要更穩(wěn)定寫(xiě),更新也更及時(shí)。

如果只能在國(guó)內(nèi)進(jìn)行構(gòu)建的話,建議使用國(guó)內(nèi)的鏡像,或者自己在私有倉(cāng)庫(kù)存一份官方鏡像,并且對(duì)鏡像進(jìn)行改造,做一份軟件源都在國(guó)內(nèi)的基礎(chǔ)鏡像,把構(gòu)建過(guò)程中的網(wǎng)絡(luò)傳輸都控制在國(guó)內(nèi)或者內(nèi)網(wǎng),這樣就不用和網(wǎng)絡(luò)進(jìn)行糾纏了。

善用 .dockerignore

.dockerignore 可以減少構(gòu)建時(shí)的文件傳輸,一般通過(guò) git 進(jìn)行持續(xù)構(gòu)建的時(shí)候不做設(shè)置都會(huì)把 .git 文件夾進(jìn)行傳輸造成很多無(wú)用的傳輸,一些與構(gòu)建無(wú)關(guān)的代碼也盡量卸載 .dockerigonre 文件中。

緩存優(yōu)化的 dockerfile

dockerfile 的優(yōu)化也是一個(gè)比較直接的優(yōu)化方式,優(yōu)化的核心就是能充分利用 build cache,把每次變化的部分放在***,一般把加入代碼放在***一步,這樣每次構(gòu)建只有***一層是新的,其他部分都是可以用 cache 的。對(duì)于 node、python、go 之類(lèi)要在構(gòu)建過(guò)程中安裝依賴的服務(wù),可以把安裝依賴和加入代碼分兩步完成,這樣在依賴不變的情況下這部分的緩存也是可以利用的。以 node 為例:

  1. COPY package.json /usr/src/app/ 
  2. RUN npm install 
  3. COPY . /usr/src/app 

其他關(guān)于 dockerfile 優(yōu)化的建議可以再單獨(dú)開(kāi)一篇了,基本上每個(gè)命令都需要特殊對(duì)待才能不掉坑里,可以參考一個(gè)在線 dockerfile 語(yǔ)法優(yōu)化器,里面會(huì)提供一些相關(guān)的 dockerfile 優(yōu)化建議和一些資源,作者一定是個(gè)大好人。

smart cache

在單機(jī)模式下充分利用 build cache 是個(gè)不錯(cuò)的注意,但是在多個(gè)構(gòu)建機(jī)器的情況下就會(huì)有問(wèn)題了。出于磁盤(pán)空間考量不可能所有機(jī)器都存著所有的鏡像,這樣緩存優(yōu)化的 dockerfile 就沒(méi)有用武之地了。為了讓 cache 重新發(fā)揮作用我們可以在構(gòu)建開(kāi)始時(shí)將舊的鏡像 pull 下來(lái),這樣一來(lái)就可以再次利用 cache 了。但是一來(lái) pull 鏡像也是需要很多時(shí)間的,并且 pull 下來(lái)的鏡像并不會(huì)全部有用,會(huì)浪費(fèi)一定的時(shí)間;而來(lái)如果 dockerfile 變化比較大有可能沒(méi)有一層能用 pull 下來(lái)反而會(huì)浪費(fèi)更多的時(shí)間;三來(lái)倉(cāng)庫(kù)內(nèi)可能會(huì)有其他的鏡像更適合做當(dāng)前構(gòu)建的緩存所以我們需要實(shí)現(xiàn)一個(gè)精準(zhǔn)的鏡像拉取,不能出錯(cuò)也不能浪費(fèi)。

舉個(gè)栗子,如下圖所示想要構(gòu)建 node:wheezy 的話那么 node:0-wheezy 是一個(gè)比較合適的鏡像來(lái)做 cache 而想要構(gòu)建 node:5 的話那么 node:wheezy 和 node:0-wheezy 都不太合適,反而是 python:latest 會(huì)更合適。如果我們把倉(cāng)庫(kù)中所有的鏡像都做成這樣一個(gè)森林,利用 tire 樹(shù)可以很精準(zhǔn)的知道,哪個(gè)鏡像的哪幾層是 cache 的***選擇,這樣精確制導(dǎo)不會(huì)有一點(diǎn)浪費(fèi)。

舉個(gè)栗子,如下圖所示 

Docker push

docker registry 在升級(jí)到 v2 后加入了很多安全相關(guān)檢查,使得原來(lái)很多在 v1 already exist 的層依然要 push 到 registry,并且由于 v2 中的存儲(chǔ)格式變成了 gzip,在鏡像壓縮過(guò)程中占用的時(shí)間很有可能比網(wǎng)絡(luò)傳輸還要多。我們簡(jiǎn)單分解一下 docker push 的流程。

  • buffer to diske 將該層文件系統(tǒng)壓縮成本地的一個(gè)臨時(shí)文件
  • 上傳文件至 registry
  • 本地計(jì)算壓縮包 digest,刪除臨時(shí)文件,digest 傳給 registry
  • registry 計(jì)算上傳壓縮包 digest 并進(jìn)行校驗(yàn)
  • registry 將壓縮包傳輸至后端存儲(chǔ)文件系統(tǒng)
  • 重復(fù) 1-5 直至所有層傳輸完畢
  • 計(jì)算鏡像的 manifest 并上傳至 registry 重復(fù) 3-5

此外判斷 already exist skip pushing 的條件變嚴(yán)格了,必須是本地計(jì)算過(guò)digest 且 該 digest 對(duì)應(yīng)的文件屬在對(duì)應(yīng) repo 存在才可以。

換句話說(shuō)就是如果這個(gè)鏡像層是 pull 下來(lái)的,那么是沒(méi)有digest的還是要把整個(gè)壓縮包傳輸并計(jì)算 digest,如果這個(gè)鏡像你之前并沒(méi)有比如 ubuntu 的 base image 你的 repo ***次創(chuàng)建之前沒(méi)傳輸過(guò),那么***次也要你傳輸一次確認(rèn)你真的有 ubuntu。

這里面的改進(jìn)點(diǎn)就是在太多了,先列舉 Docker 官方已經(jīng)做得和正在做的。

  • 1.9.1 后 push 是 streaming 式的,也就是把 1 和 2 合并去掉臨時(shí)文件,直接一邊壓縮一邊傳輸。
  • pull 鏡像后 digest 保存,大概是 1.8.3 之后添加的省去了重復(fù)計(jì)算。
  • registry 可以直接 mount 別人 repo 中的一層到自己的 repo,只要有pull權(quán)限即可,這個(gè)工作還在進(jìn)行中。

但是這只解決了一小部分問(wèn)題,push 依然會(huì)很慢,docker 和 registry 的設(shè)計(jì)更多的考慮了公有云的環(huán)境設(shè)置了過(guò)多的安全防范為了防止鏡像的偽造和越權(quán)獲取,但是在一個(gè)可信的環(huán)境內(nèi)如果 build 和 push 過(guò)程都是自己掌控的,那么很多措施都是多余的,我們可以設(shè)計(jì)一個(gè)自己的 smart pusher 挖掘性能的***潛力:

  • 壓縮傳輸 streaming 化和 docker 1.9.1 實(shí)現(xiàn)的類(lèi)似
  • 越過(guò) registry 直接和存儲(chǔ)系統(tǒng)通信,直接拿掉上面 5 的傳輸時(shí)間
  • 如果 digest 在 存儲(chǔ)系統(tǒng)中存在則不再重復(fù)傳輸,在 manifest 中寫(xiě)好層次關(guān)系就好
  • 將多層的傳輸并行化,多個(gè)層一塊傳,這樣才能充分發(fā)揮多核的優(yōu)勢(shì),docker 自帶的串行push效率實(shí)在是太低了
  • 另外針對(duì) build 結(jié)果進(jìn)行 push 的 smart pusher 可以將流水線發(fā)揮到***,build 每構(gòu)建出一層就進(jìn)行傳輸,將 build 和 push 的時(shí)間重疊利用

有了 smart pusher,push 時(shí)間的絕大多數(shù)都被隱藏到了 build 的時(shí)間中,我們把并發(fā)和流水線的技術(shù)都用上,充分發(fā)揮了多核的優(yōu)勢(shì)。

Docker pull

docker pull 鏡像的速度對(duì)服務(wù)的啟動(dòng)速度至關(guān)重要,好在 registry v2 后可以并行 pull 了,速度有了很大的改善。但是依然有一些小的問(wèn)題影響了啟動(dòng)的速度:

  • 下載鏡像和解壓鏡像是串行的
  • 串行解壓,由于 v2 都是 gzip 要解壓,盡管并行下載了還是串行解壓,內(nèi)網(wǎng)的話解壓時(shí)間比網(wǎng)絡(luò)傳輸都要長(zhǎng)
  • 和 registry 通信,registry 在 pull 的過(guò)程中并不提供下載內(nèi)容只是提供下載 url 和鑒權(quán),這一部分加長(zhǎng)了網(wǎng)絡(luò)傳輸而且一些 metadata 還是要去后端存儲(chǔ)獲取,延時(shí)還是有一些的
  • docker pull 某些情況會(huì)卡死,不 docker restart 很難解決,而 restart 又會(huì)停止所有服務(wù),嚴(yán)重影響服務(wù)穩(wěn)定性。

為此我們還需要一個(gè)獨(dú)特設(shè)計(jì)的 smart puller 幫助我們解決***的問(wèn)題: 1. streaming downloading and extracting 和在 smarter pusher 做的類(lèi)似將這兩步合為一步 2. 并行解壓,也和 smarter pusher 并行壓縮類(lèi)似 3. 越過(guò) registry 直接和后端存儲(chǔ)通信 4. redis 緩存 metadata

有了 smart puller 我們自然的將 docker pull 的工作和 docker daemon 解耦了,這樣再不會(huì)發(fā)生 pull 導(dǎo)致的 docker hang,服務(wù)穩(wěn)定性也得到了增強(qiáng),解綁后其實(shí) docker 只是做一個(gè) runtime 這一部分也可考慮改成 runc 去除掉 daemon 這個(gè)單點(diǎn),不過(guò)這個(gè)工作量就比較大了。此外 smart puller 也可以幫助我們實(shí)現(xiàn)在 smart cache 中的精確 pull 以及 pull cache 的加速,可謂一舉多得。

總結(jié)

將 push 和 pull 的工作和 daemon 解綁,把 smart cache,smart puller 和 smart pusher 用上后,持續(xù)集成如絲般潤(rùn)滑。

原文鏈接:http://oilbeater.com/docker/2016/01/02/use-docker-performance-issue-and-solution.html

責(zé)任編輯:Ophira 來(lái)源: oilbeater的博客
相關(guān)推薦

2015-09-29 10:08:26

DockerJava持續(xù)集成

2015-07-27 11:32:24

Docker持續(xù)集成Docker部署

2009-07-01 18:14:36

JSP亂碼

2011-05-06 17:25:58

硒鼓

2016-08-05 17:19:37

持續(xù)集成持續(xù)交付系統(tǒng)運(yùn)維

2022-04-02 20:27:30

ETS操作系統(tǒng)鴻蒙

2017-02-27 18:35:23

集成交付部署

2015-12-02 14:56:07

Docker開(kāi)發(fā)模式持續(xù)集成

2023-03-19 11:47:57

Taro小程序持續(xù)集

2010-12-27 10:48:10

VirtualboxFreedos

2022-04-06 10:09:17

云服務(wù)云計(jì)算

2019-10-11 19:45:28

SparkSQLHiveHadoop

2017-10-19 09:47:55

容器化微服務(wù)集成

2021-06-17 08:07:35

Linux 內(nèi)存站崗

2011-08-24 17:41:16

MySQL死鎖

2016-03-23 11:03:40

2010-05-11 18:05:50

MySQL 5安裝

2019-02-22 08:21:21

路由器WAN寬帶

2012-11-19 11:30:40

PowerShell常見(jiàn)問(wèn)題解決方法

2022-02-16 08:50:51

web自動(dòng)化測(cè)試python
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)