How to install Kubernetes on Linux
How to Install Kubernetes on Linux: A Complete Step-by-Step Guide
Introduction
Kubernetes has revolutionized container orchestration, becoming the de facto standard for managing containerized applications at scale. Whether you're a DevOps engineer, system administrator, or developer looking to deploy applications in a cloud-native environment, understanding how to install and configure Kubernetes on Linux is an essential skill.
This comprehensive guide will walk you through the entire process of installing Kubernetes on various Linux distributions, including Ubuntu, CentOS, and Red Hat Enterprise Linux (RHEL). You'll learn how to set up a complete Kubernetes cluster from scratch, configure networking, and troubleshoot common installation issues.
By the end of this tutorial, you'll have a fully functional Kubernetes cluster running on Linux, ready to deploy and manage containerized applications. We'll cover both single-node and multi-node cluster configurations, providing you with the flexibility to choose the setup that best fits your needs.
Prerequisites and System Requirements
Before diving into the Kubernetes installation process, ensure your system meets the following requirements:
Hardware Requirements
- Minimum RAM: 2GB per node (4GB recommended for master nodes)
- CPU: 2 cores minimum per node
- Storage: 20GB free disk space minimum
- Network: Reliable internet connection for downloading packages
Software Requirements
- Operating System: Linux distribution (Ubuntu 18.04+, CentOS 7+, RHEL 7+)
- Container Runtime: Docker 20.10+ or containerd
- Network Configuration: Unique hostname, MAC address, and product_uuid for each node
- Swap: Disabled on all nodes
- Firewall: Configured to allow Kubernetes traffic
Network Port Requirements
Ensure the following ports are open:
Master Node Ports:
- 6443: Kubernetes API server
- 2379-2380: etcd server client API
- 10250: Kubelet API
- 10259: kube-scheduler
- 10257: kube-controller-manager
Worker Node Ports:
- 10250: Kubelet API
- 30000-32767: NodePort Services
Step 1: Preparing the Linux System
Updating the System
First, update your Linux system to ensure all packages are current:
For Ubuntu/Debian:
```bash
sudo apt update && sudo apt upgrade -y
```
For CentOS/RHEL:
```bash
sudo yum update -y
For CentOS 8+ or RHEL 8+
sudo dnf update -y
```
Disabling Swap
Kubernetes requires swap to be disabled for optimal performance:
```bash
Disable swap temporarily
sudo swapoff -a
Disable swap permanently by commenting out swap entries
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
Verify swap is disabled
free -h
```
Setting Up Hostnames and Network Configuration
Configure unique hostnames for each node:
```bash
Set hostname (replace with your desired hostname)
sudo hostnamectl set-hostname k8s-master
For worker nodes: k8s-worker1, k8s-worker2, etc.
Update /etc/hosts file
sudo vim /etc/hosts
```
Add entries for all cluster nodes:
```
192.168.1.100 k8s-master
192.168.1.101 k8s-worker1
192.168.1.102 k8s-worker2
```
Configuring Firewall Rules
For Ubuntu (using ufw):
```bash
Master node
sudo ufw allow 6443/tcp
sudo ufw allow 2379:2380/tcp
sudo ufw allow 10250/tcp
sudo ufw allow 10259/tcp
sudo ufw allow 10257/tcp
Worker nodes
sudo ufw allow 10250/tcp
sudo ufw allow 30000:32767/tcp
```
For CentOS/RHEL (using firewalld):
```bash
Master node
sudo firewall-cmd --permanent --add-port=6443/tcp
sudo firewall-cmd --permanent --add-port=2379-2380/tcp
sudo firewall-cmd --permanent --add-port=10250/tcp
sudo firewall-cmd --permanent --add-port=10259/tcp
sudo firewall-cmd --permanent --add-port=10257/tcp
sudo firewall-cmd --reload
Worker nodes
sudo firewall-cmd --permanent --add-port=10250/tcp
sudo firewall-cmd --permanent --add-port=30000-32767/tcp
sudo firewall-cmd --reload
```
Step 2: Installing Container Runtime (Docker)
Kubernetes requires a container runtime. We'll install Docker as it's the most commonly used option:
Installing Docker on Ubuntu
```bash
Remove old Docker versions
sudo apt-get remove docker docker-engine docker.io containerd runc
Install dependencies
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Set up the stable repository
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install Docker Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
Start and enable Docker
sudo systemctl start docker
sudo systemctl enable docker
Add user to docker group
sudo usermod -aG docker $USER
```
Installing Docker on CentOS/RHEL
```bash
Remove old Docker versions
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
Install required packages
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
Add Docker repository
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
Install Docker
sudo yum install docker-ce docker-ce-cli containerd.io
Start and enable Docker
sudo systemctl start docker
sudo systemctl enable docker
Add user to docker group
sudo usermod -aG docker $USER
```
Configuring Docker for Kubernetes
Create the Docker daemon configuration file:
```bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <For Ubuntu:
```bash
Add Kubernetes signing key
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
Add Kubernetes repository
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
Update package index
sudo apt-get update
```
For CentOS/RHEL:
```bash
Create Kubernetes repository file
sudo tee /etc/yum.repos.d/kubernetes.repo <For Ubuntu:
```bash
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
```
For CentOS/RHEL:
```bash
sudo yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
```
Starting and Enabling Kubelet
```bash
sudo systemctl enable kubelet
sudo systemctl start kubelet
```
Step 4: Initializing the Kubernetes Cluster
Initializing the Master Node
Run the following command on the master node to initialize the cluster:
```bash
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=
```
Replace `` with your master node's IP address. The initialization process will take several minutes and will output important information, including the join command for worker nodes.
Sample output:
```
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
```
Configuring kubectl for Regular User
```bash
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
```
Verifying Cluster Status
```bash
kubectl get nodes
kubectl get pods --all-namespaces
```
Step 5: Installing Pod Network Add-on
Kubernetes requires a pod network add-on for pod-to-pod communication. We'll install Flannel:
```bash
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
```
Wait for all pods to be in the Running state:
```bash
kubectl get pods --all-namespaces
```
Step 6: Joining Worker Nodes to the Cluster
On each worker node, run the join command provided during cluster initialization:
```bash
sudo kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
```
If you've lost the join command, generate a new token on the master node:
```bash
kubeadm token create --print-join-command
```
Verifying Node Addition
From the master node, verify that worker nodes have joined:
```bash
kubectl get nodes
```
All nodes should show a "Ready" status.
Practical Examples and Use Cases
Example 1: Deploying a Simple Application
Create a simple nginx deployment:
```bash
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get services
```
Example 2: Scaling Applications
Scale the nginx deployment:
```bash
kubectl scale deployment nginx --replicas=3
kubectl get pods
```
Example 3: Creating a Multi-Container Pod
Create a YAML file for a multi-container pod:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
- name: busybox
image: busybox
command: ['sh', '-c', 'while true; do sleep 3600; done']
```
Apply the configuration:
```bash
kubectl apply -f multi-container-pod.yaml
```
Common Issues and Troubleshooting
Issue 1: Pods Stuck in Pending State
Symptoms: Pods remain in "Pending" status indefinitely.
Causes and Solutions:
- Insufficient resources: Check node resources with `kubectl describe nodes`
- Pod network issues: Verify network add-on installation
- Node taints: Remove taints if necessary: `kubectl taint nodes --all node-role.kubernetes.io/master-`
Issue 2: kubeadm init Fails
Common errors and solutions:
Error: "Port 6443 is already in use"
```bash
sudo netstat -tulpn | grep 6443
sudo kill -9
```
Error: "Container runtime is not running"
```bash
sudo systemctl status docker
sudo systemctl start docker
```
Issue 3: Worker Nodes Not Joining
Troubleshooting steps:
1. Verify network connectivity between nodes
2. Check firewall rules
3. Ensure token hasn't expired
4. Verify time synchronization between nodes
```bash
Check token validity
kubeadm token list
Generate new token if expired
kubeadm token create --print-join-command
```
Issue 4: DNS Resolution Problems
Symptoms: Pods cannot resolve service names or external domains.
Solutions:
```bash
Check CoreDNS pods
kubectl get pods -n kube-system | grep coredns
Restart CoreDNS if necessary
kubectl delete pods -n kube-system -l k8s-app=kube-dns
```
Issue 5: High Memory Usage
Monitoring and optimization:
```bash
Monitor resource usage
kubectl top nodes
kubectl top pods --all-namespaces
Set resource limits
kubectl set resources deployment nginx --limits=cpu=200m,memory=256Mi
```
Best Practices and Professional Tips
Security Best Practices
1. Regular Updates: Keep Kubernetes components updated
```bash
sudo apt update && sudo apt upgrade kubeadm kubectl kubelet
```
2. RBAC Configuration: Implement Role-Based Access Control
```bash
kubectl create serviceaccount limited-user
kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
kubectl create rolebinding read-pods --role=pod-reader --serviceaccount=default:limited-user
```
3. Network Policies: Implement network segmentation
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
```
Performance Optimization
1. Resource Management: Always set resource requests and limits
2. Node Affinity: Use node affinity for workload placement
3. Horizontal Pod Autoscaling: Implement HPA for dynamic scaling
```bash
kubectl autoscale deployment nginx --cpu-percent=50 --min=1 --max=10
```
Monitoring and Logging
1. Install Metrics Server:
```bash
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
```
2. Set up Persistent Logging: Consider implementing ELK stack or similar solution
Backup Strategies
1. etcd Backup:
```bash
sudo ETCDCTL_API=3 etcdctl snapshot save snapshot.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
```
2. Configuration Backup: Regularly backup Kubernetes manifests and configurations
Cluster Maintenance
1. Node Maintenance:
```bash
Drain node for maintenance
kubectl drain --ignore-daemonsets --delete-emptydir-data
Uncordon node after maintenance
kubectl uncordon
```
2. Certificate Management: Monitor certificate expiration
```bash
kubeadm certs check-expiration
```
Advanced Configuration Options
Custom Cluster Configuration
For production environments, consider using a custom kubeadm configuration file:
```yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.0
controlPlaneEndpoint: "k8s-master:6443"
networking:
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
etcd:
local:
dataDir: "/var/lib/etcd"
apiServer:
extraArgs:
enable-admission-plugins: "NodeRestriction,ResourceQuota"
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: "192.168.1.100"
bindPort: 6443
```
Initialize with custom configuration:
```bash
kubeadm init --config=kubeadm-config.yaml
```
High Availability Setup
For production environments, consider setting up a highly available control plane with multiple master nodes and an external etcd cluster.
Conclusion
Installing Kubernetes on Linux is a comprehensive process that requires careful attention to system requirements, network configuration, and security considerations. This guide has walked you through the complete installation process, from preparing your Linux system to deploying your first applications.
Key takeaways from this installation guide:
1. System Preparation: Proper system preparation, including disabling swap and configuring networking, is crucial for a successful Kubernetes installation.
2. Component Installation: The installation involves multiple components working together: container runtime, kubelet, kubeadm, kubectl, and network add-ons.
3. Cluster Management: Understanding how to initialize clusters, join nodes, and manage the cluster lifecycle is essential for ongoing operations.
4. Troubleshooting Skills: Developing troubleshooting skills helps resolve common issues quickly and maintain cluster health.
5. Security and Best Practices: Implementing security measures and following best practices ensures a robust, production-ready cluster.
Next Steps
Now that you have a functional Kubernetes cluster, consider these next steps:
1. Learn kubectl Commands: Master essential kubectl commands for daily operations
2. Explore Workload Types: Experiment with Deployments, Services, ConfigMaps, and Secrets
3. Implement CI/CD: Integrate your cluster with continuous integration and deployment pipelines
4. Monitor and Log: Set up comprehensive monitoring and logging solutions
5. Study Advanced Topics: Explore topics like custom resources, operators, and service mesh
Additional Resources
- Official Kubernetes Documentation: https://kubernetes.io/docs/
- Kubernetes GitHub Repository: https://github.com/kubernetes/kubernetes
- CNCF Training: Consider pursuing Certified Kubernetes Administrator (CKA) certification
- Community Support: Join Kubernetes Slack channels and forums for community support
With your Kubernetes cluster now running on Linux, you're well-equipped to begin deploying and managing containerized applications at scale. Remember that Kubernetes is a powerful but complex platform, and continuous learning and practice will help you master its full potential.