Reputation: 215
I am running a VM in google cloud that runs a Jenkins server (within a docker container). I am trying to build a Docker image for my application and push it out to Google Container Registry using Jenkins pipeline.
I installed all the required Jenkins plugins: Google OAuth Credentials Plugin, Docker Pipeline Plugin, Google Container Registry Auth Plugin
Created a service account + key with Storage Admin and Object Viewer roles. Downloaded the json file.
Created a credential in Jenkins using the google project name as the id and the json key.
My pipeline code for build looks like this:
stage('Build Image') {
app = docker.build("<gcp-project-id>/<myproject>")
}
My pipeline code for build looks like this:
stage('Push Image') {
docker.withRegistry('https://us.gcr.io', 'gcr:<gcp-project-id>') {
app.push("${commit_id}")
app.push("latest")
}
}
However, the build fails at the last step with this error:
unauthorized: You don't have the needed permissions to perform this operation, and you may have invalid credentials. To authenticate your request, follow the steps in: https://cloud.google.com/container-registry/docs/advanced-authentication
I have spent several hours trying to figure this out. Any help would be greatly appreciated!
Upvotes: 4
Views: 5106
Reputation: 11445
key id must be exact google-container-registry
pipeline {
agent any
tools {nodejs "node"}
environment {
CI = 'true'
PROJECT_ID = 'projet-marshmallow'
CLUSTER_NAME = 'cluster-1'
LOCATION = 'us-central1-c'
CREDENTIALS_ID = 'kubernetes'
DOCKER_FILE_PATH="${FOLDER_NAME}/Dockerfile"
SERVICE_NAME='users'
FOLDER_NAME='prod-config'
K8_FILE_PATH="${FOLDER_NAME}/k8.yaml"
IMAGE_TAG = "us.gcr.io/${PROJECT_ID}/${SERVICE_NAME}:${env.BUILD_NUMBER}"
}
stages {
stage('Scm Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
dir("${SERVICE_NAME}/"){
sh 'npm install'
}
}
}
stage('Build Docker Image') {
steps {
sh 'whoami'
script {
dockerImage = docker.build("${IMAGE_TAG}","-f ${SERVICE_NAME}/${DOCKER_FILE_PATH} ${SERVICE_NAME}")
}
}
}
stage("Push Docker Image") {
steps {
script {
echo "Push Docker Image"
docker.withRegistry('https://us.gcr.io', "gcr:google-container-registry") {
dockerImage.push()
}
}
}
}
stage('Change image version') {
steps {
dir("${SERVICE_NAME}/prod-config"){
sh """
cat k8.yaml | grep image
sed -i 's|image: .*|image: "${IMAGE_TAG}"|' k8.yaml
cat k8.yaml | grep image
"""
}
}
}
stage('Deploy to K8s') {
steps{
echo "Deployment started ..."
sh 'ls -ltr'
sh 'pwd'
echo "Start deployment of ${SERVICE_NAME} service."
step([
$class: 'KubernetesEngineBuilder',
projectId: env.PROJECT_ID,
clusterName: env.CLUSTER_NAME,
location: env.LOCATION,
manifestPattern: "${SERVICE_NAME}/${K8_FILE_PATH}",
credentialsId: env.CREDENTIALS_ID,
// verifyDeployments: true
])
echo "Deployment Finished ..."
}
}
}
post {
always {
echo "Deleting docker iamge ..."
sh "docker rmi -f ${IMAGE_TAG}"
}
success {
emailext body: "${currentBuild.currentResult}: Job ${env.JOB_NAME} build ${env.BUILD_NUMBER}\n More info at: ${env.BUILD_URL}",
recipientProviders: [[$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']],
subject: "Jenkins Build ${currentBuild.currentResult}: Job ${env.JOB_NAME}"
}
failure {
emailext body: "${currentBuild.currentResult}: Job ${env.JOB_NAME} build ${env.BUILD_NUMBER}\n More info at: ${env.BUILD_URL}",
recipientProviders: [[$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']],
subject: "Jenkins Build ${currentBuild.currentResult}: Job ${env.JOB_NAME}"
}
}
}
Upvotes: 0
Reputation: 1016
Create a service account in GCP with permission to push image and then copy the credential json fie and save it as credentials inside Jenkins; call in the credentials id inside your pipeline like below and it should push images to gcr
withCredentials([file(credentialsId: 'gcr', variable: 'GC_KEY')]){
sh "cat '$GC_KEY' | docker login -u _json_key --password-stdin https://eu.gcr.io"
sh "gcloud auth activate-service-account --key-file='$GC_KEY'"
sh "gcloud auth configure-docker"
GLOUD_AUTH = sh (
script: 'gcloud auth print-access-token',
returnStdout: true
).trim()
echo "Pushing image To GCR"
sh "docker push eu.gcr.io/${google_projectname}/${image_name}:${image-tag}"
}
Additionally i have defined some variables used above
Upvotes: 3
Reputation: 328
I have an identical problem. I found out that Jenkins doesn't seem to use those credentials: Under usage it says 'This credential has not been recorded as used anywhere.' . When used with gcloud util, the service account and key work fine, so the problem is somewhere in Jenkins.
Upvotes: 2