How to version docker images with build number in Jenkins to deploy as Kubernetes deployment?

11/5/2019

Currently I am trying to add version number or build number for Docker image to deploy on Kubernetes cluster. Previously I was working only with :latest tag. But when I am using latest tag , I found problem for pulling from Dockerhub image registry. So when I am using the build number to my docker image like <image-name>:{build-number} .

Application Structure

In my Kubernetes deployment, I am using deployment and service. I am defining my image repository in my deployment file like the following,

   containers:
   - name: test-kube-deployment-container
     image: samplekubernetes020/testimage:latest
     ports:
        - name: http
          containerPort: 8085
          protocol: TCP

Here instead of latest tag, I want to put build number with my image in deployment YAML.

  1. Can I use an environment variable for holding the random build number for accessing like <image-name>:${buildnumber} ?
  2. If i want to use a environment variable which providing the random number how I can generate a random number to a environment variable?

Updates On Image Version Implementation

My modified Jenkinsfile contains the step like following to assign the image version number to image. But still I am not getting the updated result after changes to repository,

I created step like the following in Jenkinsfile

stage ('imagebuild')
  {
     steps
         {
 sh 'docker build -f /var/lib/jenkins/workspace/jpipeline/pipeline/Dockerfile -t spacestudymilletech010/spacestudykubernetes /var/lib/jenkins/workspace/jpipeline/pipeline'
 sh 'docker login --username=my-username --password=my-password' 
 sh "docker tag spacestudymilletech010/spacestudykubernetes:latest spacestudymilletech010/spacestudykubernetes:${VERSION}"
 sh 'docker push spacestudymilletech010/spacestudykubernetes:latest'

         }
  }

And my deployment YAML file contains like the following,

 containers:
   - name: test-kube-deployment-container
     image: spacestudymilletech010/spacestudykubernetes:latest
     ports:
        - name: http
          containerPort: 8085
          protocol: TCP

Confusions

NB: When I am checking the dockerhub repository, every time it showing the latest push status

So my confusions are:

  1. Is there any problem with pulling latest image in my deployment.yaml file?
  2. Is the problem when I am tagging the image at my machine from where I am building the image and pushing?
-- Jacob
docker
kubernetes

2 Answers

1/30/2020

This Jenkins pipeline approach worked for me. I am using Jenkins build number as a tag for docker image, pushing to docker hub. Now applying yaml file to k8s cluster and then updating the image in deployment with same tag.

Sample pipeline script snippet is here,

stage('Build Docker Image'){
        sh 'docker build -t {dockerId}/{projectName}:${BUILD_NUMBER} .'
  }
  stage('Push Docker Image'){
        withCredentials([string(credentialsId: 'DOKCER_HUB_PASSWORD', variable: 'DOKCER_HUB_PASSWORD')]) {
          sh "docker login -u {dockerId} -p ${DOKCER_HUB_PASSWORD}"
        }
        sh 'docker push {dockerId}/{projectName}:${BUILD_NUMBER}'
  }
  stage("Deploy To Kuberates Cluster"){
        sh 'kubectl apply -f {yaml file name}.yaml'
        sh 'kubectl set image deployments/{deploymentName} {container name given in deployment yaml file}={dockerId}/{projectName}:${BUILD_NUMBER}'
  }
-- Sandeep Rao Annamaneni
Source: StackOverflow

11/5/2019

The standard way or at least the way that has worked for most of us is to create versioned or tagged images. For example

samplekubernetes020/testimage:1
samplekubernetes020/testimage:2
samplekubernetes020/testimage:3
...
...

Now I will try to answer your actual question which is how do I update the image which is in my deployment when my image tag upgrades?

Enter Solution

  • When you compile and build a new image with latest version of code, tag it with an incremental unique version. This tag can be anything unique or build number, etc.
  • Then push this tagged image to docker registry
  • Once the image is uploaded, this is when you can use kubectl or kubernetes API to update the deployment with the latest container image.

    kubectl set image deployment/my-deployment test-kube-deployment-container=samplekubernetes020/testimage:1 --record

  • The above set of steps generally take place in your CI pipeline, where you store the image version or the image: version in the environment variable itself.


Update Post comment

Since you are using Jenkins, you can get the current build number and commit-id and many other variables in Jenkinsfile itself as Jenkins injects these values at builds runtime. For me, this works. Just a reference.

environment { 
   NAME = "myapp"
   VERSION = "${env.BUILD_ID}-${env.GIT_COMMIT}"
   IMAGE = ${NAME}:${VERSION}"
}
stages {
    stage('Build') {
        steps {
            echo "Running ${VERSION} on ${env.JENKINS_URL}"
            git branch: "${BRANCH}",  .....
            echo "for brnach ${env.BRANCH_NAME}"
            sh "docker build -t ${NAME} ."
            sh "docker tag ${NAME}:latest ${IMAGE_REPO}/${NAME}:${VERSION}"
        }
    }
}
-- damitj07
Source: StackOverflow