Skip to main content

Chapter 2: Installation & Setup

Authored by syscook.dev

What is Kubernetes Installation?

Kubernetes installation involves setting up a complete Kubernetes cluster with all necessary components, including the control plane (master nodes) and worker nodes. The installation process varies depending on your environment, requirements, and the tools you choose to use.

Key Installation Methods:

  • Local Development: Minikube, Docker Desktop, Kind
  • Cloud Providers: EKS (AWS), GKE (Google), AKS (Azure)
  • On-Premises: kubeadm, kops, kubespray
  • Managed Services: Cloud provider managed Kubernetes
  • Container Platforms: OpenShift, Rancher

Why Choose Different Installation Methods?

1. Local Development Setup

Local installations are perfect for learning, development, and testing.

# Minikube installation example
# Install Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Start Minikube cluster
minikube start --driver=docker --memory=4096 --cpus=2

# Verify installation
kubectl get nodes
kubectl cluster-info

Minikube Benefits:

  • Quick setup for local development
  • Supports multiple Kubernetes versions
  • Easy to reset and recreate
  • Good for learning and testing

2. Production Cloud Setup

Cloud installations provide managed, scalable, and production-ready clusters.

# AWS EKS cluster creation
eksctl create cluster \
--name production-cluster \
--version 1.28 \
--region us-west-2 \
--nodegroup-name worker-nodes \
--node-type t3.medium \
--nodes 3 \
--nodes-min 1 \
--nodes-max 5 \
--managed

# Verify EKS cluster
kubectl get nodes
kubectl get pods -n kube-system

Cloud Benefits:

  • Managed control plane
  • Automatic updates and patches
  • Built-in monitoring and logging
  • High availability and scalability

How to Install Kubernetes?

1. Local Development with Minikube

Prerequisites Installation

# Install Docker (required for Minikube)
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER

# Install kubectl
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

# Verify kubectl installation
kubectl version --client

Minikube Installation and Configuration

# Install Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Start Minikube with specific configuration
minikube start \
--driver=docker \
--memory=4096 \
--cpus=2 \
--disk-size=20g \
--kubernetes-version=v1.28.0

# Enable addons
minikube addons enable ingress
minikube addons enable metrics-server
minikube addons enable dashboard

# Check cluster status
minikube status
kubectl get nodes
kubectl get pods -n kube-system

Minikube Configuration File

# ~/.minikube/config/config.json
{
"driver": "docker",
"memory": 4096,
"cpus": 2,
"disk-size": "20g",
"kubernetes-version": "v1.28.0",
"addons": [
"ingress",
"metrics-server",
"dashboard"
],
"profile": "minikube"
}

2. Production Setup with kubeadm

Master Node Setup

# Update system packages
sudo apt-get update && sudo apt-get upgrade -y

# Install required packages
sudo apt-get install -y apt-transport-https ca-certificates curl

# Add Kubernetes repository
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/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.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

# Install kubeadm, kubelet, and kubectl
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

# Configure containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd

# Initialize the cluster
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.1.100 \
--control-plane-endpoint=192.168.1.100:6443 \
--upload-certs

# Configure kubectl for 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

Worker Node Setup

# Install required packages (same as master)
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y apt-transport-https ca-certificates curl

# Add Kubernetes repository
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/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.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

# Install kubeadm, kubelet, and kubectl
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

# Configure containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd

# Join the cluster (use the command from master node output)
sudo kubeadm join 192.168.1.100:6443 \
--token abcdef.1234567890abcdef \
--discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef

Network Plugin Installation (Flannel)

# Install Flannel CNI plugin
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

# Verify installation
kubectl get pods -n kube-flannel
kubectl get nodes

3. Cloud Provider Setup (AWS EKS)

Prerequisites

# Install AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

# Install eksctl
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv /tmp/eksctl /usr/local/bin

# Install kubectl
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

EKS Cluster Creation

# Configure AWS credentials
aws configure

