Upgrade Cilium 1.20 with preflight checks and connectivity tests

John Burns

A Cilium upgrade changes the software that programs the Kubernetes networking and security datapath on every node. That is a larger operational boundary than a routine Deployment rollout. Agents, operators, CNI configuration, eBPF programs, service load balancing, and policy enforcement need to agree on a release while workloads continue to resolve DNS and establish connections.

This guide prepares a Helm-managed Kubernetes cluster for Cilium 1.20.0, runs the documented preflight workload, upgrades with a reviewed values file, and verifies the finished state with the Cilium CLI. A successful result is that the Cilium DaemonSet and operator report healthy, the installed images are 1.20.0, and cilium connectivity test completes without failures. The commands are documentation-verified against Cilium 1.20 documentation, not tested against a live cluster. Run them only against a cluster you administer and adapt the namespace, chart registry, API-server settings, and maintenance window to the installation.

Cilium 1.20.0 was released on 29 July 2026. Its release notes call out upgrade actions for some installations, including legacy mutual authentication, Envoy Go extensions, Kafka-aware policies, the cilium.io/v2alpha1 CiliumNodeConfig API, libnetwork integration, and custom CNI configuration. Treat those notes as an input to the change review, not as a generic checklist that can be skipped because a cluster does not use the highlighted features.

Establish the current state first

Begin from an administrator workstation with kubectl, Helm 3, and the Cilium CLI configured for the intended cluster. Confirm that the current Cilium installation is healthy before changing it. An existing error should be investigated separately; an upgrade is a poor way to discover whether an old connectivity problem was already present.

kubectl config current-context
kubectl get pods -n kube-system -l k8s-app=cilium -o wide
kubectl get deployment -n kube-system cilium-operator
cilium status --wait

The context command is a deliberate guardrail when an administrator has several kubeconfig contexts. The pod listing shows node placement and restart counts, while the Deployment check covers the operator separately from the agent DaemonSet. cilium status --wait waits for the Cilium components that the CLI checks to become ready. Record its output with the change ticket, including the current image versions.

Save the currently applied Helm values and manifest before selecting the new chart. The values file is the starting point for a reviewable upgrade, not a file to copy back unchanged.

mkdir -p cilium-upgrade-2026-08-06
cd cilium-upgrade-2026-08-06

helm get values cilium --namespace kube-system --all -o yaml \
  > cilium-values-before.yaml
helm get manifest cilium --namespace kube-system \
  > cilium-manifest-before.yaml
kubectl get ciliumnodes.cilium.io -o yaml \
  > ciliumnodes-before.yaml

The --all option includes values that Helm calculated or inherited, which helps make the running configuration visible during review. Protect these files as operational configuration: they can contain private endpoints, registry names, or environment-specific addresses even if they do not contain credentials. Do not add them to a public repository or attach them to an unrestricted ticket.

Compare cilium-values-before.yaml with the 1.20 chart defaults and the version-specific upgrade notes. In particular, identify the IPAM mode, routing mode, kube-proxy replacement setting, encryption settings, Gateway API or Ingress use, Hubble configuration, BGP control plane, and any custom CNI paths. Also identify the minor version currently installed. Cilium documents consecutive minor versions as the tested upgrade and rollback path, so a cluster far behind 1.20 needs intermediate, separately reviewed upgrades rather than a direct jump.

Do not use helm upgrade --reuse-values for a minor-version upgrade. Cilium documents that the flag ignores values newly introduced by the target chart and can produce an incorrect render. Instead, create cilium-values-reviewed.yaml from the saved values, remove deprecated or renamed settings after checking the target documentation, and have a second administrator review the diff. Keep the versioned file with the change record so a later rollback decision has an exact configuration reference.

Check the release and prepare the nodes

Use the official Cilium release page to select chart version 1.20.0 and record the container image digests appropriate for the deployment. Chart versions omit the leading v; image tags use it. Cilium distributes the chart through its OCI registry, and its documentation recommends that path. If your organization mirrors charts or images, verify that the mirror resolves to the same approved artifact before the change window.

Run Cilium’s preflight check before replacing the agent. The check pulls the target image onto every node and validates that the new agent can start. This reduces the chance that the rolling update stalls because a node cannot retrieve the image or accept the configuration.

