You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jenkins声明式流水线的docker.withRegistry()中解析Vault中的DockerHub凭据

问题描述

我尝试通过Jenkins声明式流水线将Docker镜像推送到DockerHub,DockerHub的凭据存储在Vault中,希望使用Docker插件的docker.withRegistry()语法。此前两种尝试均成功:

  1. 将DockerHub凭据存储在Jenkins内置凭据库时,使用以下代码可正常运行流水线:
stage('Publish the Docker Image on DockerHub')
{
    steps {
        script {
            docker.withRegistry('', 'dockerhub-credentials'){
                dockerImage.push()
            }
        }
    }
}
  1. 将DockerHub凭据存储在Vault中并通过shell命令登录时,以下代码也能成功运行:
stage('Publish the Docker Image on DockerHub')
{
    steps 
    {
        withVault(
            configuration: \
            [
                timeout: 60,
                vaultCredentialId: 'vault-jenkins-approle-creds',
                vaultUrl: 'http://172.31.32.203:8200'
            ],
            vaultSecrets: 
            [[
                engineVersion: 2,
                path: 'secret/credentials/dockerhub',
                secretValues:
                [
                    [envVar: 'DOCKERHUB_USERNAME', vaultKey: 'username'],
                    [envVar: 'DOCKERHUB_PASSWORD', vaultKey: 'password']
                ]
            ]]
        )
        {
            script 
            {
                sh "docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD"
                sh "docker push <docker-hub-repo>"
            }
        }
    }
}

现在想知道:如何将从Vault获取的用户名+密码凭据,用于第一种方式的docker.withRegistry()方法中?

解决方案

核心思路是从Vault拉取到用户名和密码后,在流水线中临时创建一个Jenkins用户名密码凭据,再将这个临时凭据的ID传给docker.withRegistry()使用。具体实现代码如下:

stage('Publish the Docker Image on DockerHub')
{
    steps {
        withVault(
            configuration: [
                timeout: 60,
                vaultCredentialId: 'vault-jenkins-approle-creds',
                vaultUrl: 'http://172.31.32.203:8200'
            ],
            vaultSecrets: [[
                engineVersion: 2,
                path: 'secret/credentials/dockerhub',
                secretValues: [
                    [envVar: 'DOCKERHUB_USERNAME', vaultKey: 'username'],
                    [envVar: 'DOCKERHUB_PASSWORD', vaultKey: 'password']
                ]
            ]]
        ) {
            script {
                // 创建临时用户名密码凭据,用UUID生成唯一ID避免冲突
                def tempDockerCreds = usernamePassword(
                    credentialsId: "temp-dockerhub-creds-${UUID.randomUUID()}",
                    username: env.DOCKERHUB_USERNAME,
                    password: env.DOCKERHUB_PASSWORD
                )
                
                // 用临时凭据调用docker.withRegistry,和第一种方式语法一致
                docker.withRegistry('', tempDockerCreds.id) {
                    dockerImage.push()
                }
                
                // 可选:删除临时凭据,避免Jenkins中积累无用凭据
                tempDockerCreds.delete()
            }
        }
    }
}

细节说明

  • usernamePassword方法会在Jenkins中生成一个临时的用户名密码凭据,通过UUID确保凭据ID唯一,不会和现有凭据冲突
  • 直接将从Vault获取到的环境变量DOCKERHUB_USERNAME和DOCKERHUB_PASSWORD作为参数传入,生成符合Jenkins插件要求的凭据
  • 将临时凭据的ID传入docker.withRegistry()后,就能完全复用第一种方式的插件语法完成镜像推送
  • 最后调用delete()方法可以清理临时凭据,保持Jenkins凭据库整洁

内容的提问来源于stack exchange,提问作者matak8s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 23:40:18