Introduction
Kubernetes has become the de facto standard for container orchestration, and its integration with Linux offers a robust and scalable platform for modern workloads. In this article we will explore step by step how to deploy a Kubernetes cluster on a Linux server, from system preparation to the deployment of your first application.
Previous requirements
Before you start, 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. In addition, it is essential to have access to a user with sudo privileges and a stable Internet connection to download the necessary packages.
Installation of Kubernetes tools
The basic components arekubeadm, kubeletandkubectl. In Debian / Ubuntu-based distributions you can add them through 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 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 as hold to avoid automatic updates:
sudo apt-mark hold kubelet kubeadm kubectl
Initialization of the master node
With the tools installed, initialize the control plane with kubeadm. Choose a range of addresses for the pods network (e.g. 10.244.0.0 / 16) and run:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
After completion, copy the settings for your user:
mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config
Installation of a pod network (CNI)
Kubernetes needs a network plugin for the containers to communicate. A popular option is Flannel:
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
Check that all nodes are ready withkubectl get nodes.
Unite nodes workers to cluster
In each worker machine, it runs the binding command that kubeadm init showed in the end, something like:
sudo kubeadm join
After joining, check from the master:kubectl get nodesI should show all the nodes in Ready state.
Deployment of an example application
To validate the cluster, we will deploy a simple web server using NGINX:
- Create a deployment:
kubectl create deployment nginx --image=nginx - Expose the deployment as service:
kubectl expose deployment nginx --port=80 --type=NodePort - Get the assigned port:
kubectl get svc nginx - Access through
http://in your browser.:
Scaling and updates
Kubernetes allows to scale applications with a single command:
kubectl scale deployment nginx --replicas=5
To update the image, for example to a specific version of NGINX:
kubectl set image deployment/nginx nginx=nginx:1.25
The control plane will perform a rolling update, ensuring that replicas are always available.
Good practices and troubleshooting
- Keep the operating system up to date and apply safety patches regularly.
- It uses descriptive node names and labels to organize workloads.
- Monitoring resource use with
kubectl top nodesandkubectl top pods. - Check the kubelet and container log with
journalctl -u kubeletandkubectl logs. - If a node does not join, check the connectivity of port 6443 and the validity of the token.
Persistent storage with Volume
For state-required applications, Kubernetes offers Persistent Volume and Persistent Volume Claims. In a local Linux environment you can use the hostPath driver for tests:
- 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 uses 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 PVC:
kubectl apply -f pvc-hostpath.yaml
Then you can mount the claim in a pod:
cat <
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
Unfolding Kubernetes in Linux is an accessible process that provides great flexibility to manage containers on a scale. Following the steps described, you will have a functional cluster ready for development, testing or production workloads. Continue to explore the Helm ecosystem, Operators and service meshes to further enhance your infrastructure.


