TT Lab
Get started
Learn Learning paths Courses

KCNA — Kubernetes and Cloud Native Associate

A successful deployment command is not a successful release

Continue in TT Lab

One-line summary

That the API accepted a new declaration, that a controller observed that declaration, and that a new process handles requests are different pieces of evidence.

Why this was needed

On a Friday afternoon, the command to deploy a new version succeeded. The Deployment's AVAILABLE is also 2. Yet users keep seeing the old screen. Since the deployment succeeded, can we conclude it is a browser cache problem? Not yet. While two healthy old Pods handle requests, one new Pod that is not ready may be failing next to them. Availability being maintained is welcome news, but that fact alone cannot prove the delivery of the new version.

Cloud native delivery does not end with moving source code into files. It is a flow of declaring what to run, turning that declaration into real processes, observing whether they are ready to receive requests, and deciding which state to return to if something fails. CI focuses on integrating and testing changes, and continuous delivery focuses on keeping the software in a deployable state. Also distinguish it from continuous deployment, which automatically releases every change to production. The fact that a commit exists in Git is only a record of some of these steps, not evidence of a user response.

How it works

A Deployment declares the desired Pod template and the number of replicas. The Deployment controller creates or adjusts ReplicaSets, and the ReplicaSet maintains the required Pods. When kubelet runs the containers and readiness reports whether they are ready, the Service's delivery targets reflect that state. Because different components each converge on their own, you must not read a single API response as completion of the whole job.

When investigating, look at the connections between objects rather than a single name. Follow the Deployment UID, the ReplicaSet UID that points to that object as its owner, and in turn the Pod UID that points to that ReplicaSet as its owner. This keeps you from mistaking a similarly named Pod that a person created by hand for the result of a real rollout. Whether the new version has started is checked separately through the container state and the ready condition, and which version is being delivered through the actual responses.

A Deployment's generation is used to compare the generation of declaration changes, and status.observedGeneration the generation the controller has observed. Even if the two are equal, it does not mean all the new version is ready. updatedReplicas looks at the replicas corresponding to the new template, and availableReplicas at the replicas that satisfy the availability condition. Whether it is complete must be investigated by looking at these values, the conditions, and actual responses together. In particular, the available replicas during a rollout can include the old version.

kubectl -n kcna-delivery get deployment web -o yaml
kubectl -n kcna-delivery get replicasets
kubectl -n kcna-delivery get pods -l app=web
kubectl -n kcna-delivery get endpointslices

Not every change creates a new ReplicaSet. Changing an explanatory annotation on the Deployment object itself and changing an environment variable inside spec.template are in different places. This lab first changes only the object's annotation and checks that the existing Pods, ReplicaSet, and revision are kept. Later, it changes the template's RELEASE from v1 to v2 and compares the creation of a new ReplicaSet and new Pods. What matters is not whether the request was made with the same kubectl but which declaration was changed.

Configuration is also a separate boundary. A ConfigMap is an object that holds non-secret configuration data. Here, the color value is injected as a container environment variable. Even if you change the ConfigMap's blue to green, the environment variables of an already running process are not automatically re-read. The ConfigMap API may say green while the response is still blue. Do not conclude this is data loss; check when and how the configuration was consumed. You must not generalize projecting it as a file volume, or having the app read the API directly, to the same update rule as environment variable injection.

What it looks like in practice

If you mix several meanings into a single green light on a deployment status screen, the response also goes to the wrong place. GitOps synchronization can explain that the desired declaration and the cluster declaration match, but whether the new app's business requests succeed needs separate verification. The same goes for image tags. You cannot guarantee that the same bytes are running just because a movable tag string is the same. This experiment pins the image digest and changes the release environment variable of a small synthetic app. It is not a lab that builds a real new image or verifies supply-chain signatures.

In production you must also check the new version identifier, the error rate, latency, and the necessary business paths. Reading six HTTP responses here is a sample for comparing the states in the class, not a check that statistically guarantees zero downtime or a service-level objective. The reason for preserving the healthy comparison group is also to tell scopes apart. Do not treat the declaration change of the experiment target and a cluster-wide outage as the same cause.

What you will do in the lab that follows

From a baseline where v1 and blue respond, you change only the annotation, and change only the ConfigMap to green, and compare Pod identities each time. Then you do a real rollout with the v2 template and check whether the new Pods' responses become green. The reading that follows explains the boundary for protecting existing responses and recovering when a v3 that never becomes ready comes in.

Official sources: Deployment · ConfigMap.