Jenkins中的Docker推送 - 被拒绝:请求访问该资源被拒绝。

3

我正在尝试在Jenkins中设置一个流水线来构建镜像并将它们推送到Docker Hub。我的凭据在“Jenkins”管理中被称为“docker-hub-credentials”,似乎已经被使用。

它可以构建,但是无法推送...有帮助吗?我已经花了几个小时在这个问题上,不确定我错过了什么。

我已经尝试过使用docker login,但jenkins不允许它。

stage('Build image') {
    /* This builds the actual image; synonymous to
     * docker build on the command line */

     bat 'docker build -t username/foldername:build . '    }


stage('Push image') {
    /* Finally, we'll push the image with two tags:
    docker.withRegistry('https://registry.hub.docker.com', 'docker-hub-credentials') {
        bat 'docker push username/foldername:build'
    }
}

我期望图片被推送,但实际上出现了这个:

The push refers to repository [docker.io/username/foldername]
a73d7d9f4346: Preparing
964bdfb24a54: Preparing
1af124d739c9: Preparing
6cffeea81e5d: Preparing
614a79865f6d: Preparing
612d27bb923f: Preparing
ef68f6734aa4: Preparing
612d27bb923f: Waiting
ef68f6734aa4: Waiting
denied: requested access to the resource is denied

你可能需要使用 docker login - CalculatingKraken
我无法进行Docker登录,它不是交互式的 :/ - shrimpy
这个程序会在哪台机器上运行?是固定的还是会不断变化?请尝试在该机器上使用 docker-login 命令。 - CalculatingKraken
9个回答

6

我找到答案了!!!

 stage('Push image') {
        withDockerRegistry([ credentialsId: "docker-hub-credentials", url: "" ]) {
        bat "docker push devopsglobalmedia/teamcitydocker:build"
        }

docker.withRegistry('', 'docker-hub-credentials') { ... 的汉语翻译为: - Beefjeff
你救了我的命,这个错误真是浪费了太多时间。 - JMPG Developer

4

Image push 阶段,您可以先执行 docker login 再进行镜像推送。尝试以下命令进行登录:

stage('Push image') {
    withCredentials([usernamePassword( credentialsId: 'docker-hub-credentials', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) {
        def registry_url = "registry.hub.docker.com/"
        bat "docker login -u $USER -p $PASSWORD ${registry_url}"
        docker.withRegistry("http://${registry_url}", "docker-hub-credentials") {
            // Push your image now
            bat "docker push username/foldername:build"
        }
    }
}

请确保注册表的url正确。

withCredentials([usernamePassword(...)])方法将设置两个环境变量USERPASSWORD,它们是来自凭据IDdocker-hub-credentials的Docker注册表凭据。


但这不是硬编码我的密码吗...? - shrimpy
1
不,你没有硬编码密码。在Jenkins中创建一个名为“docker-hub-credentials”的用户名/密码凭据。如果已经完成了这个步骤,我建议的代码应该可以工作。请查看函数https://jenkins.io/doc/pipeline/steps/credentials-binding/#withcredentials-bind-credentials-to-variables,使用代码。 - abhgangwar
哦,你的意思是实际上不用实际凭据替换usernameVariable:'USER',passwordVariable:'PASSWORD'吗?它们已经在凭据中了,我不需要在我的文件中使用它们。 - shrimpy
使用 withCredentials 方法获取的任何凭据都不能以明文形式暴露。即使您尝试在日志中打印它,它也只会打印星号(*******)。 - abhgangwar
我尝试使用--password-stdin registry.hub.docker.com/,但显然出现了以下错误: 错误:无法从非TTY设备执行交互式登录。 - shrimpy
显示剩余2条评论

1
我最近也遇到了同样的问题,原因是docker镜像库的url错误。
问题出在 - https://index.docker.io/v1 解决方法 - https://index.docker.io/v1/ 没错,这就是问题所在。我无法将它推送到docker镜像库。

1
更好的选择是使用Docker pipeline plugin(它包含在推荐插件中)。
node {

  checkout scm
  def dockerImage

  stage('Build image') {
    dockerImage = docker.build("username/repository:tag")
  }

  stage('Push image') {
    dockerImage.push()
  }   

}

以这种方式进行操作,您必须在管道模型定义中指定Docker注册表的凭证。
Docker管道插件在将分配给多分支管道项目中的管道模型定义中的凭据应用于项目时存在问题。也就是说,如果使用上述代码,您仍会收到以下错误消息:
被拒绝:请求访问资源被拒绝
那么您必须按照以下方式在Jenkinsfile中指定凭据:
node {

  checkout scm
  def dockerImage

  stage('Build image') {
    dockerImage = docker.build("username/repository:tag")
  }

  stage('Push image') {
    docker.withRegistry('https://registry-1.docker.io/v2/', 'docker-hub-credentials') {
      dockerImage.push()
    }
  }

}

如果需要,您可以修改URL以连接到自定义注册表。


你好!感谢您的回答。我尝试使用插件手动构建,但我确实想要使用pipeline,所以我按照您的建议去做了。发生了两件事:它不接受dockerImage = docker.build,因为它说没有nohup(我正在使用Windows环境),所以我改为docker image = bat 'docker build -t username/image:build .'。其次,在push image阶段,它似乎无法使用dockerImage,因为它为空...?但镜像已经成功构建了...有什么想法吗? - shrimpy
你好!我尝试了docker.withRegistry('https://registry-1.docker.io/v2/', 'docker-hub-credentials') { bat "docker push devopsglobalmedia/teamcitydocker:build",但是这次它只告诉我“拒绝访问所请求的资源”。 - shrimpy
你好!我认为 dockerImage = bat 'docker build...' 不应该起作用。我在 Docker 上运行 Jenkins,从未使用过在 Windows 上本地运行的 Jenkins,很抱歉我无法帮助你。希望你能找到解决方案。 - gjseminario

0
我通过添加 ":" 解决了这个问题。
stage('Push Docker Image') {
            steps {
                withDockerRegistry([credentialsId: "docker_auth", url: "https://index.docker.io/v1/"]) {
                    bat "docker push IMAGE_NAME:latest"
                }
            }
        }

0
如果你想要推送私有仓库,那么你需要按照以下命令:
1. 确保Jenkins上已经设置好Dockerhub的凭据。 2. 创建一个流水线项目的作业。 3. 使用Jenkinsfile推送你的项目。 4. 现在你可以构建Jenkins了。
我会提供完整的Jenkinsfile来帮助解决权限拒绝问题并成功创建Docker镜像并推送至Dockerhub。

pipeline {
     agent any
     stages{
        stage('Maven Install'){
                      agent any
                      steps{
                          bat 'mvn -f pom.xml clean install'
                      }
                  }

        stage('Docker Build'){
                         agent any
                         steps{
                             bat 'docker build -t dockerhub_username/repository_name/docker-jenkins-integration .'
                         }
                     }

        stage('Push image'){
                    agent any
                    steps{
                      
                        
                                       withDockerRegistry([ credentialsId: "id", url: "" ]) {
                                       bat "docker tag dockerhub_username/repository_name/docker-jenkins-integration dockerhub_username/repository_name:docker-jenkins-integration"
                                       bat "docker push dockerhub_username/repository_name:docker-jenkins-integration"
                                     }

                }


                }
     }

}


0

截至今天,Docker管道插件提供了Groovy方法来登录到Docker Hub,构建镜像并最终推送它。 以下是一个声明性管道的示例代码

pipeline {
agent any
stages {
    stage('Push container') {
        steps {
            echo "Workspace is $WORKSPACE"
            dir("$WORKSPACE/dir-to-Dockerfile") {
                script {
                    def REGISTRY_URL = "https://index.docker.io/v1/"
                    def USER_NAME = "your-registry-username"
                    docker.withRegistry("$REGISTRY_URL", 'DockerHub-Cred-ID-Defined-In-Jenkins') {
                        def image = docker.build("$USER_NAME/some-image-name:${env.BUILD_ID}")
                        image.push()
                    }
                }
            }
        }
    }
}
}

0

我已经花了半天的时间来解决它。请确保安装了Docker Pipeline Plugin

script {
  withDockerRegistry([ credentialsId: "Docker-Hub-Cred", url: "https://index.docker.io/v1/" ]){            
                             
  }
}  

0
withCredentials([usernamePassword(credentialsId: 'somewhat', passwordVariable: 'PASS', usernameVariable: 'USER')]) {
           "echo $PASS | docker login -u $USER --password-stdin"
        }

你好,我建议使用更方便和安全的方式传递密码,就像在Docker文档中所写的那样,通过使用stdin,它可以防止密码出现在shell的历史记录或log-files中。祝你好运 ;)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接