Docker筆記(五):整一個本身的鏡像

原文地址:http://blog.jboost.cn/docerk-5.htmlhtml

 

獲取鏡像的途徑有兩個,一是從鏡像倉庫獲取,如官方的Docker Hub,二是自定義。上文已經介紹如何從鏡像倉庫獲取鏡像,本文基於一個Springboot項目,來介紹自定義一個鏡像的基本流程。
java

1. 定製鏡像的本質

咱們知道鏡像是分層存儲的,鏡像的構建也是一層一層進行的,一層構建完後,就變爲只讀,在其上再構建下一層。所以定製鏡像,實際上就是定義每一層要乾的事,好比執行某個命令,設置一個環境變量,聲明一個暴露端口等等。而後在構建時,按照各層的定義,一層一層地完成構建,最終造成一個包含這些層的鏡像。nginx

2. Dockerfile文件

Docker中定義各層要乾的事的文件叫Dockerfile,它是一個文本文件,包含了一條條的指令,每一條指令對應一層鏡像,指令的內容就描述了這一層該如何構建。以下示例了一個很是簡單的Dockerfile,git

FROM nginx RUN echo '<h1>Hello jboost!</h1>' > /usr/share/nginx/html/index.html

 

咱們定製鏡像,必需要以某一個鏡像爲基礎,在其上構建本身須要的層,如上示例中,咱們是以nginx鏡像爲基礎,而後在第二層定製了咱們本身的內容——修改index.html的內容爲<h1>Hello jboost!</h1>,這樣運行容器打開nginx主頁時就不會顯示默認的頁面內容了。 github

上面示例中接觸了Dockerfile的兩個指令spring

  • FROM:FROM指令指定基礎鏡像,每個定製鏡像必需要有一個基礎鏡像,因此必需要有一條FROM指令,而且是Dockerfile的第一條指令
  • RUN:RUN指令指定須要執行的命令,後面接的命令就像是shell腳本同樣可執行

Dockerfile還提供了許多其它指令,後續咱們再集中介紹,本文只對接觸到的指令作簡單說明。docker

3. 自定義一個鏡像

這部分以一個Springboot項目爲基礎,介紹自定義一個鏡像涉及的基本環節。項目地址爲:https://github.com/ronwxy/swagger-register ,該項目是一個Swagger API文檔註冊服務,其它項目可將Swagger API信息註冊到該服務,進行統一查看與管理。shell

3.1 定義Dockerfile文件

首先,咱們在項目的根目錄下建立一個Dockerfile文件(文件名就叫Dockerfile),其內容爲:api

FROM openjdk:8-jdk-alpine ENV PROFILE=dev RUN mkdir /app /logs COPY ./target/swagger-register-1.0.0-SNAPSHOT.jar /app/app.jar WORKDIR /app VOLUME /register-data EXPOSE 11090 CMD ["java", "-Dspring.profiles.active=${PROFILE}", "-jar", "app.jar"]

 

從上往下依次介紹以下 瀏覽器

  • 第一行:FORM openjdk:8-jdk-alpine, 表示以openjdk:8-jdk-alpine這個鏡像爲基礎鏡像,由於這是一個Springboot項目因此必需要有jdk支持,咱們在定製鏡像時,能夠找一個最適合的鏡像做爲基礎鏡像。
  • 第二行:ENV PROFILE=dev, 定義了一個環境變量,這個環境變量能夠在後面被引用
  • 第三行:RUN mkdir /app /logs,經過mkdir命令建立了兩個目錄,用來保存jar執行文件及日誌
  • 第四行:COPY ./target/swagger-register-1.0.0-SNAPSHOT.jar /app/app.jar 將target目錄下的jar包複製到/app目錄下,而且進行重命名
  • 第五行:WORKDIR /app, 指定工做目錄爲/app,後面各層的當前目錄就是指定的工做目錄
  • 第六行:VOLUME /register-data, 定義一個匿名數據卷,前面說過寫操做不要直接在容器內進行,而要改成寫掛載的數據卷目錄,這個定義可在運行容器時經過 -v 來覆蓋。
  • 第七行:EXPOSE 11090, 聲明瞭運行容器時提供的服務端口,也僅僅是個聲明而已,只是告訴使用的人要映射這個端口,經過 -p 可映射端口。
  • 第八行:CMD [「java」, 「-Dspring.profiles.active=${PROFILE}」, 「-jar」, 「app.jar」], 指定了容器啓動命令,由於是一個Springboot項目,因此就是一個java -jar的執行命令,容器啓動的時候就會執行該命令來運行Springboot服務,這裏引用了第二行定義的環境變量PROFILE

