Complete Kubernetes Installation, Setup, and Configuration Guide with Hands-On Labs

Introduction

Kubernetes has become the de facto standard for container orchestration, enabling organizations to deploy, scale, and manage containerized applications efficiently. This comprehensive guide will walk you through installing, setting up, and configuring a Kubernetes cluster from scratch, complete with practical labs to solidify your understanding.

What is Kubernetes?

Kubernetes (K8s) is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. It provides a robust framework for running distributed systems resiliently, handling scaling and failover for your applications.

Key Components

Control Plane Components:

  • kube-apiserver: The API server that serves the Kubernetes API
  • etcd: Consistent and highly-available key-value store for cluster data
  • kube-scheduler: Assigns pods to nodes based on resource requirements
  • kube-controller-manager: Runs controller processes that regulate cluster state

Node Components:

  • kubelet: Agent that runs on each node and manages containers
  • kube-proxy: Network proxy that maintains network rules
  • Container Runtime: Software responsible for running containers (Docker, containerd, CRI-O)

Prerequisites

Before starting, ensure you have:

  • Ubuntu 20.04/22.04 or CentOS 8/Rocky Linux 8 (minimum 2 GB RAM, 2 CPUs)
  • Root or sudo access
  • Network connectivity between nodes
  • Unique hostname, MAC address, and product_uuid for each node

Installation Methods Overview

We’ll cover three primary installation approaches:

  1. kubeadm: Production-ready installation tool
  2. Minikube: Local development clusters
  3. Kind: Kubernetes in Docker for testing

Method 1: Installing Kubernetes with kubeadm

Step 1: Prepare the Environment

First, disable swap on all nodes (Kubernetes requires swap to be disabled):

# Disable swap temporarily
sudo swapoff -a

# Disable swap permanently
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

Configure kernel modules:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

Set up required sysctl parameters:

cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

sudo sysctl --system

Step 2: Install Container Runtime (containerd)

# Install containerd
sudo apt-get update
sudo apt-get install -y containerd

# Create containerd configuration
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# Configure systemd cgroup driver
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml

# Restart containerd
sudo systemctl restart containerd
sudo systemctl enable containerd

Step 3: Install Kubernetes Components

Add the Kubernetes repository:

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

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 kubelet, kubeadm, and kubectl:

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

Step 4: Initialize the Control Plane

On the master node, initialize the cluster:

sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=<MASTER_IP>

After successful initialization, 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

Step 5: Install a Pod Network Add-on

Install Flannel for pod networking:

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

Step 6: Join Worker Nodes

On each worker node, run the join command provided by kubeadm init:

sudo kubeadm join <MASTER_IP>:6443 --token <TOKEN> --discovery-token-ca-cert-hash sha256:<HASH>

Method 2: Installing Minikube for Local Development

Minikube is perfect for local development and testing:

# 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
minikube start --driver=docker

# Verify installation
kubectl get nodes

Method 3: Installing Kind (Kubernetes in Docker)

Kind runs Kubernetes clusters in Docker containers:

# 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 a cluster
kind create cluster --name my-cluster

# Verify installation
kubectl cluster-info --context kind-my-cluster

Configuration Deep Dive

Cluster Configuration

The cluster configuration is stored in /etc/kubernetes/admin.conf. Key configuration areas include:

API Server Configuration:

apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: <base64-encoded-ca-cert>
    server: https://<master-ip>:6443
  name: kubernetes

Network Configuration: Pod and service network ranges are crucial for cluster networking:

  • Pod CIDR: 10.244.0.0/16 (Flannel default)
  • Service CIDR: 10.96.0.0/12 (Kubernetes default)

Security Configuration

RBAC (Role-Based Access Control):

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

Network Policies:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Hands-On Labs

Lab 1: Deploy Your First Application

Objective: Deploy and expose a simple web application

Create a deployment:

# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80

Apply the deployment:

kubectl apply -f nginx-deployment.yaml
kubectl get deployments
kubectl get pods

Expose the deployment:

kubectl expose deployment nginx-deployment --type=NodePort --port=80
kubectl get services

Expected Output: You should see three nginx pods running and a service exposing them on a random port.

Lab 2: ConfigMaps and Secrets

Objective: Learn to manage configuration data securely

Create a ConfigMap:

