【问题标题】:Small binary file is changed on building Docker image using spotify maven plugin使用 spotify maven 插件构建 Docker 映像时更改了小二进制文件
【发布时间】:2017-04-27 02:38:34
【问题描述】:

我正在使用 spotify 的 docker-maven-plugin 来构建 docker 映像。更确切地说是这个:

<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)看起来像是被撒了(我不知道怎么说更好)多了个字节。 p>

我创建了一个小例子来展示这种行为: 项目结构:

-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

在其他情况下,当复制较大的二进制文件(如 jars、wars、ears 或 zip 档案)时,我没有遇到任何困难。但这似乎不起作用。

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

我有什么遗漏吗?

附:我在我的 linux Ubuntu 16.04 LTS 笔记本电脑上遇到了同样的问题。

【问题讨论】:

    标签: java maven docker


    【解决方案1】:

    问题是由我的示例(以及我的生产代码)中激活的资源过滤引起的。 我从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>
    

    删除 &lt;filtering&gt;true&lt;/filtering&gt; 或将其显式设置为 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 插件!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-30
      • 2019-08-24
      • 1970-01-01
      • 2020-06-16
      • 2016-08-27
      • 2018-06-30
      • 2013-03-02
      • 2018-08-22
      相关资源
      最近更新 更多