成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

記一次Docker構(gòu)建失敗

joyqi / 1389人閱讀

摘要:之所以在本地構(gòu)建,而沒有使用倉庫的,是因為,我們的鏡像采用了國內(nèi)阿里云的源,再加上某些很奇妙的網(wǎng)絡(luò)因素,在中自動構(gòu)建時,升級總會失敗。然而,在本地再次構(gòu)建成功。

見字如晤。

前段時間,Node.js 官方發(fā)布了Node 8.9.3 LTS版本,并且官網(wǎng)首頁提示新版本有重要安全更新,“Important security releases, please update now!” ,然后我立即著手公司產(chǎn)品各個模塊的Node版本升級。

發(fā)布基礎(chǔ)鏡像

我們所有項目均使用Node.js實現(xiàn),并采用Docker容器交付和部署,所以要升級所有產(chǎn)品的線上Node.js版本,只需要更新一下Docker鏡像打包時的配置文件Dockerfile即可。下方就是一個典型項目的Dockerfile配置文件。

FROM maichong/node:8.9.1

MAINTAINER Maichong Cloud 

RUN apt-get update 
    && apt-get install -y --no-install-recommends openssh-client 
    && apt-get clean 
    && rm -rf /var/lib/apt/lists/*

COPY package.json /app/

WORKDIR /app

RUN npm install --production 
 && rm -R ~/.npm*

COPY . /app

CMD node index.js

腳本大意:

基于 maichong/node:8.9.1 基礎(chǔ)鏡像構(gòu)建

記錄作者信息

運行 apt ,為鏡像安裝 openssh-client 軟件

拷貝代碼 package.js 到目標(biāo)鏡像中

設(shè)置鏡像容器工作目錄為 /app

在鏡像中運行 npm 安裝依賴

拷貝代碼到目標(biāo)鏡像的 /app 目錄中

設(shè)置鏡像的啟動命令

技巧: 這里先拷貝 package.js 再安裝npm依賴,最后拷貝代碼,這樣的好處是:項目代碼經(jīng)常變動,而項目的npm依賴一般不會變化,這樣的順序安排可以有效利用docker build緩存,在package.js沒有變化的情況下跳過漫長的npm依賴安裝時間,大大提高打包速度。

從上邊的Dockerfile配置文件中看到,我們的項目均依賴于基礎(chǔ)鏡像 maichong/node,這是我們自己發(fā)布的Node.js鏡像,和Node.js官方鏡像的主要區(qū)別是:我們的鏡像使用了阿里云的 debian apt 源鏡像,并采用了 registry.npm.taobao.org 做npm加速鏡像。

所以,首先要做的是發(fā)布一個新版本的Node.js鏡像:maichong/node:8.9.3。

發(fā)布過程很簡單,編寫基礎(chǔ)鏡像的Dockerfile,在本地構(gòu)建鏡像,最后將鏡像推送到Docker官方的倉庫,Done!

基礎(chǔ)鏡像的Dockerfile可以在這里找到 https://github.com/liangxingc... 。

之所以在本地構(gòu)建,而沒有使用Docker倉庫的 automated build,是因為,我們的鏡像采用了國內(nèi)阿里云的 Debian apt 源,再加上某些很奇妙的網(wǎng)絡(luò)因素,在Docker Hub中自動構(gòu)建時,apt升級總會失敗。

升級項目

maichong/node:8.9.3 基礎(chǔ)鏡像已經(jīng)準(zhǔn)備就緒,接下來開始升級公司的各個項目。

我們的所有項目都基于脈沖云 maichong.io 進行管理,脈沖云包含了從代碼倉庫,到自動化構(gòu)建,再到自動化部署等持續(xù)集成流程。

修改項目的Dockerfile,將基礎(chǔ)鏡像變更為 maichong/node:8.9.3,然后將代碼提交到代碼倉庫,然后起身泡了一杯咖啡,悠然地等待脈沖云自動地在線編譯打包Docker鏡像,并自動將最新的鏡像部署到服務(wù)器集群上,完成升級工作。

意外!

當(dāng)我端者剛剛泡好的咖啡回到工位,意外發(fā)現(xiàn),脈沖云在線編譯構(gòu)建失??!心里一涼,我*,何方BUG在此作祟?!趕快在線查看構(gòu)建日志,導(dǎo)致失敗的關(guān)鍵部分日志如下:

2017-12-12 10:04:05 Step 5/12 : RUN apt-get update && apt-get install -y --no-install-recommends openssh-client && apt-get clean && rm -rf /var/lib/apt/lists/*
2017-12-12 10:04:05 ---> Running in c3fb701ef925
2017-12-12 10:04:06 Ign http://mirrors.aliyun.com jessie InRelease
...
2017-12-12 10:04:07 Fetched 11.1 MB in 1s (6028 kB/s)
2017-12-12 10:04:09 Reading package lists...
2017-12-12 10:04:10 Building dependency tree...
2017-12-12 10:04:10 Reading state information...
2017-12-12 10:04:10 The following extra packages will be installed:
2017-12-12 10:04:10 adduser debconf debianutils dpkg ... (一共40個軟件包)
2017-12-12 10:04:10 Suggested packages: ...
2017-12-12 10:04:10 Recommended packages: ...
2017-12-12 10:04:12 0 upgraded, 40 newly installed, 0 to remove and 0 not upgraded.
2017-12-12 10:04:12 Need to get 16.7 MB of archives.
2017-12-12 10:04:12 After this operation, 44.7 MB of additional disk space will be used.
2017-12-12 10:04:12 Get:1 http://mirrors.aliyun.com/debian/ jessie/main sensible-utils all 0.0.9 [11.3 kB]
...
2017-12-12 10:04:22 dpkg: error processing archive /var/cache/apt/archives/libgcc1_1%3a4.9.2-10_amd64.deb (--unpack):
2017-12-12 10:04:22 pre-dependency problem - not installing libgcc1:amd64
為了限制篇幅,上邊貼出的構(gòu)建日志進行了精簡,大量的 apt 網(wǎng)絡(luò)請求和解壓縮包日志使用 … 代替,同時apt顯示了大量的必須或推薦安裝的軟件包也以 … 省略。

從日志中得到錯誤信息是,在docker build打包過程中,運行apt安裝openssh-client失敗,最直接的錯誤是因為openssh-client依賴的libgcc1包安裝失敗。

直接反應(yīng)是,莫非又是apt軟件倉庫依賴的問題?!咦,我為什么要說又呢?

apt 是Debian和Ubuntu系統(tǒng)使用的包管理器,類似Node.js世界的npm的作用,用來管理、安裝Linux系統(tǒng)中的各種軟件包,各種軟件包又有不同版本并互相依賴。

apt安裝軟件時,會從網(wǎng)絡(luò)服務(wù)器上獲取所需軟件包和相關(guān)依賴包,這里的“網(wǎng)絡(luò)服務(wù)器”被稱為“源”,所以上文中說到的 maichong/node 鏡像用到了國內(nèi)阿里云的“源”,是為了加快apt安裝軟件時的網(wǎng)絡(luò)速度,阿里云的“源”服務(wù)器是對Debian官方源的加速鏡像。

由于apt所管理的軟件包數(shù)量眾多、版本眾多、互相依賴、互相依賴指定版本,所以容易造成依賴問題,比如 A依賴于B的1.0版本,C依賴于B的2.0版本,如果安裝了A,安裝C時就會出錯,因為系統(tǒng)中無法共存B的1.0和2.0兩個版本。

題外話,npm采用多層node_modules目錄嵌套解決了一個包不同版本共存的問題。

仔細觀察安裝openssh-client時所安裝的40個依賴包,發(fā)現(xiàn)竟然有dpkg這樣非?;A(chǔ)的包,怎么可能?!dpkg是Debian系統(tǒng)最基礎(chǔ)的包管理器,apt都是依賴于dpkg,所有能跑起來的Debian系統(tǒng)一定是存在dpkg包的,難道是...

基礎(chǔ)鏡像是“壞”的?

Docker的鏡像一旦構(gòu)建完成,就一定能夠正確執(zhí)行,我個人從未見過某個鏡像自身是“壞”的,可能這次要開眼!

這里之所以說“壞”,是因為鏡像中整個apt管理依賴都錯亂了,可能是某些原因造成了鏡像的“損壞”!

在我本地執(zhí)行構(gòu)建命令:

docker build -t test ./

然后竟然構(gòu)建成功!說明基礎(chǔ)鏡像沒問題,莫非又是環(huán)境差異問題?!本地構(gòu)建日志如下:

Step 5/12 : RUN apt-get update     && apt-get install -y --no-install-recommends openssh-client       && apt-get clean       && rm -rf /var/lib/apt/lists/*
 ---> Running in 237bec98f4e6
Ign http://mirrors.aliyun.com jessie InRelease
...
Fetched 11.1 MB in 11s (972 kB/s)
Reading package lists...
Building dependency tree...
Reading state information...
The following extra packages will be installed:
  libbsd0 libedit2
Suggested packages:
  ssh-askpass libpam-ssh keychain monkeysphere
Recommended packages:
  xauth
The following NEW packages will be installed:
  libbsd0 libedit2 openssh-client
0 upgraded, 3 newly installed, 0 to remove and 8 not upgraded.

從日志中發(fā)現(xiàn),在我本地構(gòu)建時,apt安裝openssh-client只需要安裝3個軟件包。這怎么可能?!同樣的基礎(chǔ)鏡像,同樣都使用阿里云的源,難道是...

阿里云源鏡像數(shù)據(jù)問題?

阿里云的源鏡像服務(wù)是搭建在CDN上的,CDN的目的是為了讓用戶就近訪問不同地理位置的服務(wù)器,以達到不同地區(qū)的用戶訪問速度都能很快,所以雖然使用了同樣的源鏡像地址,但是在不同位置更新apt時,所請求的阿里云服務(wù)器是不一樣的。那么就有可能是阿里CDN數(shù)據(jù)不同或是從國外Debian官方服務(wù)器數(shù)據(jù)同步未完成導(dǎo)致的問題。

登錄到遠程脈沖云Builder Runner,這是專門用來執(zhí)行用戶自動化集成的服務(wù)器,一開始我們的在線構(gòu)建就是發(fā)生在這里的。在Runner上 ping mirrors.aliyun.com 得到的源鏡像IP地址和我本地的果然不一樣。

然后我將在Runner上得到的IP地址,加到了我本地DNS解析中,這樣,我本地再運行apt時,訪問的服務(wù)器就和在Runner上是一樣的了。

然而,在本地再次構(gòu)建成功。說明并非是阿里云源鏡像數(shù)據(jù)問題。同樣的鏡像,同樣的源服務(wù)器,不同的apt運行結(jié)果,難道是...

遠程主機上的鏡像損壞?

會不會是我本地拉到的鏡像是好的,但是遠程Runner上拉到的鏡像卻是壞的?

這是不可能的,因為Docker在拉取鏡像后,會對鏡像進行驗證,所以同一個鏡像版本,多人拉取完成后可以保證每個人所得是一模一樣的。不會存在某人拉取到一個損壞的鏡像的情況。

似乎所有可能性都被排除了,問題仍然得不到解決,真是莫名其妙,手上的線索已經(jīng)全部斷掉,案件偵破進入了僵局。

我向團隊說明了我遇到的情況,鄰桌Mr.Li斷言道:“一定是環(huán)境差異導(dǎo)致的BUG!”

是呀,一定是環(huán)境差異問題,但是所有環(huán)境差異都排除過了,同樣的網(wǎng)絡(luò)環(huán)境,同樣的構(gòu)建配置,同樣的鏡像...

我們知道Docker的優(yōu)勢就在于將軟件和運行環(huán)境打包成一個鏡像,一個鏡像在不同外部環(huán)境下執(zhí)行,能夠保證鏡像內(nèi)的程序所在的鏡像內(nèi)部環(huán)境一模一樣,因為Docker運行容器時,會將環(huán)境完全隔離。不對,并沒有“完全”隔離,難道是...

宿主機內(nèi)核差異問題?

在本地和在Ranner上分別執(zhí)行uname -a,果然得到的內(nèi)核版本是不一樣的。

本地:

Linux local 4.4.0-103-generic #126-Ubuntu SMP Mon Dec 4 16:23:28 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

Runner:

Linux runner02 4.4.0-98-generic #121-Ubuntu SMP Tue Oct 10 14:24:03 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

本地的Linux內(nèi)核版本是 4.4.0-103-generic ,遠程Runner宿主機內(nèi)核版本是 4.4.0-98-generic 。嘗試升級遠程Runner宿主機內(nèi)核:

apt-get update
apt-get dist-upgrade

將宿主機內(nèi)核升級到了最新版4.4.0-103-generic,重啟Runner后,在線Docker打包成功!

總結(jié)

其實Docker運行容器時,并非將所有環(huán)境“完全隔離”,比如宿主機內(nèi)核就沒有隔離。Docker并不像VMware那樣,在啟動虛擬機時,完全虛擬一個硬件環(huán)境,然后從頭加載虛擬機操作系統(tǒng)的內(nèi)核。Docker容器運行時,仍然依賴于宿主機內(nèi)存里正在運行的內(nèi)核,雖然不同容器使用不同鏡像,但鏡像的本質(zhì)是文件系統(tǒng)的壓縮包,是讓你的容器運行時有一個自己定義的文件系統(tǒng)和軟件群,而執(zhí)行容器程序時,并沒有從頭為你啟動一個系統(tǒng)內(nèi)核。所以我們稱Docker為輕量級虛擬化技術(shù)。

本文所遇到的問題的原因應(yīng)該是,在構(gòu)建 maichong/node:8.9.3 鏡像時,是在 4.4.0-103-generic 版本內(nèi)核環(huán)境下執(zhí)行的,apt 安裝的一系列軟件是適用于 4.4.0-103-generic 版本的,而在Runner上執(zhí)行構(gòu)建時,內(nèi)核又變?yōu)榱?4.4.0-98-generic可能 apt 將之前基礎(chǔ)鏡像中的一些軟件標(biāo)識為無效,又要進行重新安裝。

這種情況我之前也從未見過,所以撰文記錄,可以斷定,Docker Hub大部分鏡像編譯時的內(nèi)核環(huán)境和我們本地的內(nèi)核是不一樣的,怎么單單這次apt會出錯?apt在管理軟件時,系統(tǒng)內(nèi)核對apt有怎樣的具體影響?待來日機緣成熟再一探究竟。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/27190.html

相關(guān)文章

  • 一次PHP并發(fā)性能調(diào)優(yōu)實戰(zhàn) -- 性能提升104%

    摘要:這是多處理器系統(tǒng)中,調(diào)度器用來分散任務(wù)到不同的機制,通常也被稱為處理器間中斷,。文章編寫計劃 待完成: 詳細介紹用到的各個工具 作者: 萬千鈞(祝星) 適合閱讀人群 文中的調(diào)優(yōu)思路無論是php, java, 還是其他任何語言都是用. 如果你有php使用經(jīng)驗, 那肯定就更好了 業(yè)務(wù)背景 框架及相應(yīng)環(huán)境 laravel5.7, mysql5.7, redis5, nginx1.15 cento...

    番茄西紅柿 評論0 收藏0
  • 一次PHP并發(fā)性能調(diào)優(yōu)實戰(zhàn) -- 性能提升104%

    摘要:這是多處理器系統(tǒng)中,調(diào)度器用來分散任務(wù)到不同的機制,通常也被稱為處理器間中斷,。文章編寫計劃 待完成: 詳細介紹用到的各個工具 作者: 萬千鈞(祝星) 適合閱讀人群 文中的調(diào)優(yōu)思路無論是php, java, 還是其他任何語言都是用. 如果你有php使用經(jīng)驗, 那肯定就更好了 業(yè)務(wù)背景 框架及相應(yīng)環(huán)境 laravel5.7, mysql5.7, redis5, nginx1.15 cento...

    xeblog 評論0 收藏0
  • 幾分鐘看完 flow.ci 全部功能

    摘要:正式內(nèi)測月初,上線,正式進入開發(fā)者的視野。公測注冊取消邀請碼限制,用戶可直接注冊使用。支持持續(xù)部署相比持續(xù)集成,持續(xù)部署的工作流程更受關(guān)注。 從 0 到 1,從邀請式內(nèi)測到收費上線,flow.ci 經(jīng)歷了十個多月的沉淀與打磨。這期間,flow.ci 工程師們奮力趕工,進行了一系列的大功能更新,Bug 修復(fù),功能優(yōu)化。 這篇文章記錄了 flow.ci 內(nèi)測期間的大功能更新和相關(guān)的實踐教程...

    yuanzhanghu 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<