The default kubectl configuration file, ~/.kube/config, is actually a YAML file that can contain configurations for multiple Kubernetes clusters, contexts, and users.
Let’s say you’re working with a few different Kubernetes clusters – maybe one for development, one for staging, and a production cluster. You could have separate kubeconfig files for each, but that gets messy fast. The smart way is to merge them all into a single ~/.kube/config file.
Here’s how it looks in the wild. Imagine you have two kubeconfig files:
dev-cluster.yaml:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZ...
server: https://192.168.1.100:6443
name: development
contexts:
- context:
cluster: development
user: dev-user
name: dev
current-context: dev
kind: Config
preferences: {}
users:
- name: dev-user
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJ...
client-key-data: LS0tLS1CRUdJTiBQUk...
prod-cluster.yaml:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZ...
server: https://10.0.0.50:6443
name: production
contexts:
- context:
cluster: production
user: prod-admin
name: prod
current-context: prod
kind: Config
preferences: {}
users:
- name: prod-admin
user:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6I...
You want to combine these into your main ~/.kube/config. You don’t just copy-paste. You use kubectl config view and kubectl config use-context.
The core idea is that ~/.kube/config is a list of clusters, contexts, and users. When you merge files, you’re essentially appending to these lists and then telling kubectl which combination of cluster, user, and namespace (the "context") to use for commands.
Let’s get practical. Suppose your current ~/.kube/config looks like this:
apiVersion: v1
clusters:
- cluster:
server: https://your.existing.cluster.com:6443
name: existing-cluster
contexts:
- context:
cluster: existing-cluster
user: existing-user
name: existing-context
current-context: existing-context
kind: Config
preferences: {}
users:
- name: existing-user
user:
token: abcdef123456
First, let’s add the dev-cluster.yaml configuration. We’ll use kubectl config --kubeconfig dev-cluster.yaml view --flatten to get its content and then merge it. The --kubeconfig flag tells kubectl which file to read from, and --flatten ensures it outputs a single, self-contained config.
KUBECONFIG_DEV=$(kubectl --kubeconfig dev-cluster.yaml config view --flatten)
kubectl config --kubeconfig ~/.kube/config merge "$KUBECONFIG_DEV"
Now, your ~/.kube/config will have both existing-cluster and development clusters, existing-user and dev-user, and existing-context and dev contexts.
To verify, you can list your contexts:
kubectl config get-contexts
You should see output like:
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* existing-context existing-cluster existing-user default
dev development dev-user default
The * indicates the current-context. If you want to switch to the development cluster, you’d run:
kubectl config use-context dev
Now, repeat the process for prod-cluster.yaml:
KUBECONFIG_PROD=$(kubectl --kubeconfig prod-cluster.yaml config view --flatten)
kubectl config --kubeconfig ~/.kube/config merge "$KUBECONFIG_PROD"
And verify again:
kubectl config get-contexts
Output:
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
existing-context existing-cluster existing-user default
dev development dev-user default
* prod production prod-admin default
You can switch to the production cluster with kubectl config use-context prod.
The merge command is powerful because it intelligently combines the clusters, contexts, and users sections. If you try to merge a configuration with an identical cluster name, context name, or user name, kubectl will typically complain and ask you to resolve the conflict. This prevents accidental overwrites. The current-context field in the target ~/.kube/config file is not updated by merge; you must explicitly set it with kubectl config use-context.
The true magic of the kubeconfig file is that it’s just a YAML file, and Kubernetes clients are designed to merge these configurations. You can even set the KUBECONFIG environment variable to a colon-separated list of files, and kubectl will merge them all into a single effective configuration. This is how tools like kubectx and k9s manage multiple clusters seamlessly.
When you use kubectl config merge, the merge operation is happening against the configuration that kubectl config view would normally output from the target file (~/.kube/config by default). It takes the new configuration you’re providing (from KUBECONFIG_DEV or KUBECONFIG_PROD in our examples) and appends its clusters, contexts, and users sections to the existing ones. Importantly, it checks for name collisions. If a cluster named development already exists, and you try to merge another cluster also named development, kubectl will not overwrite it; it will error. This forces you to be explicit about how you want to handle duplicates, often by renaming contexts or users before merging, or by using a different kubeconfig file as the source for the new entries.
The next logical step after managing multiple clusters is understanding how to manage multiple namespaces within a single cluster context.