Skip to main content

Chapter 1: Kubernetes Fundamentals - Complete Container Orchestration Guide

Authored by syscook.dev

What is Kubernetes?

Kubernetes (often abbreviated as K8s) is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. This comprehensive guide will teach you everything you need to know about Kubernetes and how to use it effectively for modern application deployment.

Why Learn Kubernetes?

Kubernetes has become the industry standard for container orchestration because it:

  • Automates Deployment: Deploy and manage applications at scale
  • Scales Applications: Automatically scale based on demand
  • Manages Resources: Efficiently allocate CPU, memory, and storage
  • Ensures Reliability: Self-healing and high availability
  • Cloud Agnostic: Works across different cloud providers and on-premises
  • Industry Standard: Used by Google, Microsoft, Amazon, and thousands of companies

Kubernetes (K8s) is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. Originally developed by Google and now maintained by the Cloud Native Computing Foundation (CNCF), Kubernetes provides a robust framework for running distributed systems reliably and efficiently.

Key Concepts:

  • Container Orchestration: Managing and coordinating multiple containers across multiple hosts
  • Declarative Configuration: Describing desired state rather than imperative commands
  • Self-Healing: Automatically restarting failed containers and replacing unhealthy nodes
  • Horizontal Scaling: Automatically scaling applications based on demand
  • Service Discovery: Automatic discovery and load balancing of services
  • Rolling Updates: Zero-downtime deployments with automatic rollback capabilities

Why Use Kubernetes?

1. Container Management at Scale

Kubernetes simplifies the management of hundreds or thousands of containers across multiple servers.

# Example: Simple deployment configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web-app
spec:
replicas: 3 # Run 3 instances of the application
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: nginx:1.20
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"

What this configuration does:

  • Creates a deployment named web-app
  • Runs 3 replicas of the nginx container
  • Allocates specific CPU and memory resources
  • Exposes port 80 for web traffic

2. High Availability and Fault Tolerance

Kubernetes automatically handles failures and ensures your applications remain available.

# Example: Service configuration for load balancing
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer # Exposes the service externally

What this configuration does:

  • Creates a service that load balances traffic across all web-app pods
  • Exposes the service on port 80
  • Uses LoadBalancer type for external access
  • Automatically routes traffic to healthy pods

3. Automatic Scaling

Kubernetes can automatically scale your applications based on CPU usage, memory consumption, or custom metrics.

# Example: Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70

What this configuration does:

  • Automatically scales the web-app deployment
  • Maintains between 2 and 10 replicas
  • Scales up when CPU usage exceeds 70%
  • Scales down when CPU usage is below the threshold

How Does Kubernetes Work?

1. Kubernetes Architecture

Master Node Components

# Check cluster information
kubectl cluster-info

# Output example:
# Kubernetes control plane is running at https://kubernetes.docker.internal:6443
# CoreDNS is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

Key Master Components:

  1. API Server: Central management point for all cluster operations
  2. etcd: Distributed key-value store for cluster state
  3. Scheduler: Assigns pods to nodes based on resource requirements
  4. Controller Manager: Ensures desired state is maintained

Worker Node Components

# Check node information
kubectl get nodes -o wide

# Output example:
# NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
# docker-desktop Ready control-plane 1d v1.28.0 192.168.65.4 <none> Docker Desktop 5.15.0-91-generic docker://24.0.7

Key Worker Components:

  1. kubelet: Agent that runs on each node and manages pods
  2. kube-proxy: Network proxy that maintains network rules
  3. Container Runtime: Software responsible for running containers (Docker, containerd, etc.)

2. Core Kubernetes Objects

Pods

Pods are the smallest deployable units in Kubernetes. They can contain one or more containers.

# Example: Simple pod configuration
apiVersion: v1
kind: Pod
metadata:
name: simple-pod
labels:
app: simple-app
spec:
containers:
- name: nginx-container
image: nginx:1.20
ports:
- containerPort: 80
env:
- name: ENV_VAR
value: "production"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"

Configuration Explanation:

  • apiVersion: Kubernetes API version (v1 for core objects)
  • kind: Type of Kubernetes object (Pod)
  • metadata: Object metadata including name and labels
  • spec: Pod specification defining containers and their properties
  • containers: Array of containers to run in the pod
  • image: Container image to use
  • ports: Ports to expose from the container
  • env: Environment variables for the container
  • resources: CPU and memory requests and limits