helm upgrade --install cilium-preflight \
  oci://quay.io/cilium/charts/cilium \
  --version 1.20.0 \
  --namespace kube-system \
  --set preflight.enabled=true \
  --set agent=false \
  --set operator.enabled=false

kubectl get daemonset,deployments -n kube-system | \
  sed -n '1p;/cilium/p'
kubectl rollout status daemonset/cilium-pre-flight-check \
  --namespace kube-system --timeout=10m
kubectl rollout status deployment/cilium-pre-flight-check \
  --namespace kube-system --timeout=10m

The preflight chart intentionally enables the preflight components while disabling the normal agent and operator for that release. The preflight DaemonSet should have the same desired and ready count as the running Cilium DaemonSet. The preflight Deployment should become ready as well. A timeout, image pull failure, admission-policy denial, or failed pod is a stop condition. Inspect the affected pod and resolve that specific problem before continuing; do not proceed because other nodes became ready.

Clusters running kube-proxy-free Cilium require the Kubernetes API server address and port in the preflight configuration. Add the installation’s documented k8sServiceHost and k8sServicePort values to the preflight invocation or values file. Do not guess those values from a node address. They must match the way the existing Cilium deployment reaches the API server.

After the preflight resources are ready, remove them before performing the real upgrade:

helm uninstall cilium-preflight --namespace kube-system

Confirm that the temporary DaemonSet and Deployment disappear. Leaving the preflight release installed makes the normal Cilium state harder to interpret and can consume resources on every node.

Upgrade all Cilium components together

The agent and operator should run the same Cilium release. Upgrade the Helm release as one transaction using the reviewed values file. Set upgradeCompatibility to the version from which this cluster was originally installed, following the Cilium upgrade documentation. The placeholder below must be replaced during review; it is not necessarily the currently running version.

helm upgrade cilium \
  oci://quay.io/cilium/charts/cilium \
  --version 1.20.0 \
  --namespace kube-system \
  --values cilium-values-reviewed.yaml \
  --set upgradeCompatibility=1.<initial-minor-version> \
  --wait \
  --timeout 15m

--wait makes Helm wait for the resources it manages, and the timeout bounds the command rather than permitting an unattended wait. A Helm success does not replace application testing: it says the chart’s resources reached the conditions Helm waited for. Workloads using a userspace proxy, such as L7 policy, Ingress, or Gateway API traffic, can have connections disrupted during the upgrade and need to reconnect. Schedule that behavior with application owners instead of interpreting it as an unexpected outage.

If the command fails, stop the change and capture helm status cilium -n kube-system, the relevant pod events, and Cilium logs. Do not automatically roll back by applying the old manifest. A rollback should follow the approved plan, use the prior chart and reviewed values, and respect Cilium’s documented one-minor-version rollback boundary.

Verify the datapath rather than only the pods

Once Helm completes, confirm the control-plane state and image versions, then run Cilium’s connectivity suite from the administrator workstation.

cilium status --wait
kubectl get pods -n kube-system -l k8s-app=cilium \
  -o jsonpath='{range .items[*]}{.spec.nodeName}{"\t"}{range .spec.containers[*]}{.image}{" "}{end}{"\n"}{end}'

cilium connectivity test

The status output should show Cilium and the operator as OK, with the expected agent and operator image versions. The JSONPath output gives a concise per-node image inventory; it is useful for finding a node that did not roll during the upgrade. Do not treat a ready pod that is still running an older image as a successful upgrade.

The connectivity test creates a temporary namespace and workloads to exercise Cilium connectivity paths. A clean test ends with a report showing all tests successful and no warnings. The exact number of tests is release- and feature-dependent, so use the zero-failure result rather than copying a count from another cluster. If it fails, preserve the test output and inspect the named scenario, Cilium status, endpoint state, and recent agent logs before deleting evidence or retrying repeatedly.

Finally, check the application paths that matter to this cluster: a DNS lookup from a representative namespace, a Service request, any enforced NetworkPolicy path, and an ingress or Gateway route if one is enabled. Those checks are environment-specific because the Cilium connectivity suite cannot know the cluster’s identities, external dependencies, or business traffic. Record the results and the final Helm revision, then retain the pre-upgrade values and manifest until the approved rollback window has closed.

This process makes the Cilium 1.20 upgrade a sequence of observable gates: preserve and review the actual configuration, prove that every node can run the new image, upgrade the coordinated components, and test the network paths afterward. That is a safer boundary than a chart version change alone.

Sources