1

I am currently trying to implement the CI/CD pipeline using docker , Kubernetes and Jenkins. When I created the pipeline deployment Kubernetes deployment YAML file, I was not included the time stamp. Only I was using the imagePullPolicy as latest in YAML file. Regarding with latest pull I had already one discussion here, The following is the link for that discussion,

Docker image not pulling latest from dockerhub.com registry

After This discussion , I included the time stamp in my deployment YAML like the following,

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-kube-deployment
  labels:
   app: test-kube-deployment
spec:
 replicas: 3
 selector:
  matchLabels:
    app: test-kube-deployment
 template:
  metadata:
    labels:
      app: test-kube-deployment
    annotations: 
     date: "+%H:%M:%S %d/%m/%y"
  spec:
    imagePullSecrets:
      - name: "regcred"
    containers:
     - name: test-kube-deployment-container
       image: spacestudymilletech010/spacestudykubernetes:latest
       imagePullPolicy: Always
       ports:
         - name: http
           containerPort: 8085
           protocol: TCP

Here I modified my script to include the time stamp by adding the following in template,

annotations: 
    date: "+%H:%M:%S %d/%m/%y"

My service file like following,

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  ports:
   - port: 8085
     targetPort: 8085
     protocol: TCP
     name: http
 selector:
    app: test-kube-deployment

My jenkinsfile conatining the following,

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

  stage ('Test Deployment')
            {
                 steps
                    {
                        sh 'kubectl apply -f deployment/testdeployment.yaml'
                        sh 'kubectl apply -f deployment/testservice.yaml'
                    }
            }

But still the deployment not pulling the latest one from Dockerhub registry. How I can modify these script for resolving the latest pulling problem?

halfer
  • 19,824
  • 17
  • 99
  • 186
Mr.DevEng
  • 2,651
  • 14
  • 57
  • 115
  • Have you looked at this answer and tried the approach: https://stackoverflow.com/a/55221174 ? – apisim Oct 30 '19 at 14:54

2 Answers2

1
The default pull policy is IfNotPresent which causes the Kubelet to skip pulling an image if it already exists. If you would like to always force a pull, you can do one of the following:

set the imagePullPolicy of the container to Always.

omit the imagePullPolicy and use :latest as the tag for the image to use.

omit the imagePullPolicy and the tag for the image to use.

enable the AlwaysPullImages admission controller.

Basically, either use :latest or then use imagePullPolicy: Always

Try it and let me know how it goes!

Referenced from here

