3.2 kubeconfig: Contexts, Clusters, and Users
Right, let’s talk about your kubeconfig file. This is the single most important file on your local machine when you’re working with Kubernetes. It’s the master keyring, the backstage pass, the digital diplomat that tells kubectl exactly who you are, where you want to go, and how to prove you’re allowed to be there. If kubectl is your spaceship, this is the navigation computer. And like any good navigation computer, it can be configured to have multiple destinations.
By default, kubectl looks for this file at ~/.kube/config. Don’t worry, it creates one for you automatically if it’s not there, usually populated with the details of your first cluster (like a local Docker Desktop or Minikube instance). But the real power comes from managing multiple clusters.
The Anatomy of a Kubeconfig
A kubeconfig file isn’t some black magic; it’s just a YAML file with three main sections and one crucial combining section. Let’s break it down.
apiVersion: v1
kind: Config
clusters:
- name: my-production-cluster
cluster:
certificate-authority-data: <redacted_ca_cert>
server: https://api.production.example.com:6443
- name: my-staging-cluster
cluster:
insecure-skip-tls-verify: true # Please don't do this in prod. Seriously.
server: https://api.staging.example.com:6443
users:
- name: production-admin
user:
client-certificate-data: <redacted_client_cert>
client-key-data: <redacted_client_key>
- name: staging-developer
user:
token: <redacted_bearer_token>
contexts:
- name: prod-admin-context
context:
cluster: my-production-cluster
user: production-admin
namespace: important-app # Optional: sets a default namespace
- name: staging-dev-context
context:
cluster: my-staging-cluster
user: staging-developer
current-context: staging-dev-context # This is what kubectl uses right now
Think of it like this:
- Clusters: These are the actual API endpoints. They define where you’re talking to.
- Users: These are the credentials. They define who is talking. Notice the different authentication methods—certs, tokens, etc. This is where you’d also put
execfor IAM magic (more on that later). - Contexts: This is the genius part. A context is a tuple that combines a user, a cluster, and optionally a namespace. It answers the question: “As who do I want to talk to which cluster, and in what namespace by default?”
- current-context: This is the context that
kubectlwill use by default for all your commands. It’s the one that’s currently “active.”
Managing Contexts Like a Pro
You don’t have to edit that YAML file by hand every time (though you can, and I often do for fine-tuning). kubectl has commands for this.
To see everything you have configured and, crucially, which context is currently active:
kubectl config get-contexts
The output will show an asterisk (*) next to the current context. This command is your best friend. Use it often.
To switch your current context (this changes current-context in the file):
kubectl config use-context prod-admin-context
Boom. Now all your kubectl get pods commands are hitting production. Scary, right? This is why you always, always check your current context before running any destructive command. I’m not kidding. I’ve seen entire production databases wiped because someone forgot to switch back from their local Minikube. The get-contexts command is your seatbelt.
To create a new context, stitching together existing clusters and users:
kubectl config set-context my-new-context --cluster=my-staging-cluster --user=staging-developer --namespace=test
The --context Flag: Your Safety Override
Sometimes you just need to run a quick command against another cluster without fully switching your current-context. This is where the --context flag is a lifesaver. It overrides the current context for that single command.
kubectl get pods --context=prod-admin-context -n important-app
This lets you query your production cluster from your terminal without changing your active context, which is probably still set to your less-dangerous staging cluster. It’s a fantastic practice for avoiding “oops” moments.
The KUBECONFIG Environment Variable: The Master Switch
Here’s a feature I love: you’re not limited to one file. The KUBECONFIG environment variable is a list of paths to kubeconfig files, separated by colons (or semicolons on Windows). kubectl will load and merge them all into one super-config.
export KUBECONFIG=~/.kube/config:~/.kube/config.d/prod-config:~/.kube/config.d/staging-config
Why is this brilliant?
- Compartmentalization: You can keep your work configs separate from your personal configs, or separate configs for different projects or clients.
- Security: You can keep sensitive production credentials in a separate file with stricter permissions.
- Tooling: Tools like
kubeloginoraws-iam-authenticatoroften manage their own config files. You can just pointKUBECONFIGat them without mangling your primary config.
To see the fully merged config that kubectl is actually using:
kubectl config view
The exec Credential Plugin: Where the Real Magic Happens
This is the modern way to handle auth, especially with cloud providers (EKS, GKE, AKS). Instead of storing long-lived, static credentials (like a token or cert) in your users section, you store a command for kubectl to execute to get a fresh, short-lived token.
This is what a users section looks like for Amazon EKS:
users:
- name: my-eks-cluster-user
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: aws
args:
- "--region"
- us-east-1
- "eks"
- "get-token"
- "--cluster-name"
- my-eks-cluster
env: null
This is infinitely more secure. Your kubeconfig no longer contains a secret; it contains instructions on how to get a secret using your local, already-authenticated AWS CLI. The tokens it generates are typically valid for only 15 minutes. GKE and AKS have similar mechanisms. If you’re not using this, you should be.