如何在Jenkins声明式流水线的docker.withRegistry()中解析Vault中的DockerHub凭据
问题描述
我尝试通过Jenkins声明式流水线将Docker镜像推送到DockerHub,DockerHub的凭据存储在Vault中,希望使用Docker插件的docker.withRegistry()语法。此前两种尝试均成功:
- 将DockerHub凭据存储在Jenkins内置凭据库时,使用以下代码可正常运行流水线:
stage('Publish the Docker Image on DockerHub') { steps { script { docker.withRegistry('', 'dockerhub-credentials'){ dockerImage.push() } } } }
- 将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
相关产品推荐
相关产品推荐

