Skip to main content
RunBook Academy

KubernetesVI · kubectl for Administratorskubectl for administrators

kubectl contexts, kubeconfig, and multi-cluster administration

Intermediate⏱ ~18 minkubectl

What you'll learn

  • Read and write a kubeconfig with confidence
  • Distinguish clusters, users, and contexts and explain how they compose
  • Use KUBECONFIG, --context, --cluster, --user to disambiguate between clusters
  • Apply production discipline around destructive operations on multiple clusters

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

kubectl is a stateless REST client. The only thing that decides which cluster, identity, and namespace a command targets is the kubeconfig loaded at startup. Multi-cluster administration is the discipline of making that selection explicit, never implicit, because every destructive kubectl command inherits its target from the kubeconfig and there is no second chance.

The kubeconfig shape

The kubeconfig is a YAML file (default $HOME/.kube/config) with three top-level lists and one pointer:

apiVersion: v1
kind: Config
current-context: prod-eu-west-1
clusters:
- name: prod-eu-west-1
  cluster:
    server: https://api.prod.example.com:6443
    certificate-authority-data: <base64>
- name: staging-eu-west-1
  cluster:
    server: https://api.staging.example.com:6443
    certificate-authority-data: <base64>
users:
- name: admin-prod
  user:
    client-certificate-data: <base64>
    client-key-data: <base64>
- name: admin-staging
  user:
    token: <bearer-token>
contexts:
- name: prod-eu-west-1
  context:
    cluster: prod-eu-west-1
    user: admin-prod
    namespace: team-a-prod
- name: staging-eu-west-1
  context:
    cluster: staging-eu-west-1
    user: admin-staging
    namespace: team-a-staging
preferences: {}
flowchart LR
    Context[Context: prod-eu] --> Cluster[Cluster: api.prod.example.com:6443]
    Context --> User[User: admin-prod]
    Context --> Namespace["Namespace: team-a-prod"]
    User --> Creds[Client cert / token]
    Cluster --> CA[CA bundle]

The three lists work together:

  • clusters — named API server endpoints, each with a server URL and a CA bundle to verify the server’s certificate.
  • users — named credentials: client certificate, bearer token, OIDC config, or exec plugin.
  • contexts — triples that bind a cluster, a user, and an optional default namespace. A context is a named pointer; it stores no data of its own.

current-context is the name of the context kubectl uses when no --context, --cluster, or --user flag is supplied.

How kubectl resolves a command

For every command, kubectl answers three questions in order:

  1. Which cluster? — taken from current-context’s cluster, unless --cluster overrides it.
  2. Which identity? — taken from current-context’s user, unless --user overrides it.
  3. Which namespace? — taken from --namespace (-n); if absent, falls back to the context’s namespace; if the context has no namespace, falls back to default.

If you pass only --cluster, kubectl leaves the user and namespace untouched (it picks them from the current-context). If you pass only --user, kubectl picks the cluster and namespace from the current-context. If you pass --context, all three come from that context.

flowchart LR
    A[kubectl get pods -n team-a-prod] --> B{--context?}
    B -- yes --> C[Use that context's cluster/user/ns]
    B -- no --> D[Use current-context]
    D --> E{--cluster / --user / -n?}
    E -- yes --> F[Override the matching field]
    E -- no --> G[Use current-context values]

The flags are deliberately orthogonal. They let you compose “the user from staging” with “the cluster from prod” for a one-off cross-cluster operation — usually a mistake, but the API allows it.

Reading and editing kubeconfig

The most useful commands for day-to-day context management:

kubectl config view                              # merged config (sanitized)
kubectl config view --raw                        # with credentials shown
kubectl config view --minify                     # only current-context's entries
kubectl config get-contexts                      # list all contexts
kubectl config current-context                   # print current-context name
kubectl config use-context prod-eu-west-1        # switch
kubectl config set-context --current --namespace=team-a-prod
kubectl config set-credentials alice --token=...
kubectl config set-cluster new-cluster --server=https://...
kubectl config delete-context old-cluster
kubectl config rename-context old=new

Every kubectl config subcommand edits the kubeconfig file in place. The file is reread on every kubectl invocation, so edits take effect immediately. There is no daemon and no cache to invalidate.

Merging multiple kubeconfigs

A common production pattern: separate kubeconfigs for separate clusters (one for prod, one for staging, one for the on-prem test cluster), merged at runtime through the KUBECONFIG environment variable:

KUBECONFIG=~/.kube/config:~/.kube/prod:~/.kube/staging kubectl config view

When the variable lists multiple files, kubectl merges them left-to-right. For each entry (cluster, user, context), the first occurrence wins. New entries can be added to any file; conflicts are resolved by position.

A practical workflow:

# Start with the base kubeconfig (e.g., the cluster you mostly use)
export KUBECONFIG=~/.kube/config

# Pull another cluster's kubeconfig (e.g., from a managed service)
KUBECONFIG=~/.kube/config:./downloaded-config.yaml kubectl config view --flatten > ~/.kube/all.yaml

# Use the merged config
export KUBECONFIG=~/.kube/all.yaml
kubectl config get-contexts

--flatten rewrites embedded certificate data as file paths under the chosen kubeconfig, so the merged file is portable.

Multi-cluster discipline

A kubectl command with no --context flag inherits the target from current-context. On an engineer who runs multiple clusters from one workstation, that target is whatever they last ran kubectl config use-context to set — or whatever shell prompt they had open.

Three patterns make this safer in production:

  1. Set the namespace on every context. Every context in the kubeconfig should carry a namespace: field. The discipline: “this operator’s namespace is X for cluster Y.” Production operators should never operate in default.
  2. Verify the context before every destructive command. kubectl config view --minify | grep -E "current-context|namespace" before any delete, scale, patch, or apply of a manifest that already exists in another cluster.
  3. Use shell prompts that show the context. A shell prompt that embeds kubectl config current-context (e.g., [prod-eu-west-1:team-a-prod] $) makes the target visible at all times. The kubectx/kubens tools are common implementations.

How to inspect a remote cluster without changing context

Two flags make ad-hoc, one-off operations explicit:

kubectl --context prod-eu-west-1 get nodes
kubectl --context staging-eu-west-1 -n kube-system get pods

The --context flag overrides everything in the current-context selection. This is the right way to do “let me look at staging real quick” without changing the kubeconfig. For deeper multi-cluster work, run a separate shell with a different KUBECONFIG value:

KUBECONFIG=~/.kube/staging kubectl get nodes

Cross-course references

  • The Linux course part XXVI-Linux-SSH covers credential management primitives (ssh-agent, ~/.ssh/config) that map onto kubeconfig structure: clusters are endpoints, users are credentials, contexts are ssh host aliases.
  • The Docker course part XXIX-Docker-Build covers registry logins; kubeconfigs and ~/.docker/config.json follow the same “named endpoint + named credentials + named context” pattern.
  • The Observability course part LXIX-Observability-LongTermStorage discusses multi-cluster metric federation; that pattern uses the same kubectl-driven context discipline for inspecting remote clusters.

Quiz

Knowledge check · 4 questions

  1. Q1. A kubeconfig context is a triple. Which three fields does it contain?

  2. Q2. `kubectl config use-context prod` only affects the current terminal session; other terminals on the same workstation keep their previous context.

  3. Q3. An on-call engineer has current-context set to staging-eu-west-1. They run `kubectl delete deployment web -n team-a-prod` thinking they are targeting prod-eu-west-1. Diagnose what happened, what is the impact, and how to recover.

    Engineer's kubeconfig: ```yaml current-context: staging-eu-west-1 clusters: - name: prod-eu-west-1 - name: staging-eu-west-1 contexts: - name: staging-eu-west-1 context: {cluster: staging-eu-west-1, user: admin-staging, namespace: team-a-staging} - name: prod-eu-west-1 context: {cluster: prod-eu-west-1, user: admin-prod, namespace: team-a-prod} ``` Commands run: ```bash kubectl delete deployment web -n team-a-prod # deletes the Deployment in staging (the current-context's cluster) # the -n team-a-prod namespace is interpreted in staging; if that namespace # exists in staging, the Deployment is deleted there too ``` Engineer's intent: delete the production Deployment named `web` in the production cluster's team-a-prod namespace.

  4. Q4. How does kubectl decide which kubeconfig file to read, and what does the `KUBECONFIG` environment variable do when it lists multiple files?

Passing score: 75%. Answers are checked in this browser.

Production discipline

  • One kubeconfig file per cluster, merged at runtime. Keeps credentials scoped to the cluster they belong to and lets you revoke a cluster’s kubeconfig without touching the others.
  • Set namespace: on every context. Operators should never inherit default. The context’s namespace is the operator’s default; -n is for one-off overrides.
  • Verify current-context before destructive operations. kubectl config view --minify | grep -E "current-context|namespace" or embed the context/namespace in the shell prompt.
  • Prefer --context per command over use-context for ad-hoc work. A switch to current-context leaks into every other terminal that reads the same file.
  • Restrict file permissions. chmod 600 on every kubeconfig file; chmod 700 on ~/.kube. The file contains cluster-admin credentials and is read by every kubectl invocation.