3.2 配置maven插件

定義好Dockerfile後,爲了方便構建鏡像,咱們能夠藉助maven的dockerfile插件dockerfile-maven-plugin,在pom.xml的build部分加入配置以下

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <!-- Docker maven plugin -->
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>dockerfile-maven-plugin</artifactId>
            <version>1.4.10</version>
            <configuration>
                <repository>${docker.image.prefix}/${project.artifactId}</repository>
                <buildArgs>
                    <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                </buildArgs>
            </configuration>
        </plugin>
        <!-- Docker maven plugin -->
    </plugins>
</build>

 

repository指定了鏡像的名稱,docker.image.prefix須要properties部分進行定義,我這裏是springboot

3.3 構建鏡像

下載源碼:https://github.com/ronwxy/swagger-register.git ,而後在項目的根目錄下執行以下命令(前提是本地已經裝好了docker與maven及jdk)

mvn clean package -Dmaven.test.skip=true dockerfile:build


該命令首先會執行mvn clean package -Dmaven.test.skip=true對項目進行打包,生成./target/swagger-register-1.0.0-SNAPSHOT.jar文件,而後基於當前目錄下的Dockerfile文件進行構建,以下圖所示 

docker-build

由上圖可看出,該鏡像構建分八步(對應Dockerfile的八行指令),每一步生成一個鏡像層,每一層都有惟一的ID。由圖中也能夠看出,除了COPY之類的命令外,每一層的構建其實是先基於上一層啓動一個容器,而後執行該層定義的操做,再移除這個容器來實現的,如第八步中

Step 8/8 : CMD ["java", "-Dspring.profiles.active=${PROFILE}", "-jar", "app.jar"] [INFO] [INFO] ---> Running in f4acd0b53bca [INFO] Removing intermediate container f4acd0b53bca [INFO] ---> a9ee579f2d62

先啓動一個ID爲f4acd0b53bca的容器,在其中執行CMD所定義的命令,而後再移除容器f4acd0b53bca,最後生成ID爲a9ee579f2d62的鏡像。 

構建完後,咱們就能夠在本地鏡像中經過docker iamges看到咱們定製的鏡像了,如圖
docker-image

圖中springboot/swagger-register鏡像即爲咱們剛剛構建好的定製鏡像。

3.4 啓動容器

咱們能夠經過如下命令來啓動一個剛纔定製鏡像的容器

docker run -d --name swagger-register -p 11090:11090 -v /home/jenkins/swagger-register/register-data:/register-data -v /home/jenkins/swagger-register/logs:/logs --restart=always springboot/swagger-register:latest

其中: 

  • -d 表示之後臺進程方式運行
  • –name 指定容器名稱
  • -p 指定端口映射,左邊爲宿主機端口,右邊爲容器服務端口
  • -v 指定數據卷掛載,左邊爲宿主機目錄,右邊爲容器目錄
  • –restart=always 表示在docker啓動時自動啓動該容器

關於容器相關的內容後面詳細介紹,這裏不展開說明了。啓動容器後, 咱們就能夠瀏覽器打開地址 http://宿主機ip:11090/doc.html 來訪問服務了(打開頁面後內容是空的,由於沒有任何服務註冊Swagger API, 相關內容可參考 swagger api文檔集中化註冊管理

4. 總結

本文介紹了一個基於Springboot項目的Docker鏡像定製及使用過程,對鏡像的構建過程,及Dockerfile的基本指令以及容器的運行作了基本介紹。後續會對Dockerfile的其它指令及Dockerfile的一些最佳實踐進行更爲詳細的介紹,歡迎關注。


個人我的博客地址:http://blog.jboost.cn
個人微信公衆號:jboost-ksxy (一個不僅有技術乾貨的公衆號,歡迎關注,及時獲取更新內容)
—————————————————————————————————————————————————————
微信公衆號

 

 

原文出處:https://www.cnblogs.com/spec-dog/p/11204914.html

相關文章
相關標籤/搜索