Andrew Mercer
on this page

How KUBECONFIG merging works

kubectl normally reads a single file at ~/.kube/config, but the KUBECONFIG environment variable can list multiple files separated by : (Linux/macOS) or ; (Windows). When more than one file is listed, kubectl config view reads all of them and merges their clusters, contexts, and users entries into a single in-memory view — it doesn't touch any of the source files unless you redirect the output somewhere yourself.

KUBECONFIG=~/.kube/cluster0:~/.kube/cluster2:~/.kube/cluster3:~/.kube/cluster4 kubectl config view --merge --flatten > ~/.kube/config-merged

(Adjust the file list to whatever kubeconfig files you actually have — the numbering above is just an example set of cluster names, not a required naming scheme.)

  • --merge tells kubectl config view to combine all files listed in KUBECONFIG rather than only showing the first one.
  • --flatten inlines any certificate/key data that the source files reference by file path (client-certificate: /path/to/cert) directly into the merged output as base64 (client-certificate-data: ...). Without --flatten, the merged file would still work on this machine, but would break if copied elsewhere, since the embedded file paths wouldn't resolve on a different host.
  • The > ~/.kube/config-merged redirect is what actually writes a new file — kubectl config view on its own only prints to stdout and never modifies anything.

Symlinking it as the default config

ln -s config-merged config

This only creates a working symlink if run from inside ~/.kube, since ln -s config-merged config creates a relative symlink pointing at the plain filename config-merged in whatever directory you're currently in:

cd ~/.kube
ln -s config-merged config

Once ~/.kube/config is a symlink to ~/.kube/config-merged, kubectl picks it up automatically as its default config (no KUBECONFIG env var needed for day-to-day use), since ~/.kube/config is kubectl's built-in default path.

If ~/.kube/config already exists as a real file (not yet a symlink), back it up first rather than overwriting it blindly:

mv ~/.kube/config ~/.kube/config.bak
cd ~/.kube && ln -s config-merged config

Naming collisions

If two source kubeconfig files happen to use the same context, cluster, or user name (e.g. two clusters both named default), --merge keeps only one of them — whichever file kubectl processed last for that name silently wins, with no warning printed. Before merging files from different sources, it's worth checking each one's context/cluster/user names for collisions:

kubectl config view --kubeconfig=~/.kube/cluster0 -o jsonpath='{.contexts[*].name}'

Rename a context to avoid a collision before merging:

kubectl config rename-context old-name new-name --kubeconfig=~/.kube/cluster0

Verify the merged result

kubectl config get-contexts

This lists every context now available in the merged config, with a * marking the currently active one. Confirm the count matches what you expect (e.g. 4 source files should generally produce 4 contexts, assuming no collisions silently dropped one).

Switch between clusters

kubectl config use-context [ context_name ]

Sets current-context in the config file, so subsequent kubectl commands target that cluster until you switch again. To check which context is currently active without listing all of them:

kubectl config current-context

To temporarily target a different context for a single command without changing the persistent default:

kubectl --context=[ context_name ] get pods

Re-running the merge later

Since config-merged is a generated artifact, not a source of truth, re-run the same KUBECONFIG=... kubectl config view --merge --flatten > ~/.kube/config-merged command any time one of the source cluster kubeconfig files changes (e.g. after rotating a cluster's certificates) — the symlink at ~/.kube/config will automatically reflect the regenerated file without needing to be recreated.

Security note

The merged file contains embedded credentials (client certs/keys or tokens) for every cluster listed, inlined via --flatten — treat ~/.kube/config-merged with the same care as the individual source files, and make sure its permissions aren't more permissive than the originals:

chmod 600 ~/.kube/config-merged

See also

Monitoring and Inspecting Resources with kubectl covers --context= usage as part of a broader inspection workflow once multiple clusters are configured.