文章轉(zhuǎn)載自https://blog.csdn.net/sisiy2015/article/details/50913829
背景
我最初使用Docker的時(shí)候饿敲,每個(gè)人都在說它用起來有多簡單方便,它內(nèi)部的機(jī)制是有多么好,它為我們節(jié)省了多少時(shí)間滋将。但是當(dāng)我一使用它就發(fā)現(xiàn),幾乎所有鏡像都是臃腫而且不安全的(沒有使用包簽名,盲目相信上游的鏡像庫以curl | sh的方式安裝),而且也沒有一個(gè)鏡像能實(shí)現(xiàn)Docker的初衷:隔離默责,單進(jìn)程,容易分發(fā)咸包,簡潔桃序。
Docker鏡像本來不是為了取代復(fù)雜的虛擬機(jī)而設(shè)計(jì)的,后者有完整的日志烂瘫、監(jiān)控媒熊、警報(bào)和資源管理模塊。而Docker則傾向于利用內(nèi)核的cgroups和namespaces特性進(jìn)行封裝組合,這就好像:
在物理機(jī)器環(huán)境下泛释,一旦內(nèi)核完成了初始化,init進(jìn)程就起來了温算。
這也是為什么當(dāng)你在Dockerfile的CMD指令啟動(dòng)的進(jìn)程PID是1怜校,這是與Unix中的進(jìn)程機(jī)制類似的。
現(xiàn)在請查看一下你的進(jìn)程列表注竿,使用top或者ps茄茁,你會(huì)看到init進(jìn)程占用的也是這個(gè)PID,這是每個(gè)類Unix系統(tǒng)的核心進(jìn)程巩割,所有進(jìn)程的父進(jìn)程裙顽,一旦你理解這個(gè)概念:在類Unix系統(tǒng)上每個(gè)進(jìn)程都是init進(jìn)程的子進(jìn)程,你會(huì)理解Docker容器里不應(yīng)該有無關(guān)的修飾文件宣谈,它應(yīng)該是剛好滿足進(jìn)程運(yùn)行需要愈犹。
如何開始
現(xiàn)在的應(yīng)用多數(shù)是大型復(fù)雜的系統(tǒng),通常都需要很多依賴庫闻丑,例如有調(diào)度漩怎,編譯和很多其他相關(guān)工具類應(yīng)用,它們的架構(gòu)通常封裝性良好嗦嗡,通過一層層的抽象和接口把底層細(xì)節(jié)隱藏了勋锤,從某種程度上說,這也算是一種容器侥祭,但是從系統(tǒng)架構(gòu)視角看叁执,我們需要一種比以往虛擬環(huán)境更簡單的方案了。
以Java為例
從零開始矮冬,思考你要構(gòu)建一個(gè)最通用的基礎(chǔ)容器谈宛,想想你的應(yīng)用本身,它運(yùn)行需要什么欢伏?
可能性有很多入挣,如果你要運(yùn)行Java應(yīng)用,它需要Java運(yùn)行時(shí)硝拧;如果運(yùn)行Rails應(yīng)用径筏,它需要Ruby解釋器,對Python應(yīng)用也一樣障陶。Go和其他一些編譯型語言有些許不同滋恬,我以下會(huì)提到。
在Java例子中抱究,下一步要想的是:JRE需要什么依賴才能運(yùn)行恢氯?因?yàn)樗亲寫?yīng)用能運(yùn)行的最重要的組件,所以很自然的下一步就是要想清楚JRE運(yùn)行依賴于什么。
而實(shí)際上JRE并沒太多依賴勋拟,它本來就是作為操作系統(tǒng)的抽象層勋磕,使代碼不依賴于宿主系統(tǒng)運(yùn)行,因此安裝好JRE就基本準(zhǔn)備就緒了敢靡。
(實(shí)際上挂滓,對操作系統(tǒng)的獨(dú)立性并不是理所當(dāng)然的事,有非常多的系統(tǒng)特有API和專有的系統(tǒng)擴(kuò)展啸胧,但是便于舉例赶站,我們把注意力放在簡單的情況下)
在Linux上,JVM主要是調(diào)用系統(tǒng)的C語言庫纺念,Oracle的官方JRE贝椿,使用的是libc,也就是glibc陷谱,這意味著你要運(yùn)行任何Java程序烙博,都需要先裝好glibc。另外你可能需要某種shell來管理環(huán)境烟逊,還有一個(gè)與外部通訊的接口习勤,例如網(wǎng)絡(luò)和資源的接口。
我們總結(jié)一下Java應(yīng)用示例需要的最低配置是:
- JRE焙格,在例子中我們使用Oracle JRE
- glibc图毕,JRE的依賴
- 一個(gè)基礎(chǔ)環(huán)境(包含網(wǎng)絡(luò)、內(nèi)存眷唉、文件系統(tǒng)等資源管理工具)
走進(jìn)Alpine Linux
Alpine Linux最近得到很多關(guān)注予颤,主要是因?yàn)樗虬艘幌盗械慕?jīng)過驗(yàn)簽的可信任的依賴,并且還保持體積在2MB冬阳!而在本文發(fā)布時(shí)蛤虐,其他的一些鏡像分發(fā)版如下:
ubuntu:latest: 66MB (已經(jīng)瘦身了非常多了,以前有些版本超過600MB)
debian:latest: 55MB (同上肝陪,一開始是200MB以上的)
arch:latest: 145MB
busybox:latest: 676KB (是的驳庭!KB,我稍后會(huì)討論它)
alpine:latest: 2MB (2MB氯窍,包含一個(gè)包管理工具的Linux系統(tǒng))
Busybox是最小的競爭者饲常?
從上邊的對比中你可以看到,在體積上唯一能打敗Alpine Linux的是Busybox狼讨,所以現(xiàn)在幾乎所有嵌入式系統(tǒng)都是使用它贝淤,它被應(yīng)用在路由器,交換機(jī)政供,ATM播聪,或者你的吐司機(jī)上朽基。它作為一個(gè)最最基礎(chǔ)的環(huán)境,但是又提供了足夠容易維護(hù)的shell接口离陶。
在網(wǎng)上有很多文章解釋了為什么人們會(huì)選擇Alpine Linux而不是Busybox稼虎,我在這總結(jié)一下:
- 開放活躍的軟件包倉庫:Alpine Linux使用apk包管理工具,它集成在Docker鏡像中招刨,而Busybox你需要另外安裝一個(gè)包管理器渡蜻,例如opkg,更甚者计济,你需要尋找一個(gè)穩(wěn)定的包倉庫源(這幾乎沒有),Alpine的包倉庫中提供了大量常用的依賴包排苍,例如沦寂,如果你仍然需要在容器中編譯NodeJS或Ruby之類的代碼,你可以直接運(yùn)行apk來添加nodejs和ruby淘衙,這在幾秒內(nèi)便可以完成传藏。
- 體積確實(shí)重要,但是當(dāng)你在功能性彤守,靈活性毯侦,易用性和1.5MB之間衡量,體積就不那么重要了具垫,Alpine上添加的包使這些方面都大大增強(qiáng)了侈离。
- 廣泛的支持:Docker公司已經(jīng)聘請了Alpine Linux的作者來維護(hù)它,所有官方鏡像筝蚕,在以后都將基于Alpine Linux來構(gòu)建卦碾。沒有比這個(gè)更有說服力的理由去讓你在自己的容器中使用它了吧。
構(gòu)建一個(gè)Java環(huán)境基鏡像
正如我剛解釋的起宽,Alpine Linux是一個(gè)構(gòu)建自有鏡像時(shí)不錯(cuò)的選擇洲胖,因此,我們在此將使用它來構(gòu)建簡潔高效的Docker鏡像坯沪,我們開始吧!
組合:Alpine + bash
每個(gè)Dockerfile第一個(gè)指令都是指定它的父級容器绿映,通常是用于繼承,在我們的例子中是alpine:latest:
FROM alpine:latest
MAINTAINER cSphere <docker@csphere.cn>
RUN apk add --no-cache --update-cache bash
CMD ["/bin/bash"]
好了腐晾,現(xiàn)在我們構(gòu)建容器:
$ docker build -t my-java-base-image .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM alpine:latest
---> 2314ad3eeb90
Step 2 : MAINTAINER cSphere <docker@csphere.cn>
---> Running in 63433312d77e
---> bfe94713797a
Removing intermediate container 63433312d77e
...
Step 4 : CMD /bin/bash
---> Running in d2291684b797
---> ecc443d68f27
Removing intermediate container d2291684b797
Successfully built ecc443d68f27
并且運(yùn)行它:
$ docker run --rm -ti my-java-base-image
bash-4.3#
成功了叉弦!我們有了一個(gè)運(yùn)行著bash的Alpine Linux。
glibc and friends
前邊提到藻糖,Oracle的JRE依賴于glibc卸奉,Alpine Linux上并沒有g(shù)libc,它使用一個(gè)更小體積的替代版,叫musl libc颖御。glibc發(fā)展了這么多年榄棵,幾乎包含了所有C語言中需要的依賴包凝颇,顯然這樣會(huì)很不靈活,一個(gè)glibc庫被編譯進(jìn)Alpine Linux疹鳄,勉強(qiáng)能維持在5MB的體積拧略,而它的替代者musl-libc是一個(gè)二進(jìn)制文件,只有897KB瘪弓,并且支持了所有Linux架構(gòu)上的C依賴垫蛆。
對Oracle的JRE,沒有辦法不把glibc加上腺怯,幸運(yùn)的是袱饭,Andy Shinn已經(jīng)做過了這些,他提供了一個(gè)預(yù)編譯的glibc鏡像給Alpine Linux呛占,在Github上的alpine-pkg-glibc虑乖,最新版是2.23-r1。
這樣把這相關(guān)依賴加到Dockerfile中晾虑,現(xiàn)在我們的Dockerfile看起來是這樣:
FROM alpine:latest
MAINTAINER cSphere <docker@csphere.cn>
ENV GLIBC_PKG_VERSION=2.23-r1
RUN apk add --no-cache --update-cache curl ca-certificates bash && \
curl -Lo /etc/apk/keys/andyshinn.rsa.pub "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/andyshinn.rsa.pub" && \
curl -Lo glibc-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-${GLIBC_PKG_VERSION}.apk" && \
curl -Lo glibc-bin-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-bin-${GLIBC_PKG_VERSION}.apk" && \
curl -Lo glibc-i18n-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-i18n-${GLIBC_PKG_VERSION}.apk" && \
apk add glibc-${GLIBC_PKG_VERSION}.apk glibc-bin-${GLIBC_PKG_VERSION}.apk glibc-i18n-${GLIBC_PKG_VERSION}.apk
CMD ["/bin/bash"]
我們一句句解釋一下這些指令:
ENV GLIBC_PKG_VERSION=2.23-r1
我們通過變量指定GitHub上的glibc版本疹味,所以每當(dāng)一個(gè)新版本發(fā)布,都不需要更改URL帜篇,而直接更改這個(gè)變量即可糙捺。
RUN apk add --update-cache curl ca-certificates bash && \
這個(gè)指令會(huì)使用apk命令安裝我們需要的包,包括curl和ca-certificates(以便使用TLS的頁面)笙隙,最后的bash是我們Dockerfile上個(gè)版本已經(jīng)有的了洪灯。
curl -Lo /etc/apk/keys/andyshinn.rsa.pub "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/andyshinn.rsa.pub" && \
curl -Lo glibc-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-${GLIBC_PKG_VERSION}.apk" && \
curl -Lo glibc-bin-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-bin-${GLIBC_PKG_VERSION}.apk" && \
curl -Lo glibc-i18n-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-i18n-${GLIBC_PKG_VERSION}.apk" && \
這些命令會(huì)接著剛剛的RUN指令,它們會(huì)從GitHub下載相關(guān)公鑰和依賴包竟痰。
apk add glibc-${GLIBC_PKG_VERSION}.apk glibc-bin-${GLIBC_PKG_VERSION}.apk glibc-i18n-${GLIBC_PKG_VERSION}.apk
所有包下載完成后婴渡,我們會(huì)用這一行命令安裝全部,由于我們之前添加了公鑰凯亮,所以它們的簽名會(huì)被驗(yàn)證边臼。
好了!我們現(xiàn)在有了一個(gè)能運(yùn)行幾乎全部依賴于glibc包的環(huán)境假消。
Java運(yùn)行環(huán)境
一般來說柠并,Oracle不提供軟件倉庫的形式讓人們下載,但是人們總是會(huì)找到一些方法繞過它富拗,你可以使用以下命令把JRE添加到Docker鏡像中:
ENV JAVA_VERSION_MAJOR=8 \
JAVA_VERSION_MINOR=73 \
JAVA_VERSION_BUILD=02 \
JAVA_PACKAGE=server-jre
WORKDIR /tmp
RUN curl -jksSLH "Cookie: oraclelicense=accept-securebackup-cookie" \
"http://download.oracle.com/otn-pub/java/jdk/${JAVA_VERSION_MAJOR}u${JAVA_VERSION_MINOR}-b${JAVA_VERSION_BUILD}/${JAVA_PACKAGE}-${JAVA_VERSION_MAJOR}u${JAVA_VERSION_MINOR}-linux-x64.tar.gz" | gunzip -c - | tar -xf - && \
apk del curl ca-certificates && \
mv jdk1.${JAVA_VERSION_MAJOR}.0_${JAVA_VERSION_MINOR}/jre /jre && \
rm /jre/bin/jjs && \
rm /jre/bin/keytool && \
rm /jre/bin/orbd && \
rm /jre/bin/pack200 && \
rm /jre/bin/policytool && \
rm /jre/bin/rmid && \
rm /jre/bin/rmiregistry && \
rm /jre/bin/servertool && \
rm /jre/bin/tnameserv && \
rm /jre/bin/unpack200 && \
rm /jre/lib/ext/nashorn.jar && \
rm /jre/lib/jfr.jar && \
rm -rf /jre/lib/jfr && \
rm -rf /jre/lib/oblique-fonts && \
rm -rf /tmp/* /var/cache/apk/* && \
echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
ENV JAVA_HOME /jre
ENV PATH ${PATH}:${JAVA_HOME}/bin
這堆命令究竟做了什么臼予,我們還是一句句來看一下吧:
ENV JAVA_VERSION_MAJOR=8 \
JAVA_VERSION_MINOR=73 \
JAVA_VERSION_BUILD=02
JAVA_PACKAGE=server-jre
WORKDIR /tmp
這句非常簡單,它定義了我們要從Oracle服務(wù)器上要下載的軟件版本啃沪,本文編寫時(shí)粘拾,上邊的版本號是最新的,以后可能會(huì)變化创千,你可以從Oracle官網(wǎng)上查看缰雇。它同時(shí)也指定了WORKDIR工作目錄入偷,我們需要從一個(gè)臨時(shí)目錄開始運(yùn)行,所以這里設(shè)置了/tmp械哟。
RUN curl -jksSLH "Cookie: oraclelicense=accept-securebackup-cookie" \
"http://download.oracle.com/otn-pub/java/jdk/${JAVA_VERSION_MAJOR}u${JAVA_VERSION_MINOR}-b${JAVA_VERSION_BUILD}/${JAVA_PACKAGE}-${JAVA_VERSION_MAJOR}u${JAVA_VERSION_MINOR}-linux-x64.tar.gz" | gunzip -c - | tar -xf - && \
這句稍微有點(diǎn)復(fù)雜疏之,它使用curl傳了一個(gè)指定的頭信息(“Cookie: oraclelicense=accept-securebackup-cookie”),以從Oracle上獲取真正的下載包暇咆,這是必須的锋爪,不然會(huì)返回一個(gè)錯(cuò)誤頁。然后它會(huì)把下載好的包通過管道傳給gunzip和tar 爸业,換言之其骄,它并不會(huì)保存下載回來的tar包,而是直接解壓出來到磁盤上扯旷。
apk del curl ca-certificates && \
這時(shí)curl和ca-certificates兩個(gè)包都完成了它們的使命拯爽,可以刪除了它們以節(jié)省空間。
rm /jre/bin/jjs && \
rm /jre/bin/keytool && \
rm /jre/bin/orbd && \
rm /jre/bin/pack200 && \
rm /jre/bin/policytool && \
rm /jre/bin/rmid && \
rm /jre/bin/rmiregistry && \
rm /jre/bin/servertool && \
rm /jre/bin/tnameserv && \
rm /jre/bin/unpack200 && \
rm /jre/lib/ext/nashorn.jar && \
rm /jre/lib/jfr.jar && \
rm -rf /jre/lib/jfr && \
rm -rf /jre/lib/oblique-fonts && \
rm -rf /tmp/* /var/cache/apk/* && \
JRE自帶了一些工具包薄霜,可能永遠(yuǎn)都不會(huì)用到的,我們也將它們刪掉纸兔。 最后一行惰瓜,會(huì)把全部臨時(shí)文件和apk的包緩存也清理了。
echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
這一行中汉矿,我們修改了nsswitch.conf崎坊,以確保網(wǎng)絡(luò)正常,這會(huì)被glibc等包所用到洲拇。
最后奈揍,我們的Dockerfile會(huì)是下邊這樣:
FROM alpine:latest
MAINTAINER cSphere <docker@csphere.cn>
ENV JAVA_VERSION_MAJOR=8 \
JAVA_VERSION_MINOR=73 \
JAVA_VERSION_BUILD=02 \
JAVA_PACKAGE=server-jre \
GLIBC_PKG_VERSION=2.23-r1 \
LANG=en_US.UTF8
WORKDIR /tmp
RUN apk add --no-cache --update-cache curl ca-certificates bash && \
curl -Lo /etc/apk/keys/andyshinn.rsa.pub "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/andyshinn.rsa.pub" && \
curl -Lo glibc-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-${GLIBC_PKG_VERSION}.apk" && \
curl -Lo glibc-bin-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-bin-${GLIBC_PKG_VERSION}.apk" && \
curl -Lo glibc-i18n-${GLIBC_PKG_VERSION}.apk "https://github.com/andyshinn/alpine-pkg-glibc/releases/download/${GLIBC_PKG_VERSION}/glibc-i18n-${GLIBC_PKG_VERSION}.apk" && \
apk add glibc-${GLIBC_PKG_VERSION}.apk glibc-bin-${GLIBC_PKG_VERSION}.apk glibc-i18n-${GLIBC_PKG_VERSION}.apk && \
curl -jksSLH "Cookie: oraclelicense=accept-securebackup-cookie" \
"http://download.oracle.com/otn-pub/java/jdk/${JAVA_VERSION_MAJOR}u${JAVA_VERSION_MINOR}-b${JAVA_VERSION_BUILD}/${JAVA_PACKAGE}-${JAVA_VERSION_MAJOR}u${JAVA_VERSION_MINOR}-linux-x64.tar.gz" | gunzip -c - | tar -xf - && \
apk del curl ca-certificates && \
mv jdk1.${JAVA_VERSION_MAJOR}.0_${JAVA_VERSION_MINOR}/jre /jre && \
rm /jre/bin/jjs && \
rm /jre/bin/keytool && \
rm /jre/bin/orbd && \
rm /jre/bin/pack200 && \
rm /jre/bin/policytool && \
rm /jre/bin/rmid && \
rm /jre/bin/rmiregistry && \
rm /jre/bin/servertool && \
rm /jre/bin/tnameserv && \
rm /jre/bin/unpack200 && \
rm /jre/lib/ext/nashorn.jar && \
rm /jre/lib/jfr.jar && \
rm -rf /jre/lib/jfr && \
rm -rf /jre/lib/oblique-fonts && \
rm -rf /tmp/* /var/cache/apk/* && \
echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
ENV JAVA_HOME=/jre
ENV PATH=${PATH}:${JAVA_HOME}/bin
注意這里,我整合了兩個(gè)ENV和RUN指令赋续,因?yàn)樽詈檬怯酶俚闹虚g層男翰,特別是這個(gè)容器是作為通用的構(gòu)建單元。
簡單來說纽乱,有一個(gè)規(guī)則:你需要更大的靈活性蛾绎,那你需要更多的層;如果你需要減小體積和降低復(fù)雜度鸦列,你需要更少的層租冠。這完全取決于你的需求。
在頂部我還加上了這句:
ENV LANG=en_US.UTF-8
這句是為了確保運(yùn)行在這個(gè)系統(tǒng)環(huán)境的應(yīng)用能指定語言薯嗤。你可以根據(jù)需要設(shè)定這個(gè)LANG環(huán)境變量顽爹。
另外,JAVA_HOME和PATH也要設(shè)置好骆姐,以使用剛剛裝好的JRE镜粤。
從Github上下載:https://github.com/izuolan/dockerfiles/blob/master/base/java/oracle-jdk-1.8/Dockerfile
CMD指令會(huì)怎么運(yùn)行?
我之前提到捏题,我們這是在構(gòu)建一個(gè)能提供給其他服務(wù)作為基礎(chǔ)的鏡像,它不需要帶上CMD指令繁仁,因?yàn)樗肋h(yuǎn)不會(huì)運(yùn)行涉馅,但是一旦一個(gè)服務(wù)關(guān)聯(lián)上它,就需要用到了黄虱。
不過你還是可以通過其他方式啟動(dòng)這個(gè)容器稚矿,例如docker run或docker exec指令:
$ docker run --rm -ti my-java-base-image /bin/bash
構(gòu)建最終鏡像
最后,我們終于到了構(gòu)建鏡像這步了:
$ docker build -t my-java-base-image .
Sending build context to Docker daemon 60.42 kB
Step 1 : FROM alpine:latest
---> 2314ad3eeb90
Step 2 : MAINTAINER cSphere <docker@csphere.cn>
---> Using cache
---> 93cc2bc0bd60
Step 3 : ENV JAVA_VERSION_MAJOR 8 JAVA_VERSION_MINOR 73 JAVA_VERSION_BUILD 02 JAVA_PACKAGE server-jre GLIBC_PKG_VERSION 2.23-r1 LANG en_US.UTF8
---> Running in 3f0ffeaeca78
---> 1dcfd34b0f1a
Removing intermediate container 3f0ffeaeca78
... 省略若干行
Removing intermediate container 0a98b36a6e37
Step 7 : ENV PATH ${PATH}:${JAVA_HOME}/bin
---> Running in 54d0dfb04f98
---> 493399ac9ca6
Removing intermediate container 54d0dfb04f98
Successfully built 493399ac9ca6
它執(zhí)行成功了捻浦。我們運(yùn)行容器里的java來驗(yàn)證一下吧:
$ docker run --rm -ti my-java-base-image java -version
java version "1.8.0_73"
Java(TM) SE Runtime Environment (build 1.8.0_73-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)
這正是我們要看到的結(jié)果晤揣,我們已經(jīng)有了一個(gè)獨(dú)立的Oracle JRE環(huán)境,以后我們只需要基于這個(gè)鏡像來構(gòu)建應(yīng)用鏡像即可:
FROM my-java-base-image
[...]
最終鏡像有多大朱灿?
$ docker images | grep my-java-base-image | awk '{print $7,$8}'
130.4 MB
說實(shí)話昧识,這還是挺大的,但是畢竟里邊裝的是Java嘛~
總結(jié)
我們現(xiàn)在構(gòu)建了一個(gè)安全盗扒、輕量的Docker鏡像跪楞,基本上可以運(yùn)行任何Java應(yīng)用在上面,當(dāng)然你也可以根據(jù)實(shí)際情況調(diào)整這個(gè)Dockerfile侣灶,但是主要的思想還是像上邊說的那樣甸祭,減小體積,使用安全的軟件源褥影。
一旦你明白Docker容器只是一個(gè)基礎(chǔ)的單進(jìn)程容器池户,只是一個(gè)應(yīng)用運(yùn)行的環(huán)境,它能讓你專注于應(yīng)用的構(gòu)建而不是其他雜七雜八的依賴關(guān)系校焦,你就會(huì)把Docker應(yīng)用到得心應(yīng)手。