# Kubernetes Fundamentals :::warning [toc] ::: ![k8s-logo](https://hackmd.io/_uploads/SJBfCoi3-g.png) ### What is Kubernetes :::success Kubernetes (K8s) is an open-source, portable, and extensible platform designed to automate the deployment, scaling, and management of containerized applications. Originally developed by Google, it represents over 15 years of experience in running production workloads at scale. At its core, Kubernetes functions as a distributed system framework that drives a cluster toward a user-defined desired state through continuous, independent control loops. ::: **Critical Takeaways:** :::info - **Declarative Management**: Unlike traditional orchestration that follows a defined A-to-B-to-C workflow, Kubernetes uses a set of independent control processes that continuously monitor the current state and make adjustments to match the provided specification. - **Atomic Units (Pods)**: The smallest deployable unit in Kubernetes is the Pod, which represents one or more tightly coupled containers sharing storage and network resources. Architecture: The system is divided into a Control Plane, which makes global decisions about the cluster, and Nodes, which serve as the worker machines running the actual application workloads. - **Resiliency and Self-Healing**: Kubernetes provides built-in mechanisms for automated rollouts, rollbacks, service discovery, load balancing, and self-healing (restarting or replacing failed containers). - **Flexibility**: It is not a monolithic PaaS; it provides building blocks (pluggable logging, monitoring, and storage) while preserving user choice in configuration and CI/CD workflows. ::: ### Why Kubernetes ![Why-k8s](https://hackmd.io/_uploads/BkGq12inZg.png) --- ### Kubernetes Architecture --- **Cluster Architecture and Components** :::success Kubernetes operates on a hub-and-spoke model where all communication is centralized through the API server. A cluster is composed of two primary resource types: the Control Plane and worker Nodes. ::: ![k8s-cluster-architecture-1](https://hackmd.io/_uploads/rySfRio2bl.png) --- **Control Plane Components** --- :::info ![k8s-control-plane](https://hackmd.io/_uploads/BJrGCij2Wg.png) The Control Plane manages the overall state of the cluster, detecting and responding to cluster events. | Component | Function | |--------------------------|-------------------------------------------------------------------------| | kube-apiserver | The front end for the control plane; exposes the Kubernetes API (HTTP). Designed to scale horizontally. | | etcd | A consistent, highly-available key-value store used as the backing store for all cluster data. | | kube-scheduler | Watches for newly created Pods with no assigned node and selects a suitable node based on resource requirements and constraints. | | kube-controller-manager | Runs controller processes (e.g., Node, Job, EndpointSlice) to implement API behavior. | | cloud-controller-manager | (Optional) Links the cluster to a cloud provider's API, separating cloud-specific logic from the core cluster logic. | ::: **Node (Worker) Components** :::info ![k8s-worker-plane](https://hackmd.io/_uploads/SJUSknjhbx.png) Nodes host the Pods that comprise the application workload. Every node must run three essential services: | Component | Function | |--------------------|--------------------------------------------------------------------------| | kubelet | An agent that ensures containers are running within a Pod and remain healthy according to the provided PodSpecs. | | kube-proxy | A network proxy that maintains network rules on nodes, enabling communication to Pods from inside or outside the cluster. | | Container Runtime | The software responsible for running containers (e.g., containerd, CRI-O). | ::: --- ### Kubernetes Cluster Setup Guide (Minikube & k3s) --- **Prerequisites** :::warning - Ubuntu 22.04 / 24.04 (or similar Linux VM) - Minimum: - 2 CPU - 4 GB RAM - Internet access - sudo privileges ::: #### Option 1: Minikube Setup :::success **Step 1: Install Dependencies** ```bash sudo apt update sudo apt install -y curl wget apt-transport-https ``` **Step 2: Install kubectl** ```bash curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x kubectl sudo mv kubectl /usr/local/bin/ Verify: kubectl version --client ``` **Step 3: Install Minikube** ```bash= curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikube Verify: minikube version ``` **Step 4: Install Container Runtime (Docker)** ```bash= sudo apt install -y docker.io sudo systemctl enable docker sudo systemctl start docker sudo usermod -aG docker $USER newgrp docker ``` **Step 5: Start Minikube Cluster** ```bash= minikube start --driver=docker ``` **Step 6: Verify Cluster** ```bash= kubectl get nodes Expected output: NAME STATUS ROLES AGE VERSION minikube Ready control-plane ... ``` **Step 7: Deploy Test App** ```bash= kubectl create deployment nginx --image=nginx kubectl expose deployment nginx --type=NodePort --port=80 Access: minikube service nginx ``` ::: #### Option 2: k3s Setup :::info **Step 1: Install k3s** ```bash= curl -sfL https://get.k3s.io | sh - ``` **Step 2: Check Service Status** ```bash= sudo systemctl status k3s ``` **Step 3: Creating Command alias for Kubectl (Optional)** ```bash= alias kc='sudo k3s kubectl' kc get node ```` **Step 4: Verify Cluster** ```bash= kc get nodes Expected: NAME STATUS ROLES AGE VERSION <hostname> Ready control-plane,master ... ``` **Grab the K3S_TOKEN from the Manager** ``` sudo cat /var/lib/rancher/k3s/server/node-token ``` :bulb: *Please copy the **token**, as it will be required when adding a node to the cluster.* **Step 5: Add a worker node to the cluster** ```bash= Command: curl -sfL https://get.k3s.io | K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh - Example (DO-LAB): curl -sfL https://get.k3s.io | K3S_URL=https://165.227.225.148:6443 K3S_TOKEN=K10a810c11f1bfc253cbdbf63c6bbad2a5bc7fb67eafd91b007a30569b723d48a28::server:3a078e28e0f52fccfd8650871cddb068 sh - Example (SL-Lab): curl -sfL https://get.k3s.io | K3S_URL=https://172.31.20.160:6443 K3S_TOKEN=K10cf647253f2fcaa1475358866ccbc621f6fb2115f4e644a3437350709068a336f::server:a0522cff7f73f3132be946f5735cdc56 sh - ``` **Step 5: Deploy Test App** ```bash= kubectl create deployment nginx --image=nginx kubectl expose deployment nginx --type=NodePort --port=80 ``` **Step 6: Access Application** ```bash= Get NodePort: kubectl get svc nginx Access: http://<VM-IP>:<NodePort> ``` ::: #### Option 3: microk8s Setup :::success **1 Preparation** ```bash > Connect via SSH, example: `ssh lab123.kubelabs.tk` > Run on the server: sudo apt update sudo iptables -P FORWARD ACCEPT ```` **2. Installation** > <https://microk8s.io/> ```bash sudo snap install microk8s --classic sudo microk8s status --wait-ready ``` > Result: > > microk8s (1.23/stable) v1.23.3 from Canonical ✓ installed > To install a specific version: `--channel=1.22/stable` **2.1. Post-Installation** ```bash ./post-install.sh ``` **2.2. Permissions to run microk8s** ```bash sudo usermod -a -G microk8s kube newgrp microk8s ``` **2.3. Install addons** ```bash sudo snap install kubectl --classic sudo microk8s.enable dns dashboard storage ingress ``` **2.4. Enable remote cluster administration** ```bash mkdir .kube sudo microk8s kubectl config set-cluster microk8s-cluster \ --server=https://<PUBLIC_IP>:16443 \ --insecure-skip-tls-verify # Restart the cluster microk8s stop microk8s start ``` > Another option using stop/start ```bash sudo systemctl restart snap.microk8s.daemon-apiserver-kicker.service ``` > In case the KUBE-API is not exposed automatically ```bash sudo sh -c 'echo "--allow-privileged=true" >> /var/snap/microk8s/current/args/kube-apiserver' ``` **2.5. Export the .kube/config configuration** ```bash microk8s config > ~/.kube/config cat ~/.kube/config ``` **2.6. Verify the MicroK8s installation** ```bash kubectl get nodes kubectl describe nodes ``` ::: #### Key differences :::success | Feature | Minikube | k3s | |----------------|-----------------------------------|-------------------------------------| | Primary Use | Learning, local development | Lightweight production, edge, labs | | Installation | Multi-step setup | Single script / binary | | Architecture | Runs inside VM or Docker | Runs directly on host (bare metal) | | Resource Usage | Moderate | Very low | | Startup Time | Slower | Fast | | Components | Standard Kubernetes components | Simplified, optimized components | | Container Runtime | Docker / containerd | containerd (default) | | HA Support | Limited (single-node by default) | Supports multi-node & HA setups | | Cloud Native | No direct cloud integration | Can integrate with cloud setups | ::: #### Cleanup :::warning **Minikube** ``` minikube delete ``` **k3s** ``` sudo /usr/local/bin/k3s-uninstall.sh ``` ::: ### Working with Kubernetes Objects --- #### Pods --- Pods are the smallest deployable units of computing that you can create and manage in Kubernetes. ![Pods](https://hackmd.io/_uploads/SkooLgZpZg.png) :arrow_right: *Source: https://kubernetes.io/docs/* --- #### Pods inside a worker node --- ![PodsinNode](https://hackmd.io/_uploads/r1lyDxbTbl.png) :arrow_right: *Source: https://kubernetes.io/docs/* --- **The Kubernetes Abstraction Hierarchy** --- ![KubernetesAbstractionHierarchy](https://hackmd.io/_uploads/SkYPKq7a-x.png) ### Working with Kubernetes Objects #### Explore your Kubernetes cluster ````yaml= kubectl version kubectl cluster-info kubectl api-resources ## Get all API Object list kubectl get nodes (nodes/node/no) kubectl get pods (pods/pod/po) kubectl get namespaces (namespaces/namespace/ns) kubectl get pods --all-namespaces kubectl get pods -n kube-system kubectl get pods [pod name] kubectl get pods -o wide --all-namespaces #Show pods along with nodes kubectl get pods -o wide --all-namespaces | grep <node> #Show pods on specified node kubectl describe node <node-name> #Show all of the non-terminated pods running on that node ```` ![k8s-yaml](https://hackmd.io/_uploads/Hytyxhj3Zl.png) #### YAML Syntax for Kubernetes **Structure** :::warning A - API version K - Kind ## this defines the type of object/primitive M - Metadata S - Specs ::: ![k8s-YAML-structure](https://hackmd.io/_uploads/ryGOUebaZl.png) --- ### Class Exercises --- #### Demo 1: Creating and exploring objects ````yaml= kubectl run pingpong --image alpine ping 1.1.1.1 kubectl get all kubectl logs pod/pingpong ==> get logs from a random pod within a deploymnt kubectl logs pod/pingpong --tail 5 kubectl logs pod/pingpong --tail 1 --follow kubectl logs -l run=pingpong --tail 1 -f ==> get logs from all pods within a deployment kubectl describe pod <podname> ```` **Demo 2: Create a basic pod via YAML** **pod1.yaml** ```yaml= apiVersion: v1 kind: Pod metadata: name: redis labels: name: redis app: demo spec: containers: - name: redis image: redis:latest ports: - containerPort: 6379 protocol: TCP ``` **Commands** ```bash= ## Create k8s Object kubectl create -f pod1.yaml ## Explore and validate kubectl get pods kubectl get pods -o wide kubectl get pods -o yaml kubectl describe pods ``` #### Demo 3: YAML Introduction with a Pod Manifest **Objective** :::success Show how to create resources declaratively. ::: File: pod-nginx.yaml ```yaml= apiVersion: v1 kind: Pod metadata: name: nginx-yaml-pod labels: app: nginx-demo spec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80 ``` **Commands** ```bash= kubectl apply -f pod-nginx.yaml kubectl get pods kubectl describe pod nginx-yaml-pod ``` #### Demo 4: Inspect Live YAML and Learn the API Shape **Commands** ```bash= kubectl get pod nginx-yaml-pod -o yaml kubectl get pod nginx-yaml-pod -o wide kubectl explain pod kubectl explain pod.spec.containers ``` #### Demo 5: Create Your First Deployment **Objective** :::success Show how Kubernetes manages Pods through a higher-level controller. ::: **File: deployment-nginx.yaml** ```yaml= apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deploy spec: replicas: 2 selector: matchLabels: app: nginx-deploy template: metadata: labels: app: nginx-deploy spec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80 ``` **Commands** ```bash= kubectl apply -f deployment-nginx.yaml kubectl get deployments kubectl get replicasets kubectl get pods -l app=nginx-deploy ``` #### Demo 6: Scale a Deployment **Objective** :::success Demonstrate horizontal scaling. ::: **Commands** ```bash= kubectl scale deployment nginx-deploy --replicas=4 kubectl get deployment nginx-deploy kubectl get pods -l app=nginx-deploy kubectl get pods -w ``` :bulb: *-w (watch) → “Keep watching for changes in real time”* :bulb: *-l (label) -> shows all the pods matching the label* :bulb: *Scaling in Kubernetes is typically just a change in desired state. The platform handles creating or removing Pods.* ### References :::info - [Kubernetes Concepts](https://kubernetes.io/docs/concepts/) - [Kubernetes Tutorials](https://kubernetes.io/docs/tutorials/) - https://k3s.io/ :::