Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto Update Container Image When New Build Released on Kubernetes

I have a private repository. I want to update my image on Kubernetes automatically when the image is updated on this private repository. How can I achieve this?

like image 504
akuscu Avatar asked Dec 31 '19 11:12

akuscu


People also ask

Does Kubernetes auto pull latest image?

If a tag is not specified in the manifest file, Kubernetes will automatically use the image tagged latest.

How do I automatically update Docker images?

By pushing a new Docker image to your repository, Watchtower will automatically trigger a chain of events to update your running container's base Docker image. When Watchtower detects a new push, it will pull the new base image, gracefully shutdown your running container, and start it back up.

How do you update Docker image on Kubernetes deployment?

To update an existing deployment, you can use the kubectl edit command. Simply update the image attribute for your containers and save the Deployment. The deployment will automatically create new pods with the new image you specified, and terminate pods using the old image in a controlled fashion.

Does kubectl apply update image?

You can use kubectl set to make changes to an object's image , resources (compute resource such as CPU and memory), or selector fields. The kubectl set image command updates the nginx image of the Deployment's Pods one at a time. You can use kubectl apply to update a resource by applying a new or updated configuration.


5 Answers

Kubernetes natively does not have the feature of automatically redeploying pods when there is a new image. Ideally what you want is a tool which enables GitOps style deployment wherein state change in git will be synced to the Kubernetes cluster. There is Flux and ArgoCD open source tools which supports GitOps.

Recently there is an announcement to combine these two projects as ArgoFlux.

like image 78
Arghya Sadhu Avatar answered Oct 24 '22 02:10

Arghya Sadhu


You should assign some sort of unique identifier to each build. This could be based off a source-control tag (if you explicitly tag releases), a commit ID, a build number, a time stamp, or something else; but the important detail is that each build creates a unique image with a unique name.

Once you do that, then your CI system needs to update the Deployment spec with a new image:. If you're using a tool like Kustomize or Helm, there are standard patterns to provide this; if you are using kubectl apply directly, it will need to modify the deployment spec in some way before it applies it.

This combination of things means that the Deployment's embedded pod spec will have changed in some substantial way (its image: has changed), which will cause the Kubernetes deployment controller to automatically do a rolling update for you. If this goes wrong, the ordinary Kubernetes rollback mechanisms will work fine (because the image with yesterday's tag is still in your repository). You do not need to manually set imagePullPolicy: or manually cause the deployment to restart, changing the image tag in the deployment is enough to cause a normal rollout to happen.

like image 42
David Maze Avatar answered Oct 24 '22 04:10

David Maze


Have a look at the various image pull policies.

imagePullPolicy: always might come closest to what you need. I don't know if there is a way in "vanilla" K8s to achieve an automatic image pull, but I know that RedHat's OpenShift (or OKD, the free version) works with image streams, which do exactly what you ask for.

like image 27
bellackn Avatar answered Oct 24 '22 03:10

bellackn


The imagePullPolicy and the tag of the image affect when the kubelet attempts to pull the specified image.

imagePullPolicy: IfNotPresent: the image is pulled only if it is not already present locally.

imagePullPolicy: Always: the image is pulled every time the pod is started.

imagePullPolicy is omitted and either the image tag is :latest or it is omitted: Always is applied.

imagePullPolicy is omitted and the image tag is present but not :latest: IfNotPresent is applied.

imagePullPolicy: Never: the image is assumed to exist locally. No attempt is made to pull the image.

So to achieve this you have to set imagePullPolicy: Always and restart you pod and it should pull a fresh latest copy of image. I don't think there is any other way in K8s

Container Images

like image 32
Nandan Avatar answered Oct 24 '22 02:10

Nandan


I just wrote a bash script to achieve this.My imagePullPolicy option is always and i am running this script with crontab.(You can check everytime with infinite loops).It is checking repository and if any change occured , it is deleting the pod (automatically because of imagePullPolicy set Always) and pulling updated image.

#!/bin/bash
registry="repository_name"
username="user_name"
password="password"

##BY this you can append all images from repository to the array
#images=($( echo $(curl -s https://"$username":"$password"@"$registry"/v2/_catalog | jq .repositories | jq .[])))
##Or you can set manuaaly your image array
images=( image_name_0 image_name_1 )
for i in "${images[@]}"
do
old_image=$(cat /imagerecords/"$i".txt)
new_image=$(echo $(curl -s https://"$username":"$password"@"$registry"/v2/"$i"/manifests/latest | jq ."fsLayers" | jq .[]))


if [ "$old_image" == "$new_image" ];then
echo "image: "$i" is already up-to-date"
else
echo "image: " $i" is updating"
kubectl delete pod pod_name
echo $new_image > /imagerecords/"$i".txt
fi
done
like image 2
akuscu Avatar answered Oct 24 '22 03:10

akuscu