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=$HOME/.kube/cluster0:$HOME/.kube/cluster1:$HOME/.kube/cluster2:$HOME/.kube/cluster3 \
kubectl config view --flatten > $HOME/.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.)
- Merging is the default.
kubectl config viewmerges every file inKUBECONFIGautomatically (--mergedefaults totrue, so adding it changes nothing). --flatteninlines 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-mergedredirect is what actually writes a new file —kubectl config viewon 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), the merge keeps only one of them — the first file in the KUBECONFIG list that defines that name wins, and the later ones are silently dropped with no warning. Before merging files from different sources, it's worth checking each one's context/cluster/user names for collisions:
kubectl config view --kubeconfig=$HOME/.kube/cluster0 -o jsonpath='{.contexts[*].name}'
Rename a context to avoid a collision before merging. Use $HOME rather than ~ here, because the shell doesn't expand ~ after --kubeconfig=:
kubectl config rename-context old-name new-name --kubeconfig=$HOME/.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 --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
To avoid the file ever existing with looser permissions, generate it under a restrictive umask:
(umask 077; KUBECONFIG=... kubectl config view --flatten > ~/.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.