你肯定打过docker镜像是吧,作为一个开发这很正常,那么你用的什么打包方式呢,这里我们来梳理几种常用的docker镜像构建方式。
ps:这里不是太讲原理,更多的是一种科普和操作。因为讲原理的东西网上已经够多了。

一、Dockerfile

dockerfile的打包方式很常见了,我们需要构建一个文件,名字必须就叫Dockerfile,没有后缀名。
我们举个例子,我现在有一个springboot项目,当我们构建出一个jar包的时候,我们就可以基于这个jar包来构建一个docker image。此时我们需要编写一个Dockerfile。比如这样

FROM openjdk:17

LABEL "org.opencontainers.image.authors"="areyouok"

COPY target/app-0.0.1-SNAPSHOT.jar accounts-0.0.1-SNAPSHOT.jar

ENTRYPOINT ["java", "-jar", "app-0.0.1-SNAPSHOT.jar"]

我们在这个dockerfile中描述了我们要执行的一组docker指令,然后我们使用docker build来构建镜像,此时就会基于这个文件来构建出我们需要的镜像。
但是这种模式存在一个问题,我们需要知道docker的一些指令,不然你无法构建出合理的镜像。
那么问题来了,我作为一个开发,要学的东西本身就一大堆了。你还要我去掌握这种相对属于运维的知识?我为啥要会docker呢,真就纯当牛马是吧。所以这种模式不好,他无法屏蔽我们对于docker知识的理解,而且我这个文件还比较简单,如果你是大型项目,dockerfile会很复杂,可能要考虑构建的体积,资源的占用以及构建的速度等等。这更加增大了我们的心智成本。至于那个什么docker compose也差不多一样。所以我们需要一种屏蔽底层命令的方式来帮助我们构建镜像。于是在这种需求下,业界产生两种新的构建模式,BuildPacks和Goole libs。下面我们就来看看这两种模式如何操作。

二、BuildPacks

其原理介绍可以参考BuildPacks介绍
我们只需要知道,这种模式不需要你编写什么构建文件,他会分析你的源代码,然后分析编译产生最终的docker image。而且他的构建是完全遵守docker的规范和协议的,构建的大小也是合理的。这个你不需要担心。对于开发来说实在是解放双手的不二选择。他的官网地址是BuildPacks官方地址
下面我们以一个springboot服务来演示一下这东西如何使用。
首先我们要明白BuildPacks是一个生态,在这个生态内有一个很方便的工具来使用,帮助我们构建镜像。那就是paketo
你能看到他支持多种应用的构建,其中自然包括java在这里插入图片描述

1、pom文件

首先你要确认你的pom文件是可以打包为jar的,当你有了这个配置哪你就要保证有maven对应的插件。也就是如下配置。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
     ......
	<packaging>jar</packaging>

    ......
    <build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>
	

这样我们就可以确保我们可以基于maven构建springboot对应的jar包。并且buildpacks也是基于这个来构建镜像的。当我们有了这个之后,我们还需要在配置中为镜像构建提供一些信息,比如名称之类的,好的,让我们来修改一下我们的pom配置。

 ......
 <artifactId>loans</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>loans</name>
	<packaging>jar</packaging>
......

<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
				<!--这里做了修改-->
					<image>
						<name>levi/${project.artifactId}:s4</name><!--你的镜像名称和版本号,你可以取一个你能标识的,我这里用的就是服务的坐标名称,版本号s4-->
					</image>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

ok,至此我们的配置就简单的改完了,当然你还可以配置一些其他的诸如作者信息等等。你可以看到非常简单,他会分析你的pom文件中的结构信息包括jdk版本之类的构建对应的镜像结构。

2、mvn构建

此时让我们借助idea的maven工具并且使用mvn spring-boot:build-image来构建镜像,他会在后台为我们通过buildpacks来构建镜像,其实就是maven其实集成了这个功能而已。或者你也可以直接在dos窗口用mvn命令,我因为没配maven环境变量所以懒得弄了。当然你要先启动你的docker服务。
在这里插入图片描述

第一次构建可能会稍微耗时一点,可以略微等一等,但是他是增量的,第二次就快了。
最终我们可以看到构建成功了.
在这里插入图片描述
此时我们就可以使用命令看看我们是不是有这个镜像了。
在这里插入图片描述
没有问题,名称和版本都是我们指定的。接下来你就可以使用这个镜像了。

三、google jib

这个工具是谷歌公司搞得,你可以在github上看到他google jib
你可以在介绍中看到,他其实也是可以构建多语言应用的镜像,自然也是包括java的。所以我们完全可以使用。
而且支持maven插件,我们可以点进去链接,然后按照教程使用即可。
在这里插入图片描述

1、pom文件

按照教程我们要在我们的pom文件中添加一个插件。

<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>jib-maven-plugin</artifactId>
  <version>3.3.2</version>
  <configuration>
    <to>
      <image>myimage</image>
    </to>
  </configuration>
</plugin>

所以我们要修改一下我们的pom文件。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	......
	<artifactId>cards</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>
	......
	<build>
		<plugins>
			<plugin>
				<groupId>com.google.cloud.tools</groupId>
				<artifactId>jib-maven-plugin</artifactId>
				<version>3.3.2</version>
				<configuration>
					<to>
						<image>levi/${project.artifactId}:s4</image><!--这里还是名字,版本-->
					</to>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

此时刷新你的pom,你会看到idea就为你引入了这个插件。

2、mvn构建

在这里插入图片描述
此时你就可以使用这个来构建了,当然你依然可以使用mvn命令(mvn compile jib:dockerBuild)如果你配置了环境变量的话。
所以我们可以直接在idea插件中运行即可。
在这里插入图片描述
ok,我们可以看到最后是构建成功的。
在这里插入图片描述
我们再次查看一下我们的镜像库。
在这里插入图片描述
没有任何问题。而且前面的几种方式不管是dockerfile还是buildpacks你至少本地得有个docker服务,也就是docker环境。但是google jib甚至不需要你装docker服务,就是这么简单。但是你的运行环境还是要有的,毕竟你最终是要启动容器的。他只是在构建的时候不需要docker环境。而且如果你用jibs构建的时候,最好先把你的jar给打出来,然后再执行构建。不然会有一些奇怪的错误。
但是这对于我们实际是很有帮助的,比如你在公司配置jeckens这种自动构建,你完全可以不用docker了,只需要配置构建即可。
当然他还有很多配置,你可以参考文档。

四、总结

至此我们就介绍了常用的几种构建模式,我们看到其实各有利弊吧。看你喜欢哪一种了,只是后面两种不需要你掌握太多docker知识,更加专注于业务开发。
在buildpacks的官方文档下面有一个对比的表格,我们可以看到各类构建的优劣。
构建模式大比武
当然,很多时候这种带点吹自己贬别人,你如果不相信他的说法,可以自己测试一下,相信结果。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