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.

Want structured learning?

Take the full Kubernetes course →