How-to guide Operate a cluster
Preview changes with kix plan and kix diff
Preview a deploy with a server-side dry run, or compare rendered manifests with live Kubernetes resources using read-only access.
Kix has two previews, and neither changes the cluster:
kix planruns the deploy with every write sent as a server-side dry run. Use it to preview a deploy you are about to run. It needs the same permissions as the deploy.kix diffonly reads. Use it where the job has read-only credentials, or no cluster access at all, such as a pull request check.
Preview a deploy with kix plan
Section titled “Preview a deploy with kix plan”Run the plan with the flags you will deploy with:
❱ kix plan how-to-application --prune The output is the package-grouped plan kix deploy prints before it asks for
confirmation. Each field change is what the apiserver says the apply would
produce. After the packages, the plan lists anything the deploy would stop
on: a field another manager owns, a webhook or admission policy denial, a
validation error, an immutable field, or an RBAC refusal. Every refusal is
listed, so you can fix them all before deploying.
The plan exits 0 when the deploy would change and delete nothing, 2 when
it would change or delete something, and 3 when it would stop. In CI, treat
0 and 2 as success and block on 3, a deploy the cluster would refuse;
kix plan has a script that does
this.
Objects whose CRD or namespace the same deploy creates cannot be checked by a dry run. The plan lists them under “Not checked by the dry run” with the changes from comparing builds. On a cluster’s first deploy most objects are in this list.
Compare desired and live resources with kix diff
Section titled “Compare desired and live resources with kix diff”Start from a cluster that matches what is deployed. Kix compares only the fields it applied, so an unchanged cluster reports nothing and exits 0:
❱ kix diff how-to-application
⠁ Fetching live cluster state... Discovering API resources...
Fetching managed resources (60 resource types)...
Fetched 16 resources across 60 resource types
3 packages: 3 unchanged, 0 changed, 0 added, 0 removed
No differences found. Now change the production message in the cluster definition and run the same command:
❱ kix diff how-to-application
⠁ Fetching live cluster state... Discovering API resources...
Fetching managed resources (60 resource types)...
Fetched 16 resources across 60 resource types
3 packages: 2 unchanged, 1 changed, 0 added, 0 removed
how-to-app
~ production 1.0.0 (1 changed, 4 dep-affected)
~ ConfigMap/production@how-to-app
~ $.data.index.html:
--- old
+++ new
@@ -1 +1 @@
-Hello from production
+Updated production message
~ Deployment/production@how-to-app (via dependency)
~ Job/production-health@how-to-app (via dependency)
~ PackageInstance/production@how-to-app (via dependency)
~ Service/production@how-to-app (via dependency)
Activation: how-to-application-gb5d6ry45b5l -> how-to-application-s3ca8rcni68g
(exit code: 2) The report names the ConfigMap you edited and shows the changed value. The resources marked “via dependency” have no content change of their own. Their identity hash moves because they depend on the ConfigMap, so Kix will re-stamp them on the next deploy.
Read the diff
Section titled “Read the diff”The report is grouped by package, and each line tells you something different:
- A package marked added or removed appears on only one side.
- A resource marked
~has a content change, shown as a diff of the fields that differ. - A resource marked “via dependency” has no content change of its own. Only its identity hash moved, because something it depends on changed.
- A cluster-level group collects resources that belong to no package, such as namespaces and custom resource definitions.
- An activation line names the deployment record this change would create.
Read the packages you edited first, then the dependent resources, which tell you how far the rollout reaches. A non-empty diff exits with status 2, which lets CI tell a change from a clean comparison.
When the deployed build is on this machine, a field someone changed on the
cluster is tagged (reverts drift) when the deploy puts it back, and a
Drift section at the end names the field manager that changed it. When there
are changes, the last line reminds you that kix diff cannot see admission
webhooks, field ownership conflicts, or deploy refusals. Run kix plan for
those.
Select the flake and context
Section titled “Select the flake and context”By default, Kix evaluates the current directory and reads the current kubectl context. Set either input explicitly when needed:
❱ kix diff how-to-application --flake ./infrastructure --context kind-kix-demo The flake supplies the desired manifests. The Kubernetes context supplies the live manifests being compared.
Produce review-friendly output
Section titled “Produce review-friendly output”Select Markdown output when attaching the result to a pull request or change review:
❱ kix diff how-to-application --output markdown Show outputHide output · 28 lines
⠁ Fetching live cluster state... Discovering API resources...
Fetching managed resources (60 resource types)...
Fetched 16 resources across 60 resource types
### kix diff
**Plan:** 1 updated, 0 added, 0 removed, 2 unchanged
**Resources:** 1 with real content changes, 4 dep-affected (hash bump only)
#### Changed packages
<details>
<summary><code>how-to-app/production</code> 1.0.0 (1 changed, 4 dep-affected)</summary>
**Modified resources:**
- `ConfigMap/production@how-to-app` (1 diffs)
**Dep-affected (hash bump only, no content change):**
- `Deployment/production@how-to-app`
- `Job/production-health@how-to-app`
- `PackageInstance/production@how-to-app`
- `Service/production@how-to-app`
</details>
**Activation:** `how-to-application-gb5d6ry45b5l` → `how-to-application-s3ca8rcni68g`
(exit code: 2) Redirect it into a file for the job to publish:
❱ kix diff how-to-application --output markdown > kix-diff.md kix plan --output markdown produces the same layout with the write-path
checks added, for a job that has the deployer’s credentials.
Use JSON when another program will process the result:
❱ kix diff how-to-application --output json > kix-diff.json kix diff and kix plan print the same JSON document, so one consumer can
read either. The checks a read-only diff cannot make read
{ "status": "not_checked", "reason": "read_only" }. By default the JSON
names each changed resource and counts its changed fields. Add
--detail fields to list each field change, old to new:
❱ kix diff how-to-application --output json --detail fields > kix-diff.json { "path": "$.spec.replicas", "change": "changed", "old": 2, "new": 3, "labels": ["intended"] }change is added, removed, or changed. labels is present when the
deployed build is on this machine. Add --detail manifests to also include,
under manifests on each package, the old and new manifest of every resource
that changes, is added, or is removed, for a tool that shows a line-by-line
diff. In kix plan the two manifests of an object the cluster checked are
the live object and the cluster’s dry-run result:
❱ kix diff how-to-application --output json --detail manifests > kix-diff.json At both levels, Secret values and hashes of them read (secret, not shown),
or (secret, changed, not shown) on the new side when the value changes. A
field value larger than 16 KiB, or a manifest larger than 256 KiB, reads
(N bytes, not shown). A password written as a literal container env
value or into a ConfigMap is shown as it is, so keep secrets in Secrets.
Confirm a clean result
Section titled “Confirm a clean result”After deploying the intended change, run kix diff or kix plan again. A
clean result confirms that Kix does not currently plan another content
change.
kix diff compares the fields Kix applied. Use kix drift when you need to
know who else owns a field and what they changed.