Kubernetes explainer
kubeconfig Explained: Clusters, Users and Contexts
A kubeconfig file tells kubectl which cluster to call, which credentials to present, and which namespace to default to. It is plain YAML, and most of the confusion around it comes from three facts: it has three separate lists that point at each other, it can be merged from several files, and the active entry is a single pointer called the current context.
By Muhammad Soliman, Founder at SeaGit
·
Key takeaways
- A kubeconfig has three lists: clusters (where), users (who), and contexts (a named pair of one cluster and one user, plus an optional namespace).
- current-context selects the context kubectl uses. kubectl config use-context changes it.
- If KUBECONFIG is set, kubectl merges the listed files, and the first file to set a value wins. Otherwise it reads ~/.kube/config.
- aws eks update-kubeconfig adds a context for an EKS cluster. Its user entry runs aws eks get-token, so the token comes from your current AWS credentials.
The three lists: clusters, users and contexts
The default file is $HOME/.kube/config. Its top level has clusters, users and contexts, plus current-context. A cluster entry holds the API server address and the certificate authority. A user entry holds a client certificate, a token, or an exec plugin that produces a token. A context names one cluster and one user, and can set a default namespace.
apiVersion: v1
kind: Config
current-context: staging
clusters:
- name: prod-cluster
cluster:
server: https://ABCDEF.gr7.us-east-1.eks.amazonaws.com
certificate-authority-data: <base64 CA>
- name: staging-cluster
cluster:
server: https://1234AB.gr7.us-east-1.eks.amazonaws.com
certificate-authority-data: <base64 CA>
users:
- name: alice
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: aws
args: [eks, get-token, --cluster-name, staging-cluster, --region, us-east-1]
contexts:
- name: staging
context:
cluster: staging-cluster
user: alice
namespace: my-appBecause the three lists are separate, a context can point at a cluster that is missing or a user that is misspelt. kubectl reports that as a configuration error rather than a connection error, which is why the fix is in the file and not on the network.
Treat the file as a credential store. A user entry can hold a client key or a bearer token, so the file should be readable only by you, and it should never be committed to a repository or pasted into a ticket. Share the cluster endpoint and the context name instead, which are not secret.
Merging files with the KUBECONFIG variable
KUBECONFIG holds a list of files. On Linux and macOS the separator is a colon, and on Windows it is a semicolon. kubectl merges the files in order. The rules are simple, and they matter when two files define the same cluster or user name.
- Empty filenames are ignored.
- The first file to set a particular value or map key wins. Later files cannot overwrite it.
- current-context is taken from the first file that sets it.
- If a second file defines a user with the same name, only the first file user is used. The rest of the second entry is discarded.
- The --kubeconfig flag uses only the file you name, with no merge. It can be given once.
# Use two files at once, and view the merged result
export KUBECONFIG=~/.kube/config:~/.kube/eks-extra.yaml
kubectl config view
# Show the merged view without secrets printed in clear text
kubectl config view --minify
# Use one file only, for a single command
kubectl --kubeconfig=~/.kube/ci.yaml get nodesKeep the merge predictable
Put the file you trust most first. A stale entry in an earlier file can shadow a fresh one with the same name, so the context you expect points at the old cluster. When the answer is unclear, run kubectl config view and read the merged result rather than the individual files.
One file per environment
Many teams keep one kubeconfig file per account or per environment, such as ~/.kube/prod.yaml and ~/.kube/staging.yaml, and set KUBECONFIG per terminal session. The benefit is that a production file is only loaded when you ask for it. A tool that writes to the default file, like aws eks update-kubeconfig, writes to the first entry in KUBECONFIG, so set the variable before you run it.
The kubectl config commands you actually use
You rarely need to edit the YAML by hand. The kubectl config subcommands change the file in the right place and keep the lists consistent.
# Which context is active right now
kubectl config current-context
# Every context, with the active one marked
kubectl config get-contexts
# Switch the active context
kubectl config use-context staging
# Set a default namespace for the current context
kubectl config set-context --current --namespace=my-app
# Show only the active context and its cluster and user
kubectl config view --minifyA common mistake is to run a destructive command while the wrong context is active. Check current-context in the same shell before you delete or patch anything, and consider a shell prompt that shows the context.
Connecting to an EKS cluster with aws eks update-kubeconfig
For an Amazon EKS cluster, you do not write the kubeconfig by hand. The AWS CLI asks EKS for the cluster endpoint and CA data, then writes a context to your file. The user entry it creates calls aws eks get-token, so the credentials are your current AWS identity, not a static secret in the file.
# Add or update the context for one cluster
aws eks update-kubeconfig --region us-east-1 --name staging-cluster
# Confirm the connection
kubectl config current-context
kubectl get nodesThe command writes to the first file in KUBECONFIG, or to ~/.kube/config if the variable is not set. If you keep a separate file per account, set KUBECONFIG before you run it, so the context lands in the right place.
Access is a second step. The IAM principal in your AWS credentials must also be authorised inside the cluster, through EKS access entries or the older aws-auth ConfigMap. A valid kubeconfig with an unauthorised identity gets an Unauthorized error from the API server.
Troubleshooting: the errors and what they mean
Most kubeconfig problems show up as one of four messages. Each one points at a different layer, so read the message before you change anything.
- error: current-context is not set. The file has no current-context, or it names a context that does not exist. Run kubectl config use-context with a name from get-contexts.
- The connection to the server localhost:8080 was refused. kubectl found no usable cluster entry and fell back to the default. The file was not read, or KUBECONFIG points at the wrong file.
- Unable to connect to the server: dial tcp ... i/o timeout. The server address is wrong or the network blocks it. Check the cluster endpoint and your VPC or VPN path.
- error: You must be logged in to the server (Unauthorized). The credentials were rejected. For EKS, the token has expired or the IAM principal has no access entry. Refresh your AWS session and check the cluster access entries.
Quick checks in order
kubectl config view --minify # is the active context what you expect?
echo "$KUBECONFIG" # which files are merged?
aws sts get-caller-identity # which AWS identity will get-token use?
aws eks describe-cluster --region us-east-1 --name staging-cluster \
--query cluster.endpoint --output text # does the endpoint match the server field?