Skip to content

Infrastructure tools · guide

Kubernetes, the basics

7 min read · Last checked 10 October 2026

This page explains the Kubernetes words the course’s lessons use. Read the containers and Docker guide first if “container” or “image” is new to you. One OpenZiti word comes up throughout: a tunneler is the OpenZiti program on a device that connects that device’s apps to the network.

Docker runs containers on one computer. If that computer stops, nothing starts its containers on another machine.

Kubernetes is software that runs containers across a group of machines and keeps them running. If a container stops, Kubernetes starts another.

That group of machines is a cluster. The control plane keeps the record of everything in the cluster and decides which machine runs what. The nodes are the machines that run the containers.

A node is one machine in the cluster, physical or virtual. A cluster usually has several, but a learning setup may have only one. In Module 9, the course’s cluster in Azure, Microsoft’s cloud, has one node on purpose (see volume claims, below). Module 10 adds a second node pool, a group of nodes of the same size, for its monitoring tools.

A pod is the smallest thing Kubernetes runs: one or more containers that share a network and storage, always on one node. In Module 9, the dispatch pod holds two containers: the app, and a tunneler beside it that carries the app’s traffic.

Pods are disposable: Kubernetes creates and replaces them for you.

A deployment keeps a set of pods running for one app. When you change what it should run, such as the image, Kubernetes replaces its pods step by step. That is a rollout.

A DaemonSet runs one copy of a pod on every node, or on the nodes you choose. A node that joins the cluster gets a copy.

Module 9 runs two kinds of tunneler in the cluster:

  • The hosting tunneler (ziti-host) makes an app inside the cluster reachable over OpenZiti. It runs as a deployment.
  • The node proxy (ziti-edge-tunnel) lets the pods on a node reach OpenZiti services without a tunneler of their own. It runs as a DaemonSet, one copy per node.

Kubernetes keeps each thing you create, such as a pod, as an object. A namespace is a named group of objects inside one cluster. Two objects can share a name in different namespaces, but not inside the same one.

The course uses four: wms, dispatch, ziti and telemetry. Most commands take -n <namespace> to say which one you mean.

Every pod gets its own network address, but pods come and go, so an app’s address keeps changing. A service is a fixed name and address in front of a set of pods. Other pods talk to the service, which passes the traffic to whichever pods are running.

Kubernetes gives each service a name in the cluster’s DNS, the system that turns a name into a network address. The full name has the form <service>.<namespace>.svc.cluster.local. A pod in the same namespace can use the short name alone.

A pod is disposable, so files kept only inside it can be lost. A persistent volume is storage whose life doesn’t depend on any pod. A persistent volume claim is a request for that storage. The cluster creates a volume to match, using a storage class, a kind of storage it offers. One class can be the default. Until a claim has storage, its status is Pending, and a pod that needs it waits.

This is where a tunneler keeps its identity file (the machine’s OpenZiti credentials). Enrollment is the one-time step where a tunneler uses a token to get that file. In Module 9, the hosting tunneler keeps it in a claim named wms-ziti-host-identity-pvc.

To mount storage is to connect it to a node so programs there can read and write it. A claim’s access mode says how it can be mounted. The node proxy’s claim is ReadWriteOnce: only one node at a time can mount it for reading and writing. The DaemonSet puts a node proxy on every node, and every copy uses that one claim. A copy on a second node couldn’t mount it. That’s why the Module 9 cluster has one node.

Deleting a claim usually deletes its volume and data too, so it removes the identity file, as docker compose down -v does in Docker.

What runs where in a clusterA cluster with two nodes. The control plane decides which node runs what. Each node runs an app pod from a deployment and a node proxy from a DaemonSet, one copy per node. A service is a fixed name in front of the app pods. The node proxy’s volume claim holds the identity file and is ReadWriteOnce: node 1 mounts it, and a second node can’t. CLUSTERCONTROL PLANEdecides which node runs whatSERVICEfixed name in front of podsNODE 1NODE 2NODE PROXYDaemonSetAPP PODdeploymentAPP PODdeploymentNODE PROXYDaemonSetVOLUME CLAIMholds the identity filenode 1 mounts itReadWriteOnce: asecond node can’t
A two-node cluster: a node proxy on every node, a service in front of the app's pods, and a ReadWriteOnce claim that only one node can mount.

