Introduction
Kubernetes has become the de facto standard for container orchestration, and its integration with Linux provides a robust and scalable platform for modern workloads. In this article we will walk through step‑by‑step how to deploy a Kubernetes cluster on a Linux server, from system preparation to deploying your first application.
Prerequisites
Before you begin, you need a recent Linux distribution (Ubuntu 22.04 LTS, CentOS Stream 9, or Rocky Linux 9) with at least 2 GB of RAM and 2 CPUs per node. Additionally, you must have access to a sudo‑enabled user account and a stable internet connection to download the required packages.
Installing Kubernetes Tools
The core components are kubeadm, kubelet, and kubectl. On Debian/Ubuntu‑based distributions you can add them via the official Kubernetes repository:
- Update the package index:
sudo apt-get update - Install dependencies:
sudo apt-get install -y apt-transport-https ca-certificates curl - Add the GPG key:
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg - Add the repository:
echo 'deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main' | sudo tee /etc/apt/sources.list.d/kubernetes.list - Install the binaries:
sudo apt-get updatefollowed bysudo apt-get install -y kubelet kubeadm kubectl - Mark them on hold to prevent automatic upgrades:
sudo apt-mark hold kubelet kubeadm kubectl
Initializing the Master Node
With the tools installed, initialize the control plane using kubeadm. Choose a pod network CIDR (for example, 10.244.0.0/16) and run:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
After completion, copy the configuration for your user:
mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config
Installing a Pod Network (CNI)
Kubernetes requires a network plugin for pod communication. A popular choice is Flannel:
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
Verify that all nodes are ready with kubectl get nodes.
Joining Worker Nodes to the Cluster
On each worker machine, run the join command that kubeadm init displayed at the end, something like:
sudo kubeadm join :6443 --token --discovery-token-ca-cert-hash sha256:
After joining, verify from the master: kubectl get nodes should show all nodes in the Ready state.
Deploying a Sample Application
To validate the cluster, we’ll deploy a simple web server using NGINX:
- Create a deployment:
kubectl create deployment nginx --image=nginx - Expose the deployment as a service:
kubectl expose deployment nginx --port=80 --type=NodePort - Get the assigned port:
kubectl get svc nginx - Access via
http://:in your browser.
Scaling and Updates
Kubernetes lets you scale applications with a single command:
kubectl scale deployment nginx --replicas=5
To update the image, for example to a specific NGINX version:
kubectl set image deployment/nginx nginx=nginx:1.25
The control plane will perform a rolling update, ensuring that replicas remain available.
Best Practices and Troubleshooting
- Keep the operating system up to date and apply security patches regularly.
- Use descriptive node names and labels to organize workloads.
- Monitor resource usage with
kubectl top nodesandkubectl top pods. - Check the logs of kubelet and containers with
journalctl -u kubeletandkubectl logs. - If a node fails to join, verify connectivity to port 6443 and the validity of the token.
Persistent Storage with Volumes
For stateful applications, Kubernetes offers PersistentVolumes and PersistentVolumeClaims. In a local Linux environment you can use the hostPath driver for testing:
- Create a PV:
cat < pv-hostpath.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /mnt/data
EOF
- Apply it:
kubectl apply -f pv-hostpath.yaml - Create a PVC that consumes it:
cat < pvc-hostpath.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pvc-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
EOF
- Apply the PVC:
kubectl apply -f pvc-hostpath.yaml
You can then mount the claim in a pod:
cat < pod-with-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: task-pod
spec:
volumes:
- name: task-storage
persistentVolumeClaim:
claimName: task-pvc-claim
containers:
- name: task-container
image: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: task-storage
EOF
kubectl apply -f pod-with-volume.yaml
Conclusion
Deploying Kubernetes on Linux is an accessible process that provides great flexibility for managing containers at scale. By following the steps outlined, you will have a functional cluster ready for development, testing, or production workloads. Continue exploring the Helm ecosystem, Operators, and service meshes to further enhance your infrastructure.