Kubernetes

Reminders

  • HW2 due next week (10/23)
  • AWS invites were sent out last night, please look for these!
  • Will try to get HW1 grades out soon

Mid-Semester Feedback

qr code

https://forms.gle/wt35k9LgmHu47bGz8

Agenda

  1. Motivation for Kubernetes
  2. Kubernetes Concepts
  3. Managing Kubernetes with Manifests
  4. Helm

Motivation for Kubernetes

Docker Compose Recap

  • We've been using Docker Compose to run multiple containers locally
  • Define services in compose.yaml
  • Easy to run: docker compose up
  • Works great for local development!

Limitations of Docker Compose

Docker-compose is primarily meant for local development.

  • Single machine: All containers run on one host
  • No auto-recovery: If a container crashes, it stays down (unless configured)
  • No load balancing: Can't distribute traffic across multiple instances
  • No auto-scaling: Can't add more containers based on load
  • Limited networking: Simple bridge networks, no advanced routing

What if we want to...

  • Run containers across multiple machines?
  • Automatically restart failed containers?
  • Scale services up/down based on traffic?
  • Rolling updates without downtime?
  • Manage complex networking between services?
  • Handle secrets and configuration separately?

We need an orchestrator

Enter: Kubernetes

  • Kubernetes (K8s): Container orchestration platform
  • Originally developed by Google, now open source
  • Manages containerized applications across a cluster of machines
  • Provides:
    • Automatic scaling and load balancing
    • Self-healing (restarts failed containers)
    • Rolling updates and rollbacks
    • Service discovery and networking

k8s logo

Kubernetes Concepts

Kubernetes Architecture

  • Cluster: A set of machines running Kubernetes
  • Control Plane: Manages the cluster (scheduling, monitoring, etc.)
  • Nodes: Worker machines that run your containers

Kubernetes arch

Basic Building Blocks

Kubernetes introduces a some new concepts. The hierarchy from smallest to largest:

  1. Container: The Docker container (what we already know)
  2. Pod: One or more containers that share resources
  3. Node: A physical or virtual machine running pods
  4. Cluster: Multiple nodes managed together

Containers

  • The same Docker containers we've been using, nothing new here
  • Kubernetes doesn't replace Docker, it orchestrates it
  • Each container runs a single process

Pods

  • Pod: The smallest deployable unit in Kubernetes
  • Contains one or more containers that should run together
  • Containers in a pod:
    • Share the same network namespace (can talk via localhost)
    • Share storage volumes
    • Are always scheduled on the same node
    • Effectively running multiple docker containers on one machine

Why might we need Pods?

Why Pods?

Single Container Pod (common)

  • Most pods have one container
  • The container is your application

Multi-Container Pod (less common)

  • Main application container
  • "Sidecar" containers that support it
    • Log collector
    • Proxy
    • Monitoring agent

Nodes

  • Node: A worker machine in the cluster
  • Can be physical or virtual
  • Each node runs:
    • kubelet: Agent that manages pods on the node
    • Container runtime: Docker or other container engine
    • kube-proxy: Handles networking
  • One node can run many pods

Nodes

k8s node

K8s: Managing Resources

  • We typically want to orchestrate how nodes/pods are deployed or managed
  • Kubernetes provides abstractions for workload management, networking, and configuration
    • Deployments are ways to define a group of pods and their lifecycle
    • Services provide stable endpoints for a group of pods
    • ConfigMaps decouple configuration from containers
    • Many more...

Deployments

  • Deployment: Manages a set of identical pods
  • You specify:
    • Which container image to run
    • How many replicas (copies) you want
    • Resource limits (CPU, memory)
  • Kubernetes ensures the desired state is maintained
    • If a pod dies, Deployment creates a new one
    • If you update the image, Deployment performs a rolling update

Deployments: Example

  1. replicas: 3
  2. image: myapp:v1.0
  • Kubernetes will ensure 3 pods are always running
  • If one crashes, a new one is created automatically
  • If you change to myapp:v2.0, Kubernetes rolls out the update

Services

  • Problem: Pods are ephemeral and have no stable endpoint/IP
  • Solution: A Service provides a stable endpoint for a set of pods
  • Services handle load balancing across pods
  • Other pods/services use the Service name for discovery
  • This is similar to how docker-compose provided a named endpoint

Other Kubernetes Resources

  • ConfigMap: Store configuration data (environment variables, config files)
  • Secret: Store sensitive data (passwords, API keys)
  • Volume: Persistent storage that survives pod restarts
  • Namespace: Virtual cluster for organizing resources
  • Ingress: Manage external HTTP(S) access to services

We'll explore these as needed

Managing with Manifests

yaml meme

Declarative Configuration

  • In Docker Compose, we declared what we wanted in YAML
  • Kubernetes works the same way!
  • We write YAML files called manifests that describe our desired state
  • We apply these manifests to the cluster
  • Kubernetes makes the actual state match the desired state
  • These manifests can typically get very large, though...

