Understanding Kubernetes kubeconfig

Lesson 1 of 39 7 min read Updated

Every kubectl command has to answer three questions: which cluster should it talk to, who are you, and which namespace should it use? The answers live in one file, the kubeconfig. You write them down once and kubectl reads them every time.

Think of kubeconfig as an address book for clusters. Instead of typing an API address, a username and a certificate on every command, you save them once and give each entry a short name.

kubectl looks for the file at ~/.kube/config on Linux and macOS, and at %USERPROFILE%\.kube\config on Windows. One file can describe many clusters, many users and many environments.

What you will learn

  1. How the three building blocks (clusters, users and contexts) fit together
  2. How to read a kubeconfig file line by line
  3. The commands you will use every day to inspect, switch and edit contexts
  4. How to work with several kubeconfig files at the same time

The big picture

A kubeconfig has three lists. A context pairs one cluster with one user, and optionally sets a default namespace. One context is always marked as the current one.

cluster --+
user --+--> context --> current-context
namespace --+ (a named (the one kubectl
pairing) uses right now)
SectionWhat it storesReal-world analogy
clustersAPI server address and CA certificate of each clusterThe address of an office building
usersCredentials (certificate, token or username/password) for each identityYour employee ID badge
contextsA named pairing of a cluster, a user and an optional namespaceA saved shortcut: "go to building A as employee 42"
A context is a bookmark. Switching context changes the cluster, your identity and the default namespace in one step. That is how you move between development, staging and production with a single command.

Anatomy of a kubeconfig file

Below is a minimal kubeconfig with one cluster, one user that authenticates with a bearer token, and one context that ties them together.

apiVersion: v1
kind: Config

clusters:
- name: dev-cluster
cluster:
server: https://dev-api.example.com:6443
certificate-authority-data: <base64-encoded-CA-cert>

users:
- name: dev-admin
user:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ii...

contexts:
- name: dev-admin@dev-cluster
context:
cluster: dev-cluster
user: dev-admin
namespace: development

current-context: dev-admin@dev-cluster
It is not a manifest. Never run kubectl apply on it. Save it as ~/.kube/config, or point to it with the KUBECONFIG environment variable.

clusters

Each entry describes one Kubernetes API server. Two fields matter most: server (the HTTPS address of the API) and certificate-authority-data (the base64-encoded CA certificate that proves the server is who it says it is).

users

Each entry holds the credentials kubectl shows to the API server. The most common types are:

  1. client-certificate-data + client-key-data: mutual TLS, most common in kubeadm clusters
  2. token: a bearer token, common for ServiceAccounts and OIDC flows
  3. exec: an external command that produces a token, used by cloud providers such as EKS, GKE and AKS

contexts

A context is a named combination of a cluster and a user, with an optional namespace. Switching context switches all three at once.

current-context

The top-level current-context field tells kubectl which context to use when you do not name one. You can read it, set it and switch it with commands, so you never need to edit the file by hand.

Treat kubeconfig like a password. It can contain private keys and tokens. Keep it out of Git and out of chat messages and tickets. kubectl config view hides secrets, while --raw prints them in plain text.

Everyday commands

These five cover most of your daily work:

I want to…Command
See which context is activekubectl config current-context
List all contexts (the active one has a *)kubectl config get-contexts
Switch to another contextkubectl config use-context <name>
Change the default namespace of the active contextkubectl config set-context --current --namespace=<ns>
Print the whole config with secrets hiddenkubectl config view

Inspect what is in the file

# Print the merged config (secrets are hidden)
kubectl config view

# Show certificates and tokens in plain text
kubectl config view --raw

# List the clusters and users it knows about
kubectl config get-clusters
kubectl config get-users

Add a cluster, a user and a context

You can register new entries from the command line instead of editing the YAML. First the cluster:

kubectl config set-cluster staging-cluster \
--server=https://staging-api.example.com:6443 \
--certificate-authority=/path/to/ca.crt

Then a user. Use a bearer token…

kubectl config set-credentials staging-admin \
--token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ii...

…or a client certificate and key:

kubectl config set-credentials dev-admin \
--client-certificate=/path/to/admin.crt \
--client-key=/path/to/admin.key

