jraj
jraj

Reputation: 215

Unable to push image to GCR from Jenkins Pipeline

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.

  1. I installed all the required Jenkins plugins: Google OAuth Credentials Plugin, Docker Pipeline Plugin, Google Container Registry Auth Plugin

  2. Created a service account + key with Storage Admin and Object Viewer roles. Downloaded the json file.

  3. Created a credential in Jenkins using the google project name as the id and the json key.

  4. My pipeline code for build looks like this:

    stage('Build Image') {
        app = docker.build("<gcp-project-id>/<myproject>")
    }
    
  5. 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

Answers (3)

Rafiq
Rafiq

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

Avinash Singh
Avinash Singh

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

Fleuri
Fleuri

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

Related Questions