我正在尝试在 Jenkins 中创建 CI/CD 管道。该管道利用 Jenkinsfile 从私有 Bitbucket 服务器提取源代码,构建 Docker 映像并尝试将其推送到托管 Docker 注册表的私有 Artifactory。
我已成功使用此工作流程与 Amazon ECR 作为最后一步,但我无法让 Artifactory 存储库的推送生效。
我正在使用这个 Jenkinsfile:
pipeline {
environment {
jenkinsArtifactoryCredentialsID = '...'
}
agent any
options {
skipStagesAfterUnstable()
}
stages {
stage('Clone repository') {
steps {
script {
checkout scm
}
}
}
stage('Build') {
steps {
script {
image = docker.build("test")
}
}
}
stage('Deploy to Artifactory') {
steps {
script {
docker.withRegistry(
'https://artifactory.my.company.com:8443/artifactory/docker_registry_repo',
jenkinsArtifactoryCredentialsID) {
image.push('latest')
image.push("${env.BUILD_NUMBER}")
}
}
}
}
}
}
正如你从文件中看到的,我在 Artifactory 中创建了一个存储库,据我所知,它是一个完全成熟的 docker 注册表,例如我可以将带有不同标签的不同图像推入其中。我已经在 Jenkins 中安装了 Artifactory 插件并配置了凭据,我在此处使用其 ID 作为环境变量。
到了构建步骤,构建就卡住了:
...
Login Succeeded
+ docker tag test artifactory.my.company.com:8443/test:latest
+ docker push artifactory.my.company.com:8443/test:latest
The push refers to repository [artifactory.my.company.com:8443/test]
154c211638e0: Preparing
0997ee847b8f: Preparing
bca59febf004: Preparing
994393dc58e7: Preparing
0997ee847b8f: Retrying in 5 seconds
...
154c211638e0: Retrying in 1 second
unknown: Not Found
ERROR: script returned exit code 1
Finished: FAILURE
令我恼火的是,在标记过程中,存储库的路径(例如 docker_registry_repo)以某种方式被省略,我怀疑这会导致构建失败。如有任何帮助,我们将不胜感激。
编辑:
使用 Jenkinsfile 中的 Artifactory API,通过以下命令完成推送:
rtDockerPush(
serverId: 'company-artifactory',
image: 'artifactory.my.company.com:8443/test:latest',
targetRepo: 'docker_registry_repo'
)
我还在Jenkins的系统配置中配置了Artifactory服务器,这样我就不必将它们放入文件中。
进行这些更改后,推送仍然会失败,但需要花费更多时间才能失败。我看到以下输出:
INFORMATION: Pushing image: artifactory.my.company.com:8443/test:latest
com.github.dockerjava.api.exception.DockerClientException: Could not push image: unknown: Not Found
at com.github.dockerjava.core.command.PushImageResultCallback.throwFirstError(PushImageResultCallback.java:42)
at com.github.dockerjava.api.async.ResultCallbackTemplate.awaitCompletion(ResultCallbackTemplate.java:93)
at org.jfrog.build.extractor.docker.DockerJavaWrapper.pushImage(DockerJavaWrapper.java:42)
at org.jfrog.build.extractor.docker.extractor.DockerPush.execute(DockerPush.java:84)
at org.jfrog.build.extractor.packageManager.PackageManagerExtractor.executeAndSaveBuildInfo(PackageManagerExtractor.java:33)
at org.jfrog.build.extractor.docker.extractor.DockerPush.main(DockerPush.java:69)
ERROR: Couldn't execute docker task. RuntimeException: docker build failed with exit code 1
java.lang.RuntimeException: docker build failed with exit code 1
at org.jfrog.hudson.pipeline.common.Utils.launch(Utils.java:280)
Caused: java.lang.RuntimeException: docker build failed. Couldn't execute docker task. RuntimeException: docker build failed with exit code 1
at org.jfrog.hudson.pipeline.common.Utils.launch(Utils.java:285)
at org.jfrog.hudson.pipeline.common.executors.BuildInfoProcessRunner.execute(BuildInfoProcessRunner.java:59)
at org.jfrog.hudson.pipeline.common.executors.DockerPushExecutor.execute(DockerPushExecutor.java:42)
at org.jfrog.hudson.pipeline.declarative.steps.docker.DockerPushStep$Execution.runStep(DockerPushStep.java:98)
at org.jfrog.hudson.pipeline.declarative.steps.docker.DockerPushStep$Execution.runStep(DockerPushStep.java:83)
at org.jfrog.hudson.pipeline.ArtifactorySynchronousNonBlockingStepExecution.run(ArtifactorySynchronousNonBlockingStepExecution.java:55)
at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Finished: FAILURE
我怀疑这可能与图像名称有关,但是将 docker.build 命令中的名称更改为
artifactory.my.company.com:8443/test:latest
以匹配要推送的图像会产生相同的错误。
既然您安装了 Artifactory 插件,那么您可以使用与该插件交互的 Artifactory 插件全局变量方法而不是 Docker 全局变量方法来完成此操作。对于声明式管道:
rtServer(
id: 'myArtifactoryServer',
url: <artifactory docker registry url>,
credentialsId: <artifactory docker registry credentaisl id>
)
rtDockerPush(
serverId: 'Artifactory-1',
image: <registry>/<repo>:<tag>,
targetRepo: <target repo>,
// Attach custom properties to the published artifacts:
properties: 'project-name=docker1;status=stable',
// Optional - Only if this build is associated with a project in Artifactory, set the project key as follows.
project: <project key>,
)
对于脚本化管道(或在声明性管道内的
script
块内):
// if artifactory registry id is configured within jenkins
artServer = Artifactory.server(<registry id>)
// otherwise
artServer = Artifactory.newServer(url: <registry url>, credentialsId: <artifactory docker registry credentaisl id>)
artDocker = Artifactory.docker(server: artServer)
artDocker.push(<registry>/<repo>:<tag>, <target repo>)
请注意,从
docker.build
返回的对象必须来自具有方法参数的完整注册表和存储库名称的调用:
image = docker.build(<registry>/<repository>)
我知道这是一个老问题..但是因为我现在面临着完全相同的问题..你能告诉我你做了什么来解决这个问题吗?我很感谢你在这方面的帮助