Deployments

Deployments manage ReplicaSets and provide declarative updates to pods.

# Example: Deployment with detailed configuration
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
namespace: production
labels:
app: web-app
version: v1.0
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
version: v1.0
spec:
containers:
- name: web-container
image: nginx:1.20
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"

Configuration Explanation:

  • replicas: Number of pod replicas to maintain
  • strategy: Deployment strategy (RollingUpdate, Recreate)
  • rollingUpdate: Configuration for rolling updates
    • maxUnavailable: Maximum pods that can be unavailable during update
    • maxSurge: Maximum pods that can be created above desired replicas
  • selector: Label selector to identify managed pods
  • template: Pod template for creating new pods
  • livenessProbe: Health check to determine if container is alive
  • readinessProbe: Health check to determine if container is ready to serve traffic

Services

Services provide stable network access to a set of pods.

# Example: Service with multiple configurations
apiVersion: v1
kind: Service
metadata:
name: web-service
namespace: production
labels:
app: web-app
spec:
type: ClusterIP # Service type: ClusterIP, NodePort, LoadBalancer, ExternalName
selector:
app: web-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 443
sessionAffinity: ClientIP # Session affinity configuration
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800

Configuration Explanation:

  • type: Service type determining how the service is exposed
    • ClusterIP: Exposes service on cluster-internal IP
    • NodePort: Exposes service on each node's IP at a static port
    • LoadBalancer: Exposes service externally using cloud provider's load balancer
    • ExternalName: Maps service to external DNS name
  • selector: Label selector to identify target pods
  • ports: Array of port configurations
  • sessionAffinity: Session affinity type (None, ClientIP)
  • sessionAffinityConfig: Configuration for session affinity

3. Namespaces and Resource Organization

Namespaces

Namespaces provide logical separation of resources within a cluster.

# Example: Creating a namespace
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
environment: dev
team: frontend
# Create namespace via command line
kubectl create namespace development

# Apply resources to specific namespace
kubectl apply -f deployment.yaml -n development

# Get resources from specific namespace
kubectl get pods -n development

Namespace Benefits:

  • Resource isolation and organization
  • Access control and security boundaries
  • Resource quotas and limits
  • Logical grouping of related resources

Resource Quotas

Resource quotas limit resource consumption within namespaces.

# Example: Resource quota configuration
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: development
spec:
hard:
requests.cpu: "2"
requests.memory: 4Gi
limits.cpu: "4"
limits.memory: 8Gi
persistentvolumeclaims: "10"
pods: "20"
services: "5"
secrets: "10"
configmaps: "10"

Quota Explanation:

  • requests.cpu: Total CPU requests allowed
  • requests.memory: Total memory requests allowed
  • limits.cpu: Total CPU limits allowed
  • limits.memory: Total memory limits allowed
  • persistentvolumeclaims: Maximum number of PVCs
  • pods: Maximum number of pods
  • services: Maximum number of services
  • secrets: Maximum number of secrets
  • configmaps: Maximum number of config maps

4. Labels and Selectors

Labels

Labels are key-value pairs attached to objects for identification and selection.

# Example: Pod with multiple labels
apiVersion: v1
kind: Pod
metadata:
name: labeled-pod
labels:
app: web-app
version: v1.0
environment: production
tier: frontend
team: frontend-team
owner: john-doe
spec:
containers:
- name: web-container
image: nginx:1.20
# Query pods using label selectors
kubectl get pods -l app=web-app
kubectl get pods -l environment=production
kubectl get pods -l 'tier in (frontend,backend)'
kubectl get pods -l 'version!=v1.0'
kubectl get pods -l 'app=web-app,environment=production'

Label Selector Operators:

  • =: Equality
  • !=: Inequality
  • in: Set membership
  • notin: Set exclusion
  • exists: Key existence
  • doesnotexist: Key non-existence

Annotations

Annotations provide additional metadata that is not used for selection.

# Example: Pod with annotations
apiVersion: v1
kind: Pod
metadata:
name: annotated-pod
annotations:
description: "Web application pod for production"
contact: "[email protected]"
last-modified: "2024-01-15T10:30:00Z"
build-info: "build-123"
monitoring: "enabled"
spec:
containers:
- name: web-container
image: nginx:1.20