An app often needs several objects at once. Helm is the package manager for Kubernetes: a tool that installs, upgrades and removes packaged apps. A chart is a Helm package: the files that describe all of an app’s objects. A values file holds your settings for that chart, written in YAML, plain text in which indenting shows structure.

Installing a chart creates a release: one installed copy of the chart in a cluster, under a name you choose. Charts are published in repositories. The course adds OpenZiti’s chart repository, then installs the ziti-host and ziti-edge-tunnel charts with its own values files.

With managed Kubernetes, a cloud provider runs the control plane for you. In AKS (Azure Kubernetes Service), Azure runs the control plane at no cost on the Free tier, which the course uses, and you pay for the nodes. Module 9’s cluster costs about $2 a day; remove it between sessions.

k3d creates a local cluster inside Docker containers on your own computer. It runs K3s, a small Kubernetes distribution: a packaged edition of Kubernetes. The course’s k3d cluster, meridian-yard-edge, stands in for a K3s cluster at a remote site, for free.

kubectl is a command-line tool, a program you use by typing commands, that talks to a cluster’s control plane. It reads its settings from a kubeconfig file, by default the file config in the .kube folder of your home folder.

A context is a named entry in that file. It pairs a cluster with the account that signs in to it, and optionally a namespace. kubectl sends each command to the current context unless you name another with --context.

KUBECONFIG is a setting in your terminal that points kubectl at one or more kubeconfig files. On Windows, you separate them with ;, and kubectl merges them. The course sets it in every new PowerShell window, so one window sees both clusters: aks-meridian-lab-eus-01 and k3d-meridian-yard-edge.

When k3d creates a cluster, it adds the context to your default kubeconfig and switches to it. Before you run a command, check which cluster it will reach.

Which cluster a kubectl command reacheskubectl on your computer reads the kubeconfig file, which lists the contexts. kubectl sends each command to the current context, here the AKS cluster aks-meridian-lab-eus-01 in Azure, unless you name another with --context, such as the k3d cluster k3d-meridian-yard-edge, which runs inside Docker on your computer. KUBECTLon your computerKUBECONFIGlists the contextsreadsAKS CLUSTERaks-meridian-lab-eus-01in AzureK3D CLUSTERk3d-meridian-yard-edgeinside Docker, on your computerthe current contextgets each commandor name anotherwith --context
kubectl reads the kubeconfig file and sends each command to the current context, unless you name another with --context.
Command What it does
kubectl config get-contexts Lists the contexts kubectl knows and marks the current one.
kubectl config use-context <context> Makes that cluster the one later commands go to.
kubectl get pods -n <namespace> Lists the pods in a namespace and whether they’re running.
kubectl apply -f <file>.yaml Creates or updates the objects described in a manifest: a YAML file from the course’s labs repo that describes Kubernetes objects.
kubectl rollout status deployment/<name> -n <namespace> Waits until a deployment’s new pods are running, then reports it.
kubectl logs <pod> -n <namespace> --tail=50 Shows the last 50 lines a pod printed.
kubectl exec <pod> -c <container> -n <namespace> -- <command> Runs one command inside one container of a pod. Everything after -- is the command to run inside the container.
kubectl describe pod <pod> -n <namespace> Shows a pod’s details and its events: a list of what happened to the pod, such as pulling the image or failing to start.
helm repo add <name> <url> Adds a chart repository so Helm can find its charts.
helm install <release> <chart> -n <namespace> -f values.yaml Installs a chart as a named release, with your settings from a values file. When a lab also passes a file with --set-file, write that path with forward slashes (./x.jwt): Helm drops a backslash there.
helm uninstall <release> -n <namespace> Removes a release and everything it created, including its volume claim and the identity file stored in it.
k3d cluster create <name> Creates a local cluster inside Docker; k3d cluster delete <name> removes it.

Sources

Facts on this page are explained in our own words. Short quotes are marked and linked.