上一章節,主要是介紹了下
Dockerfile
的一些經常使用命令的說明。咱們知道,利用Dockerfile
能夠構建一個新的鏡像,好比運行Java
環境,就須要一個JDK
環境的鏡像,但直接使用公共的鏡像時,通常上大小都比較大。因此本章節就主要結合Dockerfile
文件及commit
方式,構建屬於本身的鏡像,同時對鏡像進行壓縮和優化,同時也是對Dockerfile
知識的一個實踐。html
做爲一個
java
後端開發,這裏就直接以構建一個Oracle官方jre
環境來示例。java
因爲在Linux中,
JVM
主要是調用系統的C語言庫,Oracle的官方JRE,使用的是libc,也就是glibc
,這意味着你要運行任何Java程序,都須要先裝好glibc
。因此咱們直接去https://hub.docker.com
找一個基於glibc
的基礎鏡像(固然了,你們也可直接選定好比CensOS
這些Linux的發行版本了)。linux
咱們之類直接選擇默認排在第一個的alpine-glibc
做爲咱們的基礎鏡像,比較這個大小也才12M左右呀!spring
題外話:你們做爲實驗性質時,爲了獲取更小的基礎鏡像,能夠選擇alpine
這個基礎鏡像,比較這個只有5M大小,夠精簡了!docker
這裏咱們直接去Oracle官網選擇
jre
版本,這裏選擇的是jre-8u181-linux-x64
版本(因爲對linux命令不是很熟悉,爲了避免必要的時間浪費,這裏直接下載了鏡像了,熟悉的各位能夠直接使用wget
進行下載的)。後端
# 基礎鏡像 FROM frolvlad/alpine-glibc LABEL MAINTAINER oKong <499452441@qq.com> # 將JRE添加至鏡像中,add 命令在源文件爲壓縮文件時,會自動解壓的 ADD jre-8u181-linux-x64.tar.gz /opt/docker/java/jre8 # 設置JAVA環境變量 # 這裏須要注意下,解壓後有個目錄的,爲jre1.8.0_181,一開始沒注意,啓動時報了:exec: "java": executable file not found in $PATH: unknown 後才發現。 ENV JAVA_HOME /opt/docker/java/jre8/jre1.8.0_181 ENV CLASSPATH=$JAVA_HOME/bin ENV PATH=.:$JAVA_HOME/bin:$PATH # 這裏無實際意義,只是在容器啓動時,輸出jre版本信息,驗證是否安裝成功 CMD ["java","-version"]
利用build
命令,構建鏡像,同時指定tag
:tomcat
docker build -t lqdev.cn/jre8:0.1 .
注意:後面有個.
的。springboot
Sending build context to Docker daemon 81.19MB Step 1/7 : FROM frolvlad/alpine-glibc ---> d3bc626306a1 Step 2/7 : LABEL MAINTAINER oKong <499452441@qq.com> ---> Running in e788d29cd1e1 Removing intermediate container e788d29cd1e1 ---> 5d95db4ae169 Step 3/7 : ADD jre-8u181-linux-x64.tar.gz /opt/docker/java/jre8 ---> 0f4bb83df722 Step 4/7 : ENV JAVA_HOME /opt/docker/java/jre8/jre1.8.0_181 ---> Running in 57a1e1ef00ed Removing intermediate container 57a1e1ef00ed ---> 6f2b543a91b7 Step 5/7 : ENV PATH ${PATH}:${JAVA_HOME}/bin ---> Running in 2d75c88f97fb Removing intermediate container 2d75c88f97fb ---> 92a7a0f9926c Step 6/7 : WORKDIR /opt/docker/java/jre8/jre1.8.0_181 ---> Running in 7b9a69efc980 Removing intermediate container 7b9a69efc980 ---> 158c08c995c3 Step 7/7 : CMD ["java","-version"] ---> Running in 9ab517f8292a Removing intermediate container 9ab517f8292a ---> 9c8606ac315a Successfully built 9c8606ac315a Successfully tagged lqdev.cn/jre8:0.1
而後查看下鏡像列表,bash
docker images
說明已經構建成功了,咱們來運行下:app
docker run -it -d --name myfirstjre lqdev.cn/jre8:0.1
查看下容器列表:
docker ps -a
因爲Dockerfile
中使用CMD
命令覆蓋了本來的/bin/sh
,容器已啓動就中止了。因此咱們看下日誌,就知道是否jre
安裝成功。
docker logs -f c6873a97ff49
輸出了版本信息了,說明已經安裝成功了。
如今咱們就能夠基於這個jre鏡像進行實際的jar包部署了。
Dockerfile
文件方式:
# 基於咱們自定義構建的鏡像 FROM lqdev.cn/jre8:0.1 VOLUME /opt/tmp # 這是jar 可自行選擇,這裏直接使用了原先講解springboot十四章節:基於Docker部署時的jar包 ADD chapter-14-0.0.1-SNAPSHOT.jar app.jar # -Djava.security.egd=file:/dev/./urandom 可解決tomcat可能啓動慢的問題 # 具體可查看:https://www.cnblogs.com/mightyvincent/p/7685310.html ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] # 對外端口 EXPOSE 8080
而後構建新鏡像,並運行,同時查看日誌輸出
docker run -it -d --name springboot lqdev.cn/springboot:0.1
日誌控制檯:
運行的容器列表:
說明咱們已經成功了,jar也啓動了。如今訪問下部署的jar服務:
在第三章講解
Docker
經常使用命令時,有說到,利用commit
可從容器中構建一個新的鏡像。因此這裏簡單講解下利用此命令進行自動鏡像的構建過程。
構建思路:咱們啓動一個基礎鏡像,同時運行,而後咱們進入容器,下載所須要的jre版本,並配置其環境變量。以後退出容器進行保存操做。這裏就不直接下載了,咱們直接拷貝jre到容器裏
啓動基礎鏡像:
docker run -it -d --name commitImages frolvlad/alpine-glibc
拷貝jre到容器中。
docker cp /opt/docker/java/jre-8u181-linux-x64.tar.gz b0d354b9453a:/opt/docker/java/jre8
這裏會提示,說目錄不存在,可利用exec命令,進入容器建立目錄下,這裏就不演示了。
No such container:path: b0d354b9453a:/opt/docker/java
如今咱們進入容器:
docker exec -it b0d354b9453a /bin/sh
進入,/opt/docker/java/jre8
目錄,進行常規linux下的jre安裝:
cd /opt/docker/java/jre8 # 解壓 tar -xzvf jre-8u181-linux-x64.tar.gz # 配置環境變量,vi /etc/profile 末尾加入 export JAVA_HOME=/opt/docker/java/jre8/jre1.8.0_181 export CLASSPATH=$JAVA_HOME/bin export PATH=.:$JAVA_HOME/bin:$PATH # 生效配置 source /etc/profile # 驗證是否成功 java -version 輸出: java version "1.8.0_181" Java(TM) SE Runtime Environment (build 1.8.0_181-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode) # 這裏有個坑,生效配置後退出容器後又失效了,搜索了後,把環境變量放在### ~/.bashrc 或者在~/.bashrc裏面加一句source /etc/profile 可是仍是未生效。。。。我放棄了。。 直接寫個sh腳本啓動 時加入吧。。
而後咱們退出容器,利用commit
命令進行構建新鏡像:
docker commit b0d354b9453a lqdev.cn/jre8:0.2
而後查看:
運行jar,驗證下是否正常,這裏直接在啓動的時候拷貝jar到鏡像。
docker run -it -d -p 1234:8080 -v /opt/docker/java:/opt/docker/java/app.jar --name springboot2 lqdev.cn/jre8:0.2
而後進入容器運行下java 命令
# 進入容器 docker exec -it 583d0f387555 /bin/sh # 生效配置 source etc/profile # 運行jar nohup java -Djava.security.egd=file:/dev/./urandom -jar /opt/docker/java/app.jar >log.txt &
退出後,訪問宿主的1234端口服務,就能看見部署成功了:
其實比較好的作法是:建立一個sh
腳本,腳本里設置了環境生效命令及java命令便可,你們可自行嘗試下,這裏就不演示了。
上一章節,咱們利用Dockerfile
和commit
的方式生成鏡像。如今咱們看下,鏡像文件大小:
兩種方式,commit還多了80M多。這裏咱們本着精簡的原則,對鏡像大小進行優化下。
首先,鏡像文件是按
鏡像層(Layers)
進行疊加的。總的來講就是:每一條指令都會建立一個鏡像層,繼而會增長總體鏡像的大小。
一個基礎鏡像的大小直接決定了新鏡像的大小,因此能夠選擇儘可能小的精簡的鏡像。本文就使用了alpine-glibc
做爲基礎鏡像,大小12.8M。
多個RUN時,可經過 && 和 / 支持將命令串聯在一塊兒
# 舉例 RUN yum -y install java-1.7.0-openjdk-devel && yum clean all
不少鏡像大部分都是經過此方式進行RUN方式編寫的。官網:https://hub.docker.com/裏面的大部分鏡像都是以下寫法
好比jre
包中就有不少的文檔及說明文件是非必要的,這些就能夠刪除了。如下只是個參考,你們能夠自行刪減,能夠在Dockerfile
編寫時,解壓後,使用RUN
命令進行操做也能夠直接把壓縮包裏刪除後在拷貝:
rm -rf COPYRIGHT LICENSE README release THIRDPARTYLICENSEREADME-JAVAFX.txtTHIRDPARTYLICENSEREADME.txt Welcome.html #刪除其餘無用文件 rm -rf lib/plugin.jar \ lib/ext/jfxrt.jar \ bin/javaws \ lib/javaws.jar \ lib/desktop \ plugin \ lib/deploy* \ lib/*javafx* \ lib/*jfx* \ lib/amd64/libdecora_sse.so \ lib/amd64/libprism_*.so \ lib/amd64/libfxplugins.so \ lib/amd64/libglass.so \ lib/amd64/libgstreamer-lite.so \ lib/amd64/libjavafx*.so \ lib/amd64/libjfx*.so
對比下,確實少了不少了。
固然對於大小不關心的,也就無需理會了,畢竟如今存儲空間都很大的,也就可能傳輸的時候慢點,哈哈~
鏡像優化的你們可看看如下幾篇文章或者自行搜索下相關資料:
本章節主要是介紹如何利用
Dockerfile
或者commit
方式構建自定義鏡像。經過這兩種方式,咱們就能根據本身的實際業務須要進行個性化改造、優化,最終構建一個通用鏡像。在構建本身的鏡像時,儘可能仍是選擇本身熟悉的、穩定的基礎環境鏡像進行構建,畢竟出了問題找起來也熟門熟路點。一般,運維部門或者實施部門,制定的鏡像屬於資產,通常不會上送至Docker
遠程倉庫的,有了鏡像,咱們就須要有個地方去存儲。下一章節,就重點講解下如何構建私有倉庫,管理本身的鏡像文件!
若文中有錯誤或者遺漏之處,還望指出,共同進步!
499452441
lqdevOps
我的博客:http://blog.lqdev.cn