使用spotify maven插件在构建Docker镜像时更改小二进制文件

时间:2017-04-03 09:44:17

标签: java maven docker

我使用spotify的docker-maven-plugin来构建泊坞窗图像。更确切地说是这个:

<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>

我的开发机器有一个Windows 7,所以我正在运行版本为docker-machine version 0.9.0, build 15fd4c7的docker机器 Docker版本就是这个

Client:
 Version:      1.13.1
 API version:  1.26
 Go version:   go1.7.5
 Git commit:   092cba3
 Built:        Wed Feb  8 08:47:51 2017
 OS/Arch:      windows/amd64

Server:
 Version:      17.03.0-ce
 API version:  1.26 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   3a232c8
 Built:        Tue Feb 28 07:52:04 2017
 OS/Arch:      linux/amd64
 Experimental: false

我的应用程序使用我想提前准备的证书并包含在图像中。

如果我使用Docker cli直接构建Docker镜像,它可以正常传输带有证书的密钥库文件。

如果我使用spotify maven插件构建Docker镜像,则密钥库文件将被破坏。比较显示它的大小要大得多,它的内容(hexdump)的比较看起来像是撒了(我不知道怎么说更好)和额外的字节。

我创建了一个显示行为的小例子: 项目结构:

-src
|-main
| |-docker
|   |-binaries
|   | |-example.jks
|   |-Dockerfile
|-pom.xml

像这样创建example.jks(使用openjdk 8中的keytool)

keytool -genkey -keyalg RSA -alias selfsigned -keystore example.jks -storepass password -keypass password -validity 18250 -keysize 2048 -dname "CN=Unknown, OU=Example, O=Example, L=Example, ST=Unknown, C=US" 

的pom.xml

<?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 http://maven.apache.org/maven-v4_0_0.xsd">


    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>smallbinary</artifactId>
    <name>Small binary problem</name>
    <version>1.0</version>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <resources>
            <resource>
                <!--
                 | Enable resource filtering pre dockerfile build calls.
                 -->
                <directory>src/main/docker</directory>
                <targetPath>${project.build.directory}/docker-derived</targetPath>
                <filtering>true</filtering>
            </resource>
        </resources>
        <pluginManagement>
            <plugins>
                <plugin>
                   <groupId>com.spotify</groupId>
                   <artifactId>docker-maven-plugin</artifactId>
                   <version>0.4.13</version>
                   <executions>
                       <execution>
                           <id>build-image</id>
                           <phase>compile</phase>
                           <goals>
                               <goal>build</goal>
                           </goals>
                       </execution>
                   </executions>
                   <configuration>
                       <imageName>${project.artifactId}</imageName>
                       <dockerDirectory>${project.build.directory}/docker-derived</dockerDirectory>
                   </configuration>
               </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin><!--  Triggers the Docker build configured within the plugin management. -->
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Dockerfile

FROM openjdk:8-jre-alpine

COPY binaries/* /opt/service/

CMD ["keytool", "-list", "-keystore", "/opt/service/example.jks", "-storepass", "password"]

如果按docker build .直接构建并按docker run [imagename]

运行,则输出
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

selfsigned, Apr 3, 2017, PrivateKeyEntry,
Certificate fingerprint (SHA1): 07:56:26:66:16:82:DD:BF:6A:61:4B:94:E8:67:69:F8:77:36:5C:6D

令人遗憾的是,使用maven构建输出:

keytool error: java.io.IOException: Invalid keystore format

在其他情况下,当复制更大的二进制文件,如罐子,战争,耳朵或拉链档案时,我没有遇到任何困难。但是这个似乎不起作用。

我目前的解决方法是在映像构建期间通过Dockerfile中的RUN命令直接创建证书。

我有什么遗失的吗?

P.S。我在我的Linux Ubuntu 16.04 LTS笔记本电脑上遇到了同样的问题。

1 个答案:

答案 0 :(得分:0)

问题是由我的示例(以及我的生产代码中)激活的资源过滤引起的。 我从My Technical Life学到的,它再次链接到stackoverflow问题jar file gets corrupted while building with maven

违规代码是:

<resource>
  <!--
   | Enable resource filtering pre dockerfile build calls.
  -->
  <directory>src/main/docker</directory>
  <targetPath>${project.build.directory}/docker-derived</targetPath>
  <-- The next line breaks my binary-->
  <filtering>true</filtering>
 </resource>

删除<filtering>true</filtering>或明确将其设置为false可修复我的示例代码并创建可用的Docker镜像。

如果你需要过滤怎么办,就像我一样,因为我在我的生产代码Dockerfile中引用项目版本并希望Maven替换一些令牌?

解决方案是稍微改变项目结构并分离可过滤和不可过滤的资源。

我按如下方式更改了文件夹结构:

-src
|-main
| |-docker
|   |-Dockerfile
|-resources
| |-binaries
|   |-example.jks
|-pom.xml

并改变了我的示例的资源部分:

<resources>
  <resource>
    <!--
     | Enable resource filtering pre dockerfile build calls for non binaries.
    -->
    <directory>src/main/docker</directory>
    <targetPath>${project.build.directory}/docker-derived</targetPath>
    <filtering>true</filtering>
  </resource>
  <resource>
    <directory>src/main/resources/binaries</directory>
    <targetPath>${project.build.directory}/docker-derived/binaries</targetPath>
  </resource>
</resources>

然后它就像一个魅力。很抱歉怀疑spotify插件!