1. 程式人生 > >Dockerfile生成映象並實現應用自啟

Dockerfile生成映象並實現應用自啟

初學docker,磕磕絆絆經歷了很多坑,終於摸著點門路,趁手熱趕緊記下來,後面溫習改進。本篇的主要內容是,通過dockerfile檔案,生成一個新映象,並且實現映象在啟容器時,容器中應用自啟動。
關於docker的基本操作和基礎映象這裡就不再贅述了,我基於的基礎映象是centos7.0。

第1步,準備jdk1.7壓縮包,並解壓

# wget http://zhibo100.oss-cn-hangzhou.aliyuncs.com/software/jdk-7u79-linux-x64.tar.gz

# tar -zxvf jdk-7u79-linux-x64.tar.gz

第2步,編輯dockerfile檔案(涉密部分x代替)

FROM 基礎映象:1.2
MAINTAINER xxxxxxxxxxxxxxxxxx.com

COPY jdk1.7.0_79 jdk1.7.0_79

ENV JAVA_HOME=/jdk1.7.0_79
ENV PATH=$JAVA_HOME/bin:$PATH
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

EXPOSE 20110
EXPOSE 20140
EXPOSE 20410
EXPOSE 20440

ENTRYPOINT ["java","-jar","/esb/lib/xxxxxx.jar"]

第3步,生成映象(注意命令後面有一個 . )

# docker build -t 新映象名 .

步驟看著很簡單是吧?對於新手真是踩坑踩的不要不要的

1,如何進行容器中埠與宿主機的埠對映?
這是我在操作過程中遇到的第一個坑,先來認識兩個引數:

-p 可以指定要對映的埠,並且在一個指定埠上只可以繫結一個容器
-P 它會隨機對映一個埠至容器內部開放的網路埠

對於指定埠對映,可以採用如下命令去啟動容器

# docker run -d -it -p 宿主機埠:容器埠 -p 8088:8080 --name 容器名 映象名:版本號

另外一種,就是本文dockerfile採用的這一種了,dockerfile中EXPOSE命令字,EXPOSE 指令是宣告執行時容器提供服務埠,這只是一個宣告,在執行時並不會因為這個宣告應用就會開啟這個埠的服務。在 Dockerfile 中寫入這樣的宣告有兩個好處,一個是幫助映象使用者理解這個映象服務的守護埠,以方便配置對映;另一個用處則是在執行時使用隨機埠對映時,也就是 docker run -P 時,會自動隨機對映 EXPOSE 的埠。
生成容器時使用命令

# docekr run -d -it -P --name 容器名 映象名:版本號

2,如何實現容器在啟動時,應用自啟動
這裡描述一個之前失敗的一個思路,並且總結從中學習到的東西。
容器中放一個啟動指令碼檔案(.sh),然後在dockerfile中用CMD命名去執行;
然後出現了一個問題:容器啟動後自動退出,並且應用沒啟
通過查詢發現,Docker 在執行shell的時候,是在後臺執行的;因此,在shell執行完成以後,docker檢測到沒有前臺任務需要執行,便退出container。在shell指令碼的最後加上一個“永遠完成不了”的命令:

# tail -f /dev/null

進一步來探尋這個問題
Docker 不是虛擬機器,容器中的應用都應該以前臺執行,而不是像虛擬機器、物理機裡面那樣,用 upstart/systemd 去啟動後臺服務,容器內沒有後臺服務的概念。對於容器而言,其啟動程式就是容器應用程序,容器就是為了主程序而存在的,主程序退出,容器就失去了存在的意義,從而退出,其它輔助程序不是它需要關心的東西。因此主程序實際上是 sh。那麼當 service nginx start 命令結束後,sh 也就結束了,sh 作為主程序退出了,自然就會令容器退出。
所以我後來採取了直接執行jar包