Finally the context that pairs them, with a default namespace:

kubectl config set-context staging-admin@staging-cluster \
--cluster=staging-cluster \
--user=staging-admin \
--namespace=staging

Remove entries you no longer need

kubectl config delete-context old-context-name
kubectl config delete-cluster old-cluster-name
kubectl config delete-user old-user-name

Hands-on: manage two clusters

Imagine you work against two clusters: a local development cluster created with kind, and a remote staging cluster. You will register both, create a context for each environment and switch between them.

Step 1 — Check where you start

See which contexts already exist:

kubectl config get-contexts

Step 2 — Confirm the development cluster

If you use kind, running kind create cluster already adds the cluster entry for you. Verify it:

kubectl config get-clusters

Step 3 — Add the staging cluster

Your ops team gives you the API server address, a CA certificate file and a bearer token. Register them:

kubectl config set-cluster staging-cluster \
--server=https://staging-api.example.com:6443 \
--certificate-authority=/home/dev/certs/staging-ca.crt

kubectl config set-credentials staging-developer \
--token=eyJhbGciOiJSUzI1NiIsImtpZCI6Ii...

Step 4 — Create one context per environment

A context for development that defaults to the dev namespace:

kubectl config set-context dev \
--cluster=kind-kind \
--user=kind-kind \
--namespace=dev

A context for staging that defaults to the staging namespace:

kubectl config set-context staging \
--cluster=staging-cluster \
--user=staging-developer \
--namespace=staging

Step 5 — Switch to development and verify

kubectl config use-context dev
kubectl config current-context

Expected output:

dev

Confirm you are talking to the right cluster by listing its nodes:

kubectl get nodes

Step 6 — Switch to staging

kubectl config use-context staging
kubectl get nodes
That is the payoff. One use-context command replaces long URLs and flags. Before any destructive command, run kubectl config current-context to confirm which cluster you are about to change.

Using more than one kubeconfig file

You do not have to keep everything in one file. Three techniques cover most needs.

Combine files on the fly with KUBECONFIG

Set KUBECONFIG to a list of file paths, separated by a colon (a semicolon on Windows). Kubernetes merges them in memory, so kubectl config get-contexts lists the contexts from every file.

# Linux / macOS
export KUBECONFIG=~/.kube/config:~/.kube/staging-config:~/.kube/prod-config

# Windows PowerShell
$env:KUBECONFIG = "$HOME\.kube\config;$HOME\.kube\staging-config;$HOME\.kube\prod-config"

Merge files permanently

To collapse several files into one, combine KUBECONFIG with kubectl config view --flatten:

# Linux / macOS
cp ~/.kube/config ~/.kube/config.bak # keep a backup first
export KUBECONFIG=~/.kube/config:~/.kube/staging-config
kubectl config view --raw --flatten > ~/.kube/merged-config
cp ~/.kube/merged-config ~/.kube/config
unset KUBECONFIG
The last cp overwrites ~/.kube/config. Keep the backup until you have checked the merged file with kubectl config get-contexts.

Override the file for a single command

Use the --kubeconfig flag to target one file for one command, without touching environment variables or your default file:

kubectl get pods --kubeconfig=/home/dev/certs/staging-config.yaml

Which file wins?

kubectl picks its kubeconfig in this order, highest priority first:

  1. The --kubeconfig flag on the command line
  2. The KUBECONFIG environment variable (a merged list of files)
  3. The default file at ~/.kube/config

Summary

The kubeconfig file tells kubectl how to reach your clusters and who you are. It has three sections: clusters (API server addresses), users (credentials) and contexts (named pairings of cluster, user and namespace).

  1. kubectl config get-contexts shows every environment you can reach.
  2. kubectl config use-context <name> switches between them instantly.
  3. kubectl config set-context --current --namespace=<ns> changes your default namespace.
  4. KUBECONFIG lets you work with several files at once, and --kubeconfig overrides the file for a single command.
  5. Keep kubeconfig private: it holds credentials.

Once you are comfortable with contexts, multi-cluster work, CI/CD pipelines and limited namespace access for teammates all build on the same few commands.