# Create EKS cluster with eksctl
eksctl create cluster \
--name production-cluster \
--version 1.28 \
--region us-west-2 \
--nodegroup-name worker-nodes \
--node-type t3.medium \
--nodes 3 \
--nodes-min 1 \
--nodes-max 5 \
--managed \
--with-oidc \
--ssh-access \
--ssh-public-key my-key \
--vpc-public-subnets subnet-12345,subnet-67890 \
--vpc-private-subnets subnet-abcde,subnet-fghij

# Verify cluster creation
kubectl get nodes
kubectl get pods -n kube-system

EKS Configuration File

# cluster-config.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
name: production-cluster
region: us-west-2
version: "1.28"

nodeGroups:
- name: worker-nodes
instanceType: t3.medium
desiredCapacity: 3
minSize: 1
maxSize: 5
ssh:
allow: true
publicKeyName: my-key
iam:
withAddonPolicies:
imageBuilder: true
autoScaler: true
externalDNS: true
certManager: true
appMesh: true
ebs: true
fsx: true
efs: true
awsLoadBalancerController: true

addons:
- name: vpc-cni
version: latest
- name: coredns
version: latest
- name: kube-proxy
version: latest
- name: aws-ebs-csi-driver
version: latest

4. Docker Desktop Kubernetes

Enable Kubernetes in Docker Desktop

# Docker Desktop settings
# 1. Open Docker Desktop
# 2. Go to Settings > Kubernetes
# 3. Check "Enable Kubernetes"
# 4. Click "Apply & Restart"

# Verify installation
kubectl get nodes
kubectl cluster-info

Docker Desktop Configuration

// Docker Desktop settings.json
{
"kubernetes": {
"enabled": true,
"version": "v1.28.0",
"memory": 4096,
"cpus": 2
},
"experimental": false,
"debug": false,
"registry-mirrors": [],
"insecure-registries": [],
"default-runtime": "containerd"
}

5. Kind (Kubernetes in Docker)

Kind Installation and Setup

# Install Kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

# Create Kind cluster
kind create cluster --name dev-cluster --config kind-config.yaml

# Verify cluster
kubectl get nodes
kubectl cluster-info --context kind-dev-cluster

Kind Configuration File

# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: dev-cluster
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
- role: worker
- role: worker
networking:
apiServerAddress: "127.0.0.1"
apiServerPort: 6443

Practical Examples

1. Complete Local Development Setup

Step 1: Install Prerequisites

#!/bin/bash
# install-prerequisites.sh

# Update system
sudo apt-get update && sudo apt-get upgrade -y

# Install Docker
sudo apt-get install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER

# Install kubectl
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 Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

echo "Prerequisites installed successfully!"

Step 2: Start Minikube Cluster

#!/bin/bash
# start-minikube.sh

# Start Minikube with optimal settings
minikube start \
--driver=docker \
--memory=4096 \
--cpus=2 \
--disk-size=20g \
--kubernetes-version=v1.28.0

# Enable essential addons
minikube addons enable ingress
minikube addons enable metrics-server
minikube addons enable dashboard

# Verify cluster
kubectl get nodes
kubectl get pods -n kube-system

echo "Minikube cluster started successfully!"

Step 3: Deploy Test Application

#!/bin/bash
# deploy-test-app.sh

# Create namespace
kubectl create namespace test-app

# Deploy nginx
kubectl create deployment nginx --image=nginx:1.20 -n test-app

# Expose service
kubectl expose deployment nginx --port=80 --type=NodePort -n test-app

# Get service URL
minikube service nginx -n test-app --url

echo "Test application deployed successfully!"

2. Production EKS Setup

Step 1: Create EKS Cluster

#!/bin/bash
# create-eks-cluster.sh

# Create cluster
eksctl create cluster \
--name production-cluster \
--version 1.28 \
--region us-west-2 \
--nodegroup-name worker-nodes \
--node-type t3.medium \
--nodes 3 \
--nodes-min 1 \
--nodes-max 5 \
--managed \
--with-oidc \
--ssh-access \
--ssh-public-key my-key

