首页 > 解决方案 > Jenkins 多次构建 docker 端口冲突

问题描述

我有一个多模块 Maven 项目,当同时进行多个 Jenkins 构建时,我遇到了 docker 端口冲突。

我在 pom.xml 文件中使用 docker-maven-plugin

我该如何解决这个问题?

<plugin>
    <groupId>io.fabric8</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>start</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>stop</goal>
                <goal>build</goal>
                <goal>start</goal>
            </goals>
        </execution>
        <execution>
            <id>stop</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>stop</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <images>
            <image>
                <name>guest/guest-main:${project.version}</name>
                <alias>guest</alias>
                <run>
                    <env>
                        <myapp_ENDPOINT>http://mock:8081/mycalcService</myapp_ENDPOINT>
                    </env>
                    <namingStrategy>alias</namingStrategy>
                    <dependsOn>
                        <container>mock</container>
                    </dependsOn>
                    <links>
                        <link>mock:mock</link>
                    </links>
                    <ports>
                        <port>guest.port:8080</port>
                    </ports>
                    <wait>
                        <log>Started guestServiceApplication</log>
                        <time>60000</time>
                    </wait>
                </run>
            </image>
            <image>
                <alias>mock</alias>
                <name>guest/myapp-mock:${project.version}</name>
            </image>
        </images>
    </configuration>
</plugin>

问候

标签: dockerjenkins

解决方案


您的配置通过以下行暴露给您的 Docker 主机系统(例如您的 Jenkins)的guest.port端口8080

<port>guest.port:8080</port>

由于一个端口一次只能绑定到一个服务,以后的构建会发现无法绑定到该端口。

要解决这个问题,您可以为每个构建使用不同的端口,或者等待您想要使用的一个端口被另一个作业释放。

例如,您可以在执行之前将以下内容添加到您的 Jenkinsfile 中mvn

timeout(time: 10, unit: "MINUTES") {
    waitUntil {
        script {
            sh(script: 'netstat -lnpt 2>&1 | grep ":8080"', returnStatus: true) != 0
        }
    }
}
sh "mvn ..."

timeout步骤导致 Jenkins 在 10 分钟后取消。

waitUntil步骤使 Jenkins 重试script直到成功。

Ascript是必要的,因为我们!=对返回值进行了 caparison ( )。

最后netstat返回当前绑定端口的列表,并且仅当端口是其中之一时grep才会返回。08080


推荐阅读