Practical Examples

1. Complete Web Application Setup

Step 1: Create Namespace

# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: web-app
labels:
environment: production

Step 2: Create Deployment

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
namespace: web-app
labels:
app: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-container
image: nginx:1.20
ports:
- containerPort: 80
env:
- name: ENV
value: "production"
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"

Step 3: Create Service

# service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-service
namespace: web-app
spec:
selector:
app: web-app
ports:
- port: 80
targetPort: 80
type: LoadBalancer

Step 4: Deploy the Application

# Apply all configurations
kubectl apply -f namespace.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

# Verify deployment
kubectl get all -n web-app

# Check pod status
kubectl get pods -n web-app -o wide

# Check service
kubectl get service -n web-app

2. Health Checks and Probes

Liveness Probe Example

apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
spec:
containers:
- name: web-container
image: nginx:1.20
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30 # Wait 30 seconds before first probe
periodSeconds: 10 # Check every 10 seconds
timeoutSeconds: 5 # Timeout after 5 seconds
failureThreshold: 3 # Restart after 3 consecutive failures
successThreshold: 1 # Consider healthy after 1 success

Readiness Probe Example

apiVersion: v1
kind: Pod
metadata:
name: readiness-pod
spec:
containers:
- name: web-container
image: nginx:1.20
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5 # Wait 5 seconds before first probe
periodSeconds: 5 # Check every 5 seconds
timeoutSeconds: 3 # Timeout after 3 seconds
failureThreshold: 3 # Mark unready after 3 failures
successThreshold: 1 # Mark ready after 1 success

3. Resource Management

Resource Requests and Limits

apiVersion: v1
kind: Pod
metadata:
name: resource-pod
spec:
containers:
- name: web-container
image: nginx:1.20
resources:
requests:
memory: "128Mi" # Minimum memory required
cpu: "250m" # Minimum CPU required (250 millicores)
limits:
memory: "256Mi" # Maximum memory allowed
cpu: "500m" # Maximum CPU allowed (500 millicores)

Quality of Service Classes

# Check pod QoS class
kubectl get pod resource-pod -o jsonpath='{.status.qosClass}'

# QoS Classes:
# - Guaranteed: requests == limits for all resources
# - Burstable: requests < limits for some resources
# - BestEffort: no requests or limits specified

Best Practices

1. Resource Naming and Organization

# Good: Consistent naming convention
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-frontend-v1
namespace: production
labels:
app: web-app
component: frontend
version: v1.0
environment: production
team: frontend-team

2. Health Check Configuration

# Good: Comprehensive health checks
livenessProbe:
httpGet:
path: /health/live
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3

readinessProbe:
httpGet:
path: /health/ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3

3. Resource Limits

# Good: Always specify resource requests and limits
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"

Common Pitfalls and Solutions

1. Missing Resource Limits

# ❌ Bad: No resource limits
spec:
containers:
- name: web-container
image: nginx:1.20

# ✅ Good: Proper resource limits
spec:
containers:
- name: web-container
image: nginx:1.20
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"

2. Inadequate Health Checks

# ❌ Bad: No health checks
spec:
containers:
- name: web-container
image: nginx:1.20

# ✅ Good: Proper health checks
spec:
containers:
- name: web-container
image: nginx:1.20
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5

3. Poor Label Organization

# ❌ Bad: Inconsistent or missing labels
metadata:
name: pod1
labels:
app: web

# ✅ Good: Consistent and comprehensive labels
metadata:
name: web-app-frontend-pod
labels:
app: web-app
component: frontend
version: v1.0
environment: production
team: frontend-team

Conclusion

Kubernetes fundamentals provide the foundation for understanding container orchestration. By understanding:

  • What Kubernetes is and its core concepts
  • Why it's essential for modern containerized applications
  • How its architecture and components work together

You can begin your journey into container orchestration. Kubernetes provides powerful abstractions for managing complex distributed systems, making it easier to deploy, scale, and maintain applications in production environments.

Next Steps

  • Practice with basic Kubernetes commands
  • Set up a local development cluster
  • Move on to Chapter 2: Installation & Setup

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