# Update kubeconfig
aws eks update-kubeconfig --region us-west-2 --name production-cluster

# Verify cluster
kubectl get nodes
kubectl get pods -n kube-system

echo "EKS cluster created successfully!"

Step 2: Install Essential Addons

#!/bin/bash
# install-eks-addons.sh

# Install AWS Load Balancer Controller
kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller/crds?ref=master"
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=production-cluster

# Install Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# Install Cluster Autoscaler
kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml

echo "EKS addons installed successfully!"

3. Multi-Node kubeadm Setup

Master Node Configuration

#!/bin/bash
# setup-master.sh

# Initialize cluster
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.1.100 \
--control-plane-endpoint=192.168.1.100:6443 \
--upload-certs

# Configure kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# Install network plugin
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

# Remove taint to allow scheduling on master
kubectl taint nodes --all node-role.kubernetes.io/control-plane-

echo "Master node configured successfully!"

Worker Node Configuration

#!/bin/bash
# setup-worker.sh

# Join cluster (replace with actual token and hash from master)
sudo kubeadm join 192.168.1.100:6443 \
--token abcdef.1234567890abcdef \
--discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef

echo "Worker node joined successfully!"

Best Practices

1. Resource Planning

# Calculate resource requirements
# Master nodes: 2-4 CPU cores, 4-8GB RAM
# Worker nodes: 2-8 CPU cores, 4-16GB RAM
# Storage: 20-100GB per node

# Example resource calculation
# 3 worker nodes × 4 CPU cores = 12 total CPU cores
# 3 worker nodes × 8GB RAM = 24GB total RAM

2. Security Configuration

# Enable RBAC
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=admin

# Enable Pod Security Standards
kubectl label namespace default pod-security.kubernetes.io/enforce=restricted
kubectl label namespace default pod-security.kubernetes.io/audit=restricted
kubectl label namespace default pod-security.kubernetes.io/warn=restricted

3. Monitoring Setup

# Install Prometheus and Grafana
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack

# Install Jaeger for tracing
helm repo add jaegertracing https://jaegertracing.github.io/helm-charts
helm install jaeger jaegertracing/jaeger

Common Pitfalls and Solutions

1. Insufficient Resources

# ❌ Problem: Cluster fails to start due to insufficient resources
# Error: failed to start node: failed to start: creating host: create: creating: setting up container node: preparing kubeadm: generating kubeadm config: getting cluster info: getting nodes: listing nodes: the server could not find the requested resource

# ✅ Solution: Increase allocated resources
minikube start --memory=4096 --cpus=2 --disk-size=20g

2. Network Issues

# ❌ Problem: Pods cannot communicate with each other
# Error: network is unreachable

# ✅ Solution: Install and configure CNI plugin
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

3. Firewall Configuration

# ❌ Problem: Nodes cannot join cluster
# Error: connection refused

# ✅ Solution: Configure firewall rules
sudo ufw allow 6443/tcp # Kubernetes API server
sudo ufw allow 2379:2380/tcp # etcd server client API
sudo ufw allow 10250/tcp # Kubelet API
sudo ufw allow 10251/tcp # kube-scheduler
sudo ufw allow 10252/tcp # kube-controller-manager

Conclusion

Kubernetes installation and setup is the foundation for running containerized applications. By understanding:

  • What different installation methods are available and their use cases
  • Why each method is suitable for different environments
  • How to properly configure and deploy Kubernetes clusters

You can choose the right installation method for your needs and successfully set up a Kubernetes cluster. Whether for local development or production deployment, proper installation ensures a stable and scalable container orchestration platform.

Next Steps

  • Practice with different installation methods
  • Configure cluster networking and storage
  • Move on to Chapter 3: Cluster Configuration

This tutorial is part of the Kubernetes Mastery series by syscook.dev