Guides / Container Orchestration

How to Install & Set Up Kubernetes

Install the kubectl CLI, understand the control-plane/node split, bootstrap a real cluster with kubeadm, and deploy your first workload.

Updated 20269-step setupDownload Kubernetes →

Prerequisites

  • ✓One or more Linux hosts (2 GB+ RAM, 2 vCPUs each) with swap disabled — one becomes the control-plane node, the rest are workers
  • ✓A container runtime installed (containerd or CRI-O) on every node — Kubernetes talks to it through the CRI (Container Runtime Interface), it no longer runs containers itself
  • ✓Unique hostnames, unique MAC addresses, and full network connectivity between every node

Control plane vs. nodes — what you're actually building

A cluster splits into two roles. The control plane is the brain: the API server (every kubectl command and every internal component talks through it), etcd (the cluster's entire state lives in this key-value store), the scheduler (decides which node a new pod lands on), and the controller manager (a set of reconciliation loops that keep reality matching what you declared).

Worker nodes are where your workloads actually run. Each one runs a kubelet (the agent that talks to the API server and starts/stops containers via the runtime), kube-proxy (programs the networking rules that make Services work), and the container runtime itself. kubeadm — the tool below — automates wiring all of this together on your own machines; kubectl is just the client you use to talk to the API server afterward.

If you don't want to run this yourself, k3s, k0s, and MicroK8s package the same control plane into a much lighter single binary — see their dedicated guides — and kind/Minikube spin up a throwaway cluster for local development only.

Install kubectl only (quick, distro-agnostic)

If you only need a client to talk to a cluster someone else runs (managed, or already bootstrapped), the plain binary is all you need — no repo, no package manager.

terminal
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

Install kubeadm, kubelet & kubectl together (for bootstrapping a real cluster)

To actually build a cluster you need kubeadm and kubelet too, not just kubectl — install all three together from Kubernetes' own package repository, on every node that will join the cluster.

Ubuntu/Debian (apt)
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
RHEL / CentOS Stream / Fedora (dnf)
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/repodata/repomd.xml.key
EOF
sudo dnf install -y kubelet kubeadm kubectl
sudo systemctl enable --now kubelet
!

Swap v1.31 in the URL for whichever minor version you're targeting — the repo is versioned per minor release, and apt-mark hold / a pinned dnf version stops an unattended upgrade from silently jumping your cluster to an incompatible version.

Bootstrap a control plane with kubeadm

terminal
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
!

kubeadm init prints a `kubeadm join ...` command with a token near the end of its output — copy it before it scrolls away, you'll need it for every worker.

Install a CNI plugin (required)

Kubernetes doesn't ship pod networking itself — without a CNI (Container Network Interface) plugin, nodes stay stuck in NotReady and pods can't get an IP at all. Flannel is the simplest option and matches the --pod-network-cidr used above.

terminal
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

Join worker nodes

Run the join command kubeadm init printed earlier, on each worker node, as root:

terminal
sudo kubeadm join CONTROL_PLANE_HOST:6443 \
  --token TOKEN \
  --discovery-token-ca-cert-hash sha256:HASH
lost the token? regenerate it from the control-plane node
kubeadm token create --print-join-command

Verify the installation

Every node should report Ready and every pod in the kube-system namespace should be Running before you deploy anything of your own.

terminal
kubectl get nodes
kubectl get pods -A

The object model, in one deployment

You almost never manage individual containers directly. A Deployment declares how many replicas of a Pod (one or more containers sharing network/storage) you want running and keeps that count true even as nodes fail; a Service gives that shifting set of pods a single stable IP and DNS name to be reached at.

deploy nginx and expose it
kubectl create deployment nginx --image=nginx:latest --replicas=2
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get deployments,pods,svc
watch it self-heal
kubectl delete pod -l app=nginx --field-selector=status.phase=Running --grace-period=0 | head -1
kubectl get pods -w
!

Real workloads live in YAML manifests applied with `kubectl apply -f` (so the config is versioned in Git), not typed imperatively like the create/expose commands above — those are just the fastest way to prove the cluster works.

Working across clusters with kubectl context

Your kubeconfig (~/.kube/config) can hold credentials for several clusters at once, and context is what tells kubectl which one — and which namespace — a command should hit.

terminal
kubectl config get-contexts
kubectl config use-context my-cluster
kubectl config set-context --current --namespace=my-team

Documentation & Knowledge Base

Official DocumentationKubernetes Documentation →Knowledge Base & CommunityKubernetes Community Forum →
Download Kubernetes— all versions & official links→

Related Guides

k3sInstall guide →Minikube / kindInstall guide →Argo CDInstall guide →

Need Kubernetes deployed and managed for you?

We're OpenStack Dev — we design, deploy, and operate production DevOps infrastructure.

Get in TouchAll Install Guides