manifest

Anatomy of a Manifest

Every Kubernetes manifest has:

  1. apiVersion: v1 # Which K8s API version
  2. kind: Pod # What type of resource
  3. metadata: # Info about the resource
  4. name: my-pod
  5. labels:
  6. app: myapp
  7. spec: # The desired state
  8. # Details depend on the resource type

Example: Pod Manifest

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: nginx-pod
  5. spec:
  6. containers:
  7. - name: nginx
  8. image: nginx:1.21
  9. ports:
  10. - containerPort: 80

This defines a pod with a single nginx container

Example: Deployment Manifest

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: nginx-deployment
  5. spec:
  6. replicas: 3
  7. selector:
  8. matchLabels:
  9. app: nginx
  10. template:
  11. metadata:
  12. labels:
  13. app: nginx
  14. spec:
  15. containers:
  16. - name: nginx
  17. image: nginx:1.21

Example: Service Manifest

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: nginx-service
  5. spec:
  6. selector:
  7. app: nginx
  8. ports:
  9. - protocol: TCP
  10. port: 80
  11. targetPort: 80
  12. type: LoadBalancer

Applying Manifests

Kubernetes is managed through the command line tool kubectl

  1. # Apply a single manifest
  2. kubectl apply -f deployment.yaml
  3. # Apply all manifests in a directory
  4. kubectl apply -f ./manifests/
  5. # View resources
  6. kubectl get pods
  7. kubectl get deployments
  8. kubectl get services

Minikube

How do we test manifests?

  • Minikube: Tool for running Kubernetes locally
  • Creates a single-node cluster on your machine
  • Perfect for learning and development
  • Works similar to production Kubernetes
  1. minikube start # Start local cluster
  2. minikube stop # Stop cluster
  3. minikube delete # Delete cluster

The Problem with Manifests

  • For a real application, you might have:
    • 5 deployments
    • 5 services
    • Multiple ConfigMaps and Secrets
    • Different configurations for dev/staging/prod
  • Managing dozens of YAML files gets messy
  • How do we handle environment-specific values?

Helm

What is Helm?

  • Helm: Package manager for Kubernetes
  • Think npm or apt, but for Kubernetes applications
  • Bundles related manifests into a Chart
  • Provides templating for environment-specific configuration
  • The real power comes from being able to define custom templates

Helm Charts

  • A Chart is a collection of Kubernetes manifests
  • Think of a chart as a template
  • Organized in a specific directory structure:

Templating with Helm

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: {{ .Values.appName }}
  5. spec:
  6. replicas: {{ .Values.replicaCount }}
  7. template:
  8. spec:
  9. containers:
  10. - name: app
  11. image: {{ .Values.image.repository }}:{{ .Values.image.tag }}

Values come from a provided values.yaml (can be named differently)

values.yaml

  1. appName: myapp
  2. replicaCount: 3
  3. image:
  4. repository: myapp
  5. tag: v1.0.0
  6. resources:
  7. limits:
  8. memory: "256Mi"
  9. cpu: "500m"

Environment-Specific Configuration

We can create clean separations per environment using values!

values-dev.yaml

  1. replicaCount: 1
  2. image:
  3. tag: latest
  4. resources:
  5. limits:
  6. memory: "128Mi"

values-prod.yaml

  1. replicaCount: 5
  2. image:
  3. tag: v1.0.0
  4. resources:
  5. limits:
  6. memory: "512Mi"
  1. helm install myapp ./mychart -f values-dev.yaml
  2. helm install myapp ./mychart -f values-prod.yaml

Benefits of Helm

  • Package multiple resources: One chart = complete application
  • Templating: Reuse manifests across environments
  • Versioning: Track chart versions, easy rollbacks
  • Sharing: Publish charts to repositories for others to use
  • Dependency management: Charts can depend on other charts

Helm Commands

  1. # Install a chart
  2. helm install myapp ./mychart
  3. # Upgrade an installation
  4. helm upgrade myapp ./mychart
  5. # List installations
  6. helm list
  7. # Rollback to previous version
  8. helm rollback myapp
  9. # Uninstall
  10. helm uninstall myapp

Summary

  • Kubernetes provides powerful abstractions for container orchestration
    • Pods, Deployments, Services abstract away infrastructure complexity
    • Manifests let us declare desired state
  • Helm helps manage complexity with templating
  • In the future: how do we integrate Kubernetes with cloud providers

Lab: Minikube & Helm

Note: Add icon/diagram of a container

Note: Add diagram showing a pod with 2-3 containers inside

Note: Add diagram showing node with multiple pods inside

Note: Add diagram showing deployment with 3 pod replicas

Note: Add diagram showing service routing to multiple pods