Setting Up Kubernetes: Part -1

Prerequisites

My setup:

Ensure SSH is enabled in the VMs (disabled by default on Multipass VM):

# Enable in /etc/ssh/sshd_config
PasswordAuthentication yes
PubkeyAuthentication yes

# Generate RSA key on client machines
# Add ~/.ssh/id_rsa.pub from each client machine to ~/.ssh/authorized_keys on each VM
            

Configuring Control Plane Node

# Define the Kubernetes version and used CRI-O stream
export KUBERNETES_VERSION=v1.31
export CRIO_VERSION=v1.31

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

# Add the CRI-O repository
sudo curl -fsSL https://pkgs.k8s.io/addons:/cri-o:/stable:/$CRIO_VERSION/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/cri-o-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://pkgs.k8s.io/addons:/cri-o:/stable:/$CRIO_VERSION/deb/ /" | sudo tee /etc/apt/sources.list.d/cri-o.list

# Install packages
sudo apt-get update
sudo apt-get install -y cri-o kubelet kubeadm
sudo apt-mark hold kubelet kubeadm cri-o

# Set swap off, start br_netfilter, and set ipv4 forwarding
sudo swapoff -a
sudo modprobe br_netfilter
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/k8s.conf
sudo sysctl --system

# Start CRI-O
sudo systemctl start crio.service

# Initialize control-plane node
export CIDR=10.85.0.0/16
sudo kubeadm init
            

Configuring Client Node

# Install kubectl
sudo apt install kubectl

# Create .kube directory
mkdir ~/.kube

# Copy necessary files from control plane node
# /etc/kubernetes/pki/apiserver-kubelet-client.crt
# /etc/kubernetes/pki/apiserver-kubelet-client.key
# /etc/kubernetes/pki/ca.crt

# Create local Kubeconfig file (~/.kube/config)
apiVersion: v1
clusters:
- cluster:
    certificate-authority: ./ca.crt
    server: https://<control-plane-ip>:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate: ./apiserver-kubelet-client.crt
    client-key: ./apiserver-kubelet-client.key

# Test kubectl
kubectl config use-context kubernetes-admin@kubernetes
kubectl get nodes
            

Configuring Worker Node

Follow the same steps as the control-plane node, except for the initialization. Then join the cluster:

sudo kubeadm join <cluster-ip>:6443 --token e7dfct.uh6ojtum3vmswbx7 --discovery-token-ca-cert-hash sha256:e012626
            

Deploying an Application

Create deployment and service files on the client machine:

# hello-world-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-world
        image: hashicorp/http-echo
        args:
        - "-text=Hello, World!"
        ports:
        - containerPort: 5678

# hello-world-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: hello-world
spec:
  type: NodePort
  selector:
    app: hello-world
  ports:
    - port: 5678
      targetPort: 5678
      nodePort: 30007

# Apply the configurations
kubectl apply -f hello-world-deployment.yaml
kubectl apply -f hello-world-service.yaml

# View pods and nodes
kubectl get pods -o wide
kubectl get nodes -o wide

# Access the hello-world app
curl http://<any-one-node-internal-ip>:30007

# Scale the deployment
kubectl get deployments
kubectl scale deployment  --replicas=2

# To know on which node the pod is running
kubectl get pods -o wide