DUDANF
  • 2,618
  • 1
  • 12
  • 42
  • Thank you for your response sir. I have already used the `imagePullPolicy : always` and with image i am using `:latest`. Did you noticed sir in my container? . If any mistake I did there , please guide me sir. – Mr.DevEng Oct 30 '19 at 14:05
  • That is exactly what I meant Jacob. You are using both. Try using one of them. Remove `imagePullPolice` and leave `:latest` or remove `:latest` and keep `imagePullPolicy`. – DUDANF Oct 30 '19 at 14:10
  • I tried both ways. Still not working. First I removed the image policy and then I removed the latest tag. Both of the method not updating with latest image. – Mr.DevEng Oct 30 '19 at 14:38
  • hm. And you're sure you have uploaded the latest image? – DUDANF Oct 30 '19 at 14:44
  • What if you delete all older images from the container registry, then upload image again, and try? – DUDANF Oct 30 '19 at 14:44
  • Even If I am deleting images from repository , then also still same. No change. After clearing all images. First time it shows the correct out. But from second time , no updation. – Mr.DevEng Oct 30 '19 at 15:01
  • and you're sure the latest image is tagged `:latest`? – DUDANF Oct 30 '19 at 15:11
  • 1
    @Jacob, because you are missing the version k8s assumes the pods are already running the latest image. To force update in the deployment use `kubectl rollout restart deployment/test-kube-deployment` – Crou Oct 30 '19 at 15:13
  • @Crou - In my jenkinsfile I added like `sh 'kubectl apply -f deployment/testdeployment.yaml'` for deployment and `sh 'kubectl apply -f deployment/testservice.yaml'"` for service. So for each SVN repo commit it will update. So Do I need to use kubectl rollout restart ? ,How I can modify then my jenkinsfile step ? Can you check my updated question with Jenkinsfile segment for deployment step? – Mr.DevEng Oct 30 '19 at 15:23
  • @daudnadeem - Thank you for your response . I am using the latest image. I cleared everything and started from beggining. Still not working. By removing imagePullPolicy and by removing latest tag aslo tried. What about the point Mr. Crou mentioned above ? Can you look the latest comments please ? – Mr.DevEng Oct 31 '19 at 07:44
  • Mr. Crou meant that if you have already deployed stuff to K8s, it won't update automatically. His command is to force restart on all Kubernetes containers. Give it a go. Any idea how I can reproduce your problem? If I can reproduce it, I can fix it. – DUDANF Oct 31 '19 at 09:41
  • I think there is few ways to handle it. One would be adding versions to your image that would result into updating the deployment on every image update. Second would be removing all deployments and apply them again. – Crou Oct 31 '19 at 11:38
  • @daudnadeem - I am sing Jenkins pipeline job which will get triggered when my SVN repo get commited/updated. And using the above deployment file and in deployment I am using the kubectl apply command. Apart from this my spring boot micro service displays sample message. Thats all about how I implemented. And you can follow the same for reproduce. – Mr.DevEng Oct 31 '19 at 12:30
  • @Crou - I already used both image policy and latest tag with my sample Helm chart deployment. There I did not faced any issue. I don know why this happening when I went through without chart. The image updation issue i Can resolve by using Helm chart. But here I don't know which stuff making problem. If I need to try with version I can try that also. But still the question is here only , If i done the same using Helm chart , why its not updating in plane kubernetes deployment ? Is it actually latest image pulling issue or kubectl command issue or something else? – Mr.DevEng Oct 31 '19 at 12:34
  • @Jacob, because pods are already running and yaml file is not changing Kubernetes does not know if there is a new image to download and reschedule the pods. That needs to be done manually by deleting the deployment and applying it again or by adding versions to image and to yaml file using helm charts. – Crou Oct 31 '19 at 12:38
  • @Crou - Ok. I understood that. But If we are on a real time application and we only using kubernetes deployment and service. We not using helm chart. Then deleting previous deployment and re-applying is a good practice for devops implementation ? . I don't think so . before helm chart coming into picture are devops were doing like same? – Mr.DevEng Oct 31 '19 at 12:46
  • @Jacob, it's a very bad practice. But not versioning your builds is also very bad practice. What will happen if the build is bugged and it destroys the app, you need to revert. In your current pipeline you need to recreate the image which is time consuming. This should be done quicker just by changing one line of code not the whole docker image. – Crou Oct 31 '19 at 12:59
  • @Crou - Ok. I understood the concern about the image versioning.That I am going to try here.But the alternative way that you discussed - deleting the previous deployment and re-applying again using `kubectl apply` , it may change the deployed node port. So for every deployment if port number is changing ,then how i can give the url in my application from where I am accessing this deployed micro service ?. In my case first deployment the port number was 32089 . And it changed to 30034. So How I know the changed port If am going in this deleting and re-applying way ? I am totally confused. – Mr.DevEng Oct 31 '19 at 13:27
  • @Jacob, Where in `deployment` you have nodeport? You don't. You need to create a `service` for that `deployment`, as long as you don't touch `service` notching changes because `service` points to the deployment using labels. – Crou Oct 31 '19 at 14:08
  • @Crou - How I can give the versioning to my building image ? What I need to do for versioning my image ? Can you guide me please? – Mr.DevEng Nov 05 '19 at 11:27
0

There is many articles and docs that explain how to properly build and publish the docker image using Jenkins. You should first read Using Docker with Pipeline which shows you an example with environment variable ${env.BUILD_ID}

node {
   checkout scm

   docker.withRegistry('https://registry.example.com', 'credentials-id') {

       def customImage = docker.build("my-image:${env.BUILD_ID}")

       /* Push the container to the custom Registry */
       customImage.push()
   }
}

Or to put it as a stage:

    stage('Push image') {
        docker.withRegistry('https://registry.hub.docker.com', 'docker-hub-credentials') {
            app.push("${env.BUILD_NUMBER}")
            app.push("latest")
        }
    }

I really do recommend reading Building your first Docker image with Jenkins 2: Guide for developers, which I think will answer many if not all of your questions.

Crou
  • 10,232
  • 2
  • 26
  • 31