Java项目镜像化之Dockerfile

最近公司准备将项目进行容器化部署,因此我对Docker相关的知识进行了些了解和学习, 因此写篇日志记录下。

Docker组成

Docker作为C/S架构其主要由三部分组成:

  • Client,也就是我们在命令行中使用的docker,其作为客户端是用户与 Docker 交互的主要方式
  • Docker daemon,也就是服务端启动的dockerd作为守护进程,监听Docker客户端请求并管理 Docker 对象,例如图像、容器、网络和卷
  • Registry: 存储 Docker 镜像

Docker的安装

关于Docker的安装可以查看官方文档,这里选取了些我个人认为比较重要的参数进行一些记录说明:

  • -HDocker守护进程监听的地址,例:dockerd -H unix:///var/run/docker.sock -H tcp://192.168.59.106表示监听sock和tcp的连接,这样可以可以为本机减负,将服务端交由其他机器处理
  • --registry-mirror指定镜像地址,这个主要是用来加速镜像的下载速度,例:dockerd --registry-mirror 'https://xxxxx'
  • --data-root指定镜像,容器,卷,网络等对象的存放位置,系统磁盘容量较小时需要更换此位置至容量大的盘,默认放在/var/lib/docker

Java镜像构建方式

目前Java有如下几种镜像的构建方式

  • Dockerfile
  • Jib
  • CNB

这几种各有优劣,可按需进行选择,本期主要讲下Dockerfile

Dockerfile

Dockerfile是docker推出的一种构建镜像的方式,通过docker build调用Dockerfile中的指令发送给服务端进行镜像的构建,如下所示

1
2
3
4
5
6
7
8
9
10
11
┌────────────┐
│ │
│ Dockerfile ├────┐
│ │ │ ┌─────────┐
└────────────┘ │ build │ │
├────────►│ image │
┌────────────┐ │ │ │
│ │ │ └─────────┘
│ context ├────┘
│ │
└────────────┘

由于实际构建过程是在docker服务端下完成的,此时无法是用到本机文件的。因此将会指定一个目录作为上下文的一起打包发送docker 引擎, 需要注意的是在上下文路径下不要放无用文件,过多无用的文件会造成构建过程缓慢。未指定上下文时, 上下文路径为 Dockerfile 所在的目录。

Java中的使用

本人使用的是fabric8的maven构建插件。如下是个对于SpringBoot的一个简单例子:

Dockerfile

1
2
3
4
5
6
FROM openjdk:8-jdk-alpine
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker-maven-plugin.version}</version>
<configuration>
<dockerHost>tcp://192.168.x.x:2375</dockerHost>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>

使用mvn package之后就会向192.168.x.x所在的docker服务端进行镜像的构建,生成的镜像也会放在该机器上。

写在最后

本期Dockerfile的一个简单使用示例,对docker不那么熟悉的人大概就会这么用,但再深入去学习的话你就会发现上述Dockerfile用法其实存在一定性能和资源浪费问题。不过使用Dockerfile的好处是如果你掌握使用技巧之后就可以灵活且高效的控制镜像的构建同时避免性能问题。