Consider this partial k8s deployment manifest for a basic rest application called myapp
spec:
replicas: 1
...
containers:
name: myapp
image: us.gcr.io/my-org/myapp.3
...
resources:
limits:
cpu: 1000m
memory: 1.5Gi
We store incremental builds in Google Container Registry (GCR) eg (myapp.1, myapp.2, myapp.3
). In the current setup, our CI system (Jenkins) does the following:
- Docker builds new image
myapp.4
and uploads to GCR - Runs
kubectl set image myapp.4
to update the deployment.
This works well for most deploys, but what about changes to the deployment manifest itself? For example, if we changed resource > cpu
to 1500m, we'd now have to manually run kubectl apply
. This step needs to be automated, which brings me to my point: instead of using kubectl set image
couldn't the build system itself just run kubectl apply
each time? When is it appropriate to use kubectl set image
vs. kubectl apply
in a CI/CD pipeline?
As long as the new image were provided, wouldn't kubectly apply
handle both image updates AND other config changes? If so, what are the pros/cons against just kubcetl set image
?
PS - our deploys are simple and mainly rely on single replica and 100% uptime is not necessarily required.
CodePudding user response:
With a kubectl set image
, you only patch the image deployed in your deployment. To patch the other values (CPU, memory, replicas,...) you can use other commands like path
or set repiclas
The problem is that you loose the consistency with your original YAML definition. If your cluster crash and you want to recreate one, you won't have the exact same deployment because your YAML file will be outdated (the "patches" won't be known)
With kubectl apply
you overwrite the existing control plane config and you set the exact content of your YAML. It's more consistent and it's a common practice when you are in GitOps mode.
Which one to use? All depends on what you need and what you want to achieve. I prefer the kubectl apply
mode for its consistency and its replayability, but it's up to you!
CodePudding user response:
Use whatever suits your case the best. Just remember that the CI will be the "source of truth" when it comes to where resources and such are applied. If you change it somewhere else and run the CI job, it will update it again.
Most CI engines have the ability to only trigger a certain job in case a file have been changed. That way, you could patch the image in case the manifest have not changed and run a full apply in case the manifest have changed.
I usually use the image patch method personally, as I prefer to have my Kube files separated from my sourcecode, but as said, whatever fits your case the best!
CodePudding user response:
Each time you make changes to your application code or Kubernetes configuration, you have two options to update your cluster: kubectl apply
or kubectl set 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.
You can use kubectl apply to update a resource by applying a new or updated configuration