0

I have this workflow where I write some code and a docker image is deployed under latest. Currently, it deploys to my container registry and then I run this kubectl apply file.yaml after the container deploys, but K8s doesn't seem to recognize that it needs to re-pull and rollout a new deployment with the newly pulled image.

How can I basically feed in the YAML spec of my deployments and just rollout restart the deployments?

Alternatively, is there a better approach? I unconditionally am rolling out deployment restarts on all my deployments this way.

Ryan
  • 1,102
  • 1
  • 15
  • 30

1 Answers1

2

@daniel-mann is correct to discourage the use of :latest.

Don't read the word 'latest' when you see the tag latest. It's a default tag and it breaks the ability to determine whether the image's content has changed.

A better mechanism is to tag your images by some invariant value... your code's hash, for example. This is what Docker does with its image hashes and that's the definitive best (but not easiest) way to identify images: [[image]]@sha256:.....

You can use some SemVer value. Another common mechanism is to use the code's git commit for its tag: git rev-parse HEAD or similar.

So, assuming you're now uniquely identify images by tags, how to update the Deployment? The docs provide various approaches:

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#updating-a-deployment

But these aren't good for robust deployments (lowercase-D). What you should also do is create unique Deployment manifests each time you change the image. Then, if you make a mistake and inadvertently deploy something untoward, you have a copy of what you did and you can correct it (making another manifest) and apply that. This is a principle behind immutable infrastructure.

So...

TAG=$(git rev-parse HEAD)

docker build \
--tag=${REPO}/${IMAGE}:${TAG} \
...

docker push ${REPO}/${IMAGE}:${TAG}

Then change the manifest (and commit the change to source control):

sed --in-place "s|image: IMAGE|image: ${REPO}/${IMAGE}:${TAG}|g" path/to/manifest.yaml

git add /path/to/manifest.yaml
git commit --message=...

Then apply the revised (but unique!) manifest to the cluster:

kubectl apply \
--filename=/path/to/manifest.yaml \
--namespace=${NAMESPACE}
DazWilkin
  • 32,823
  • 5
  • 47
  • 88