DHorse系列文章之鏡像製作

DHorse系列文章之鏡像製作

製作鏡像常用的工具

使用Docker製作鏡像

1.使用docker commit製作
該命令使用比較簡單,可以自行網上搜索教程。
2.使用Dockerfile製作
這種方式,需要編寫如下的Dokerfile文件:

FROM openjdk:openjdk:13-jdk-alpine
ADD client-1.0.0.jar /client.jar
ENTRYPOINT ["java","-jar","/client.jar"]

並且執行如下命令:

docker build -t dhorse/client:102 .

才能完成鏡像的製作。
通過以上可以看出,如果要使用docker製作鏡像的話,必須要有docker環境,而且需要編寫Dockerfile文件。當然,也可以不用安裝docker環境,而且使用doker的遠程介面:post/build。但是,在遠程伺服器中仍然需要安裝doker環境和編寫Dockerfile。

DHorse的技術選型

DHorse作為一個簡單易用的DevOps開發平台,在一開始設計時就考慮到了對外部環境的依賴性。無論是從安裝還是從使用的角度,都應該盡量減少對外部環境的依賴,尤其是對docker的依賴。不依賴docker還有另外一個重要的原因,k8s在高版本也逐漸不依賴docker了。而DHorse主要還是基於k8s來實現部署的,因此DHorse在構建鏡像時更不能依賴docker環境。那麼,在不依賴docker的情況下,是否可以通過其他技術構建鏡像呢?答案是有的,比如通過Jib就可以實現。

Jib介紹

Jib是Google開源的一套工具,github地址,它是一個無需Docker守護進程——也無需深入掌握Docker最佳實踐的情況下,為Java應用程式構建Docker和OCI鏡像, 它可以作為Maven和Gradle的插件,也可以作為Java庫。

比如,使用jib-maven-plugin插件構建鏡像的程式碼如下:

<plugin>
	<groupId>com.google.cloud.tools</groupId>
	<artifactId>jib-maven-plugin</artifactId>
	<version>3.3.0</version>
	<configuration>
		<from>
			<image>openjdk:13-jdk-alpine</image>
		</from>
		<to>
			<image>gcr.io/dhorse/client</image>
			<tags>
				<tag>102</tag>
			</tags>
			<auth>
				<!--連接鏡像倉庫的帳號和密碼 -->
				<username>username</username>
				<password>password</password>
			</auth>
		</to>
		<container>
			<ports>
				<port>8080</port>
			</ports>
		</container>
	</configuration>
	<executions>
		<execution>
			<phase>package</phase>
			<goals>
				<goal>build</goal>
			</goals>
		</execution>
	</executions>
</plugin>

然後使用命令進行構建:

mvn compile jib:build

可以看出,無需docker環境就可以實現鏡像的構建。但是,要想通過平台類型的系統去為每個系統構建鏡像,顯然通過插件的方式,不太合適,因為需要每個被構建系統引入jib-maven-plugin插件才行,也就是需要改造每一個系統,這樣就會帶來一定的麻煩。那麼有沒有不需要改造系統的方式直接進行構建鏡像呢?答案是通過Jib-core就可以實現。

首先,在使用Jib-core的項目中引入依賴,maven如下:

<dependency>
	<groupId>com.google.cloud.tools</groupId>
	<artifactId>jib-core</artifactId>
	<version>0.22.0</version>
</dependency>

下面通過DHorse的程式碼,看Jib-core是如何使用的,如下:

try {
	JibContainerBuilder jibContainerBuilder = null;
	if (StringUtils.isBlank(context.getProject().getBaseImage())) {
		jibContainerBuilder = Jib.fromScratch();
	} else {
		jibContainerBuilder = Jib.from(context.getProject().getBaseImage());
	}
	//連接鏡像倉庫5秒超時
	System.setProperty("jib.httpTimeout", "5000");
	System.setProperty("sendCredentialsOverHttp", "true");
	String fileNameWithExtension = targetFiles.get(0).toFile().getName();
	List<String> entrypoint = Arrays.asList("java", "-jar", fileNameWithExtension);
	RegistryImage registryImage = RegistryImage.named(context.getFullNameOfImage()).addCredential(
			context.getGlobalConfigAgg().getImageRepo().getAuthUser(),
			context.getGlobalConfigAgg().getImageRepo().getAuthPassword());
	jibContainerBuilder.addLayer(targetFiles, "/")
		.setEntrypoint(entrypoint)
		.addVolume(AbsoluteUnixPath.fromPath(Paths.get("/etc/localtime")))
		.containerize(Containerizer.to(registryImage)
				.setAllowInsecureRegistries(true)
				.addEventHandler(LogEvent.class, logEvent -> logger.info(logEvent.getMessage())));
} catch (Exception e) {
	logger.error("Failed to build image", e);
	return false;
}

其中,targetFiles是要構建鏡像的目標文件,比如springboot打包後的jar文件。

通過Jib-core,可以很輕鬆的實現鏡像構建,而不需要依賴任何其他環境,也不需要被構建系統做任何改造,非常方便。

如果你的項目有此需求,也可以通過Jib-core來實現。