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.