kubectl create configmap app-config --from-literal=database_url=postgresql://localhost:5432/mydb

Create a Secret:

kubectl create secret generic app-secret --from-literal=database_password=supersecret

Use them in a deployment:

# app-with-config.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-with-config
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: busybox
        command: ['sh', '-c', 'echo "Database URL: $DATABASE_URL" && echo "Password: $DATABASE_PASSWORD" && sleep 3600']
        env:
        - name: DATABASE_URL
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: database_url
        - name: DATABASE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: app-secret
              key: database_password

Lab 3: Persistent Storage

Objective: Work with persistent volumes and claims

Create a PersistentVolume:

# pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /tmp/data

Create a PersistentVolumeClaim:

# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

Use the PVC in a pod:

# pod-with-storage.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-storage
spec:
  containers:
  - name: container
    image: nginx
    volumeMounts:
    - name: storage
      mountPath: /usr/share/nginx/html
  volumes:
  - name: storage
    persistentVolumeClaim:
      claimName: my-pvc

Lab 4: Services and Ingress

Objective: Understand different service types and ingress controllers

Create different service types:

# services.yaml
apiVersion: v1
kind: Service
metadata:
  name: clusterip-service
spec:
  type: ClusterIP
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nodeport-service
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
---
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80

Install NGINX Ingress Controller:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

Create an Ingress resource:

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: myapp.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-deployment
            port:
              number: 80

Monitoring and Maintenance

Health Checks

Monitor cluster health:

kubectl get nodes
kubectl get pods --all-namespaces
kubectl top nodes
kubectl top pods

Troubleshooting Common Issues

Pod stuck in Pending state:

kubectl describe pod <pod-name>
kubectl get events --sort-by=.metadata.creationTimestamp

Node not ready:

kubectl describe node <node-name>
journalctl -u kubelet

Network issues:

kubectl get pods -n kube-system
kubectl logs -n kube-system <flannel-pod-name>

Backup and Recovery

Backup etcd data:

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/healthcheck-client.crt \
  --key=/etc/kubernetes/pki/etcd/healthcheck-client.key

Best Practices

Security Best Practices

  1. Enable RBAC: Always use role-based access control
  2. Use Network Policies: Restrict pod-to-pod communication
  3. Scan Images: Use tools like Trivy or Clair for vulnerability scanning
  4. Limit Resources: Set resource requests and limits for all containers
  5. Use Secrets: Never hardcode sensitive data in manifests

Operational Best Practices

  1. Use Namespaces: Organize resources logically
  2. Label Everything: Use consistent labeling strategies
  3. Monitor Resources: Implement comprehensive monitoring
  4. Regular Backups: Backup etcd and persistent data regularly
  5. Update Regularly: Keep Kubernetes and components updated

Performance Optimization

  1. Node Sizing: Right-size your nodes based on workload requirements
  2. Pod Disruption Budgets: Ensure high availability during updates
  3. Horizontal Pod Autoscaling: Automatically scale based on metrics
  4. Resource Quotas: Prevent resource exhaustion

Next Steps

After completing this guide, consider exploring:

  1. Advanced Networking: Calico, Cilium, or Istio service mesh
  2. Monitoring Stack: Prometheus, Grafana, and Alertmanager
  3. CI/CD Integration: GitOps with ArgoCD or Flux
  4. Advanced Scheduling: Node affinity, taints, and tolerations
  5. Custom Resources: Operators and Custom Resource Definitions (CRDs)

Conclusion

Kubernetes provides a powerful platform for container orchestration, but proper installation and configuration are crucial for success. This guide covered the fundamental concepts and provided hands-on experience with real-world scenarios. The labs demonstrate practical applications of Kubernetes features, from basic deployments to advanced configuration management.

Remember that Kubernetes is a complex system that requires ongoing learning and practice. Start with simple deployments and gradually incorporate more advanced features as your understanding grows. The community resources, documentation, and hands-on practice will help you master this essential technology.

Continue experimenting with different configurations, explore the vast ecosystem of Kubernetes tools, and consider pursuing official certifications like CKA (Certified Kubernetes Administrator) or CKAD (Certified Kubernetes Application Developer) to validate your skills.

The journey to Kubernetes mastery is ongoing, but with this foundation, you’re well-equipped to deploy, manage, and scale containerized applications in production environments.

Share: