Skip to content

Connect to a Kubernetes cluster

View as Markdown

Connect to a TIR Kubernetes cluster by downloading its kubeconfig from TIR and giving it to kubectl. The kubeconfig points at the cluster’s API server, which has a public IP address and listens on port 6443. That means kubectl works straight from your own machine, over the internet.

  • A cluster in the Worker Joined or Ready state. The kubeconfig becomes available at Worker Joined.
  • kubectl on your own machine. See the Kubernetes install guide.
  • A role with the read permission on Kubernetes in the project, which is all you need to download the kubeconfig. See Roles and permissions.
  1. In TIR, open your project. In the side menu, under PRODUCTS, select Kubernetes.
  2. Select Download kubeconfig in one of two places:
    • In Manage Kubernetes Cluster, open the cluster’s Actions menu.
    • Select the cluster’s name to open its details page, and use the button at the top.

Your browser saves the file as the cluster’s name followed by -kubeconfig.yaml, with any character other than a letter, a digit, a dot, an underscore, or a hyphen turned into a hyphen.

The kubeconfig gives full administrative access to the cluster, so anyone who has the file controls the cluster. Keep it as you would a private key, out of repositories, tickets, and chat. The only way to retire a kubeconfig is to delete its cluster, so a leaked file means deleting the cluster and creating a new one.

On Linux and macOS, move the file somewhere predictable and make it readable only by you:

mkdir -p ~/.kube
mv ~/Downloads/<cluster-name>-kubeconfig.yaml ~/.kube/<cluster-name>.yaml
chmod 600 ~/.kube/<cluster-name>.yaml

Replace <cluster-name> with your cluster’s name. The commands that follow use the file at ~/.kube/<cluster-name>.yaml.

kubectl reads ~/.kube/config unless you tell it otherwise. The downloaded kubeconfig works like any other kubeconfig, with the --kubeconfig flag or the KUBECONFIG variable.

To run one command against the cluster, pass the file with the flag:

kubectl --kubeconfig ~/.kube/<cluster-name>.yaml get nodes

To leave out the flag, set KUBECONFIG for the terminal you are in. It lasts until you close the terminal, which makes it the safest choice while you are trying things out.

On macOS and Linux:

export KUBECONFIG=~/.kube/<cluster-name>.yaml
kubectl get nodes

In Windows PowerShell:

$env:KUBECONFIG = "$HOME\.kube\<cluster-name>.yaml"
kubectl get nodes

In the Windows Command Prompt:

set KUBECONFIG=%USERPROFILE%\.kube\<cluster-name>.yaml
kubectl get nodes

To keep the setting in every new terminal on macOS or Linux, add the line to your shell profile. Use ~/.zshrc for zsh, the macOS default, or ~/.bashrc for bash.

export KUBECONFIG=$HOME/.kube/<cluster-name>.yaml

Then reload the profile and check which cluster kubectl uses:

source ~/.zshrc # or: source ~/.bashrc
kubectl config current-context

On Windows, set it for your user account, so every new terminal picks it up:

[Environment]::SetEnvironmentVariable(
"KUBECONFIG",
"$HOME\.kube\<cluster-name>.yaml",
"User"
)

Open a new terminal and run kubectl config current-context to check it.

KUBECONFIG takes a list of files and kubectl merges them as it reads them, leaving the files on disk as they are. Separate the files with a colon on macOS and Linux, and with a semicolon on Windows. Here, <prod-cluster> and <dev-cluster> stand for the names of two clusters:

export KUBECONFIG=$HOME/.kube/<prod-cluster>.yaml:$HOME/.kube/<dev-cluster>.yaml
$env:KUBECONFIG = "$HOME\.kube\<prod-cluster>.yaml;$HOME\.kube\<dev-cluster>.yaml"

List the clusters, and switch to the one you want to work on:

kubectl config get-contexts
kubectl config use-context <context-name>

When two files have a context with the same name, the first file in the list wins. To keep both, rename one of the contexts before you merge:

kubectl config rename-context <old-name> <new-name>

To write the merged result into one file, back up ~/.kube/config first, because this command replaces it:

KUBECONFIG=$HOME/.kube/config:$HOME/.kube/<cluster-name>.yaml \
kubectl config view --flatten > ~/.kube/merged-config
mv ~/.kube/merged-config ~/.kube/config
chmod 600 ~/.kube/config

Check which file and cluster kubectl is using, and that the cluster answers:

echo $KUBECONFIG
kubectl config current-context
kubectl cluster-info
kubectl get nodes -o wide

The list includes the control plane nodes as well as the workers, and each node shows Ready once it has joined. Your own pods run on the workers only.

To check that cluster networking is healthy, list the system pods:

kubectl get pods -n kube-system

Cilium, the cluster’s network plugin, has a pod on every node. Each one shows Running when networking is healthy.

To check the cluster end to end, start a web server and reach it from your machine:

kubectl create deployment hello --image=nginx
kubectl expose deployment hello --port=80 --type=ClusterIP
kubectl get pods -w

Once the pod is Running, forward a local port to it, then open http://localhost:8080 in your browser:

kubectl port-forward deployment/hello 8080:80

The nginx welcome page opens. Press Ctrl+C to stop forwarding, and remove the app:

kubectl delete deployment hello
kubectl delete service hello

You can now run kubectl and Helm against the cluster from any terminal. To publish an app on a public address instead of forwarding a port, attach a reserved IP and expose services with a load balancer. If kubectl times out, reaches the wrong cluster, or reports a certificate error, see Troubleshooting TIR Kubernetes.