NKP 2.18 is out. We upgraded, then checked the changelog against the cluster
Nutanix released NKP 2.18 in July 2026. We run NKP on our own infrastructure (air-gapped management cluster, 3 control plane + 6 workers, Ultimate license, AHV), so instead of summarizing the release notes we upgraded, and then went through the claims one by one with kubectl.
Short version: the release is good. The release notes are not always accurate. And some of the biggest changes are either soft-pedaled or missing entirely: the release notes recommend you "use NKPCluster instead of editing the CAPI Cluster" without mentioning that a webhook now rejects CAPI edits outright (your GitOps pipeline finds out on its first real commit), the control plane gets a TLS hardening pass nobody documents, the root CA quietly gets a 10-year lifetime, and topology changes freeze during platform upgrades. Details below, all reproduced on our cluster.
This is the first post of our 2.18 series. The full upgrade story, including everything that broke, comes next.
What Nutanix announced
| Area | 2.17 | 2.18 |
|---|---|---|
| Kubernetes | 1.34.x | 1.35.2 |
| Container runtime | containerd 1.x | containerd v2 (2.1.6) |
| Cluster API | 1.10.x, v1beta1 | 1.12.4, v1beta2 (CAPX and CAPPP migrated) |
| Cluster lifecycle API | CAPI Cluster / KommanderCluster | NKPCluster (clusters.nkp.nutanix.com), now the API you are supposed to use |
| Logging | Loki 2.9 (loki-distributed chart) | Loki 3.x (new grafana-loki-v3 app, OTLP support) |
| Upgrade safety | none | preflight checks on cluster create/update |
| Air-gapped bundle | NDK downloaded separately | NDK included in the default bundle |
| Compliance | - | FIPS 140-3 clusters, Ubuntu Pro CIS/STIG image |
| PC/AOS minimum | - | pc.7.3 / AOS 7.3 |
Deprecated in 2.18: KubeFed (the thing that federates workspaces and projects to attached clusters), the kommander-federated-edit ClusterRole (you have to remove bindings yourself), the Kubernetes Dashboard, the legacy EKS workflow, systemd-based control plane cert renewal (migrated automatically), and the AI Navigator Cluster Info Agent (removed automatically).
The version table vs the cluster
We compared the component versions in the release notes with what actually runs on our upgraded cluster. Five differences. All of them in the same direction: the cluster runs newer versions than documented.
| Component | Release notes | Our 2.18 cluster |
|---|---|---|
| Cilium | 1.19.2 | v1.19.4 |
| MetalLB | 0.15.2 | v0.15.3 |
| Nutanix CSI | 3.7.0 (docs storage table) | ntnx-csi:3.7.1 |
| Dex | 2.37.0 | v2.42.0 |
| CAPX | 1.9.2 | v1.9.6 |
| etcd | 3.5.24 | 3.5.24-0, matches |
| containerd | 2.1.6 | 2.1.6-d2iq.1, matches |
| Traefik | 3.6.12 | v3.6.12, matches |
The CSI line matters. NDK 2.2 came out at the same time and requires CSI 3.7.1 or newer. The NKP docs say 2.18 ships 3.7.0. If you only read the two compatibility matrices, you conclude NDK 2.2 does not work on NKP 2.18 without a manual CSI bump. Wrong: the cluster ships 3.7.1, the docs table is stale. We almost planned work around this. Check your own cluster:
kubectl get ds -n ntnx-system -o jsonpath='{range .items[*]}{range .spec.template.spec.containers[*]}{.image}{"\n"}{end}{end}' | grep ntnx-csi
What the changelog does not mention
CRDs have creation timestamps. So after an upgrade you can see exactly what got installed and when. The list below is what appeared on our cluster during the 2.18 upgrade and is not in the release notes.
Three new CRDs and their controllers arrive with the Kommander upgrade:
nkpclusters.clusters.nkp.nutanix.com the new cluster API
loggingstacks.loggingstack.nkp.nutanix.com drives the Loki v2 to v3 migration
managementplanes.managementplane.nkp.nutanix.com a "ManagementPlane" object that owns the new operators
The upgrade also creates an NKPCluster object for every cluster you already have. Watch out: on upgraded environments the NKPCluster gets the KommanderCluster's name (host-cluster in our case), which does not match the CAPI cluster name. The management cluster upgrade command documented in the guide builds on that name and fails. Use the CAPI cluster name and namespace instead.
Your CAPI Cluster objects are now read-only - enforced, not just recommended. The release notes do mention NKPCluster (NCN-113041): "update the NKPCluster directly and use its name in nkp cluster commands and GitOps workflows, instead of editing the CAPI Cluster." What they do not say is that this is not advice. A new admission webhook compares every write to a managed CAPI Cluster's topology against the NKPCluster and rejects it if it differs - kubectl, controllers, Flux, all of them. The guide admits it in one paragraph, inside the GitOps upgrade chapter that non-GitOps users will never open. And it fails late: as long as your manifests match the live state, applies pass. The first change that actually differs gets a Forbidden. If you manage clusters with GitOps, read our dedicated post on this before upgrading, not after.
Topology changes are frozen while platform apps upgrade. The NKPCluster controller just requeues them, and only logs it at INFO level. Practical consequence we hit: a cluster whose platform upgrade is stuck because it lacks CPU cannot be given more CPU, because adding a node is a topology change. You have to free capacity on the cluster instead.
The CAPI stack is now operator-managed. The upgrade installs cluster-api-operator: 7 new operator.cluster.x-k8s.io CRDs, 3 new namespaces. And since NKP installs all six infrastructure providers on the management cluster even if you only deploy on Nutanix, their 2.18 bumps bring new upstream CRDs with them: ROSA networks and role configs from CAPA 2.11, GKE cluster templates from CAPG 1.11. Unused on a Nutanix cluster, visible to every CRD inventory and security scan. Check: kubectl get infrastructureproviders -A.
The 2.18 cluster upgrade installs Multus CNI on every node. Not just a CRD: a privileged DaemonSet (multus in kube-system, image multus-cni:v4.2.4-thick), deployed as a CAREN cluster addon during the Kubernetes upgrade. Our workload clusters, still on the old node stack, have no trace of it - it ships with the 2.18 node roll specifically. Nothing creates a NetworkAttachmentDefinition, so it sits there idle. Our guess: groundwork for multi-network support on AHV. Facts: a new privileged pod on all your nodes that no document mentions. kubectl get ds multus -n kube-system to see yours.
The kommander root CA gets extended to 10 years. The upgrade logs a single line about setting kommander-ca duration to 87600h. Fine by us, but if you track CA lifetimes for compliance, this changed without asking you.
The upgrade writes to your management git repo. Removing the deprecated AI Navigator apps includes deleting their folders from the git-operator repository. Correct behavior, still worth knowing it happens.
Under the hood
Our workload clusters are still on Kubernetes 1.34.3 with the same 2.18 platform version, which makes a clean before/after comparison for the node stack:
- containerd 1.7.29 to 2.1.6 is the real jump. Same Rocky Linux 9.7, kernel one patch level newer. No kube-proxy on either (Cilium replaces it).
- The control plane got TLS hardening nobody mentioned: the 1.35 kube-apiserver pins an explicit list of six ECDHE cipher suites (1.34 uses Go defaults), and kube-scheduler and kube-controller-manager both gain
--tls-min-version=VersionTLS12. The funny part: the guide's own CIS appendix still lists cipher pinning as a manual remediation you are supposed to do yourself. The product now does it by default and the hardening guide has not noticed. If you run compliance scans, expect your TLS findings to change - for the better. - Apart from TLS, the control plane flags are identical between 1.34 and 1.35. No new admission plugins, no new feature gates.
- Kubelet still sets
podPidsLimit: 4096(checked via configz). That is the CIS default behind the "Trino goes CrashLoopBackOff" known issue, and it applies to upgraded clusters too. - Eight new admission webhooks total, in two waves (NKPCluster/ManagementPlane with Kommander, capi-operator/CAPX with the cluster upgrade).
- For scale: the management cluster now serves 431 API resource types. A workload cluster serves 192.
Deprecated does not mean removed
Checked live after the upgrade: the Kubernetes Dashboard is still installed (and was even upgraded to 7.14.1), KubeFed still runs and still federates everything (our RBAC and project setup work unchanged), and kommander-federated-edit still exists as a ClusterRole. The only thing you must do is remove bindings to it. Careful: bindings created through the UI do not show up in your GitOps repo, so audit the live cluster:
kubectl get clusterrolebindings -o wide | grep kommander-federated-edit
We found one on ours, created months ago through the UI. Nobody remembered it.
One bug that survived
Not in the release notes: the NKP Insights CronJob nkp-insights-credentials-rotate is broken in 1.7 and still broken in the 1.8.4 that ships with 2.18. Its container args start with delete but there is no kubectl command in the spec, so every run fails with exec: "delete": executable file not found in $PATH. It runs quarterly and rotates credentials, so the failure is easy to miss. Check yours:
kubectl get cronjob nkp-insights-credentials-rotate -n kommander \
-o jsonpath='{.spec.jobTemplate.spec.template.spec.containers[0].command}'
# empty output = broken
Should you upgrade?
Yes. The release is solid and our cluster is in better shape on 2.18 than it was before, partly because the upgrade forced us to fix things that had been quietly broken for months. But plan for the sharp edges: the Loki migration blocks the whole platform upgrade if you customized log storage, GitOps setups need the NKPCluster migration, a PDB with zero allowed disruptions will freeze your node roll, and the CLI timeouts are shorter than a real upgrade takes.
All of that is the rest of this series: the upgrade field report, the Loki v2 to v3 deep dive, and the GitOps migration. Each one with the logs to back it up.


