本文介紹了使用Maven插件構(gòu)建Docker鏡像的方法珊蟀,分享給大家菊值,具體如下:
工具
工欲善其事,必先利其器育灸。筆者經(jīng)過調(diào)研腻窒,有以下幾款Docker的Maven插件進(jìn)入筆者視野。
插件名稱+官方地址
docker-maven-plugin https://github.com/spotify/docker-maven-plugin
docker-maven-plugin https://github.com/fabric8io/docker-maven-plugin
docker-maven-plugin https://github.com/bibryam/docker-maven-plugin
修改宿主機(jī)配置(docker可以遠(yuǎn)程訪問)
- 修改宿主機(jī)的docker配置磅崭,讓其支持遠(yuǎn)程訪問儿子。
vi /usr/lib/systemd/system/docker.service
開啟docker遠(yuǎn)程API,修改docker配置文件 docker.service進(jìn)入編輯模式后砸喻。
ExecStart=后添加配置-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
保存后退出柔逼,重新加載配置文件#systemctl daemon-reload ,啟動docker #systemctl start docker 。
- 刷新配置割岛,重新服務(wù)
systemctl daemon-reload
systemctl restart docker
配置 DOCKER_HOST
docker-maven-plugin 插件默認(rèn)連接本地 Docker 地址為:localhost:2375愉适,所以我們需要先設(shè)置下環(huán)境變量。
DOCKER_HOST=tcp://<host>:2375
注意:如果沒有設(shè)置 DOCKER_HOST 環(huán)境變量癣漆,可以命令行顯示指定 DOCKER_HOST 來執(zhí)行维咸,如我本機(jī)指定 DOCKER_HOST:DOCKER_HOST=tcp://<host>:2375
例如
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock ,這里就寫4個0惠爽,你可別改成自己的ip哦癌蓖,
輸入
#netstat -anp|grep 2375
顯示docker正在監(jiān)聽2375端口,輸入#curl 127.0.0.1:2375/info 顯示一大堆信息婚肆,證明遠(yuǎn)程api就弄好了在windows系統(tǒng)環(huán)境變量中新建DOCKER_HOST,值為tcp://10.100.74.220:2375租副,(你改成你自己的docker服務(wù)器ip地址)
使用插件構(gòu)建Docker鏡像
在我們持續(xù)集成過程中,項(xiàng)目工程一般使用 Maven 編譯打包较性,然后生成鏡像用僧,通過鏡像上線,能夠大大提供上線效率赞咙,同時(shí)能夠快速動態(tài)擴(kuò)容永毅,快速回滾,著實(shí)很方便人弓。docker-maven-plugin 插件就是為了幫助我們在Maven工程中,通過簡單的配置着逐,自動生成鏡像并推送到倉庫中崔赌。
添加插件
在pom.xml中添加下面這段:
<build>
添加相關(guān)的鏡像插件
</build>
構(gòu)建鏡像
構(gòu)建鏡像可以使用一下兩種方式意蛀,第一種是將構(gòu)建信息指定到 POM 中,第二種是使用已存在的 Dockerfile 構(gòu)建健芭。(支持將 FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD 信息配置在 POM 中县钥,不需要使用 Dockerfile 配置。)
第一種方式,支持將 FROM, ENTRYPOINT, CMD, MAINTAINER 以及 ADD 信息配置在 POM 中慈迈,不需要使用 Dockerfile 配置
第二種方式,如果使用 VOLUME 或其他 Dockerfile 中的命令的時(shí)候若贮,需要創(chuàng)建一個 Dockerfile,并在 POM 中配置 dockerDirectory 來指定路徑即可痒留。(創(chuàng)建一個 Dockerfile谴麦,并在 POM 中配置 dockerDirectory 來指定路徑即可)
添加docker-maven-plugin
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<imageName>{dockerhub名稱/imageName}</imageName>
<imageTags>
<imageTag>{imageTag}</imageTag>
</imageTags>
<baseImage>{baseImage}</baseImage>
<entryPoint>{end[point]}</entryPoint>
<maintainer>author author@email.com</maintainer>
<workdir>/ROOT</workdir>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
-
{dockerhub名稱/imageName}:
dockerhub名稱:對應(yīng)DockerHub用戶名,伸头,一定要是符合正則[a-z0-9-_.]的匾效,否則構(gòu)建不會成功
imageName:對應(yīng) DockerHub 倉庫名,一定要是符合正則[a-z0-9-_.]的恤磷,否則構(gòu)建不會成功
可以直接指定:
{project.artifactId}
{imageTag}:鏡像標(biāo)簽面哼,相當(dāng)于標(biāo)簽或者版本,latest扫步。
{baseImage}: 指定基礎(chǔ)鏡像魔策,等同 FROM 指令,例如:java河胎,當(dāng)然可以不用闯袒,直接在dockerfile文件中生成。
{endpoint}:// 等同于 ENTRYPOINT 指令仿粹,例如: ["java","-jar","app.jar"]
這里是復(fù)制 jar 包到 docker 容器指定目錄配置搁吓,也可以寫到 Dockerfile中
{project.build.directory}:指定要復(fù)制的根目錄,${project.build.directory} 表示 target 目錄吭历。
{project.build.finalName}:指定要復(fù)制的文件堕仔,${project.build.finalName}.jar 指打包后的 jar 文件。
resources.resource.targetPath:將打包后的資源文件復(fù)制到該目錄晌区;
resources.resource.directory:需要復(fù)制的文件所在目錄摩骨,maven打包的應(yīng)用jar包保存在target目錄下面;
resources.resource.include:需要復(fù)制的文件朗若,打包好的應(yīng)用jar包恼五。
讀取 Dockerfile 文件就不必指定 baseImage 和 entrypoint
- 指定要讀取的Dockerfile文件:
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
創(chuàng)建Dockerfile
\src\main\docker
內(nèi)容如下
FROM java:8
VOLUME /tmp
ADD admin-service-80-0.0.1-SNAPSHOT.jar admin-service-80.jar
RUN bash -c 'touch /admin-service-80.jar'
EXPOSE 80
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","${project.build.finalName}.jar"]
執(zhí)行以下命令構(gòu)建 Docker 鏡像
mvn clean package docker:build
[INFO] --- docker-maven-plugin:1.0.0:build (default-cli) @ mavenDemo ---
[INFO] Building image mavendemo
Step 1/5 : FROM java
---> d23bdf5b1b1b
Step 2/5 : MAINTAINER docker_maven docker_maven@email.com
---> Using cache
---> 2faf180d4a50
Step 3/5 : WORKDIR /ROOT
---> Using cache
---> 862210f7956a
Step 4/5 : ENTRYPOINT java -jar mavenDemo.jar
---> Running in 96bbe83de6ec
---> c29009c88993
Removing intermediate container 96bbe83de6ec
Step 5/5 : CMD java -version
---> Running in f69b8d2a75b1
---> bc8d54014325
Removing intermediate container f69b8d2a75b1
Successfully built bc8d54014325
執(zhí)行 docker images 查看剛才構(gòu)建的鏡像
執(zhí)行命令
- mvn clean package docker:build:只執(zhí)行 build 操作
- mvn clean package docker:build -DpushImage 執(zhí)行 build 完成后 push 鏡像
- mvn clean package docker:build -DpushImageTag 執(zhí)行 build 并 push 指定 tag 的鏡像
注意:這里必須指定至少一個 imageTag,它可以配置到POM 中哭懈,也可以在命令行指定灾馒。
命令行指定如下:
mvn clean package docker:build -DpushImageTags -DdockerImageTags=imageTag_1 -DdockerImageTags=imageTag_2,POM 文件中指定配置如下:
<build>
<plugins>
...
<plugin>
<configuration>
...
<imageTags>
<imageTag>imageTag_1</imageTag>
<imageTag>imageTag_2</imageTag>
</imageTags>
</configuration>
</plugin>
...
</plugins>
</build>
綁定Docker 命令到 Maven 各個階段
可以綁定 Docker 命令到 Maven 各個階段遣总,我們可以把 Docker 分為 build睬罗、tag轨功、push,然后分別綁定 Maven 的 package容达、deploy 階段古涧。
只需要執(zhí)行mvn deploy就可以完成整個 build、tag花盐、push操作了羡滑,當(dāng)我們執(zhí)行mvn build就只完成 build、tag 操作算芯。
除此此外柒昏,當(dāng)我們想跳過某些步驟或者只執(zhí)行某個步驟時(shí),不需要修改 POM 文件也祠,只需要指定跳過 docker 某個步驟即可昙楚。比如當(dāng)我們工程已經(jīng)配置好了自動化模板了,但是這次我們只需要打鏡像到本地自測诈嘿。
不想執(zhí)行 push 階段堪旧,那么此時(shí)執(zhí)行要指定參數(shù)-DskipDockerPush就可跳過 push 操作了。
以上示例奖亚,當(dāng)我們執(zhí)行mvn package時(shí)淳梦,執(zhí)行 build、tag 操作昔字,當(dāng)執(zhí)行mvn deploy時(shí)爆袍,執(zhí)行build、tag作郭、push 操作陨囊。如果我們想跳過 docker 某個過程時(shí),只需要:
- -DskipDockerBuild 跳過 build 鏡像
- -DskipDockerTag 跳過 tag 鏡像
- -DskipDockerPush 跳過 push 鏡像
- -DskipDocker 跳過整個階段
例如:我們想執(zhí)行 package 時(shí)夹攒,跳過 tag 過程蜘醋,那么就需要mvn package -DskipDockerTag。
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<imageName>mavendemo</imageName>
<baseImage>java</baseImage>
<maintainer>docker_maven docker_maven@email.com</maintainer>
<workdir>/ROOT</workdir>
<cmd>["java", "-version"]</cmd>
<entryPoint>["java", "-jar", "${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/ROOT</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
<execution>
<id>tag-image</id>
<phase>package</phase>
<goals>
<goal>tag</goal>
</goals>
<configuration>
<image>mavendemo:latest</image>
<newName>docker.io/wanyang3/mavendemo:${project.version}</newName>
</configuration>
</execution>
<execution>
<id>push-image</id>
<phase>deploy</phase>
<goals>
<goal>push</goal>
</goals>
<configuration>
<imageName>docker.io/wanyang3/mavendemo:${project.version}</imageName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
docker-maven-plugin 插件還提供了很多很實(shí)用的配置咏尝,稍微列舉幾個參數(shù)吧压语。
安全認(rèn)證配置
當(dāng)我們 push 鏡像到 Docker 倉庫中時(shí),不管是共有還是私有编检,經(jīng)常會需要安全認(rèn)證胎食,登錄完成之后才可以進(jìn)行操作。當(dāng)然允懂,我們可以通過命令行
docker login -u user_name -p password docker_registry_host
登錄厕怜,但是對于自動化流程來說,就不是很方便了。使用 docker-maven-plugin 插件我們可以很容易實(shí)現(xiàn)安全認(rèn)證粥航。
首先在 Maven 的配置文件 setting.xml 中增加相關(guān) server 配置舵揭,主要配置 Docker registry用戶認(rèn)證信息。
<servers>
<server>
<id>my-docker-registry</id>
<username>wanyang3</username>
<password>12345678</password>
<configuration>
<email>wanyang3@mail.com</email>
</configuration>
</server>
</servers>
然后只需要在 pom.xml 中使用 server id 即可躁锡。
<plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<imageName>registry.example.com/wanyang3/mavendemo:v1.0.0</imageName>
...
<serverId>my-docker-registry</serverId>
</configuration>
</plugin>
使用私有Docker倉庫地址
實(shí)際工作環(huán)境中,我們需要 push 鏡像到我們私有 Docker 倉庫中置侍,使用d ocker-maven-plugin 插件我們也是很容易實(shí)現(xiàn)映之,有幾種方式實(shí)現(xiàn):
修改 POM 文件 imageName 操作
<configuration>
<imageName>{privateImageHubUrl}/imageName/tag</imageName>
...
</configuration>
以以上的格式進(jìn)行輸出即可。
修改 POM 文件中 newName 操作
<configuration>
<imageName>mavendemo</imageName>
...
</configuration>
<execution>
<id>tag-image</id>
<phase>package</phase>
<goals>
<goal>tag</goal>
</goals>
<configuration>
<image>mavendemo</image>
<newName>{privateImageHubUrl}/imageName/tag</newName>
</configuration>
</execution>
重新啟動Docker服務(wù)
systemctl stop docker
systemctl start docker
開啟防火墻的Docker構(gòu)建端口
firewall-cmd --zone=public --add-port=2375/tcp --permanentfirewall-cmd --reload