say.farewell.cloud admin

K8s Learning: Kubernetes Concepts Overview

Kubernetes Concepts for This Project

Script context: All deployment scripts (01–06)

This guide explains every Kubernetes concept used in the farewell.cloud deployment scripts. You already know Docker, DNS, TCP/IP, and reverse proxies — this builds directly on that foundation. Each concept is tied to its concrete role in getting a containerized app running on a single VM with automatic HTTPS.


The Big Picture

Architecture diagram

Every component in this diagram maps to a Kubernetes resource you will configure explicitly across the deployment scripts.


Core Kubernetes Concepts

Node

A node is a machine (physical or virtual) that runs Kubernetes workloads. In this setup, your single VM is your only node. In production clusters you'd have many nodes for redundancy and capacity.

Docker analogy: A node is the machine where docker run executes. One machine = one node.

Cluster

A cluster is the entire Kubernetes system — all nodes plus the control plane (API server, scheduler, controller manager). Even a single-node setup is a cluster. The command kubectl get nodes lists every node in the cluster.

Docker analogy: If Docker is a single engine on one machine, a cluster is a coordinated fleet of engines with a manager.

Pod

A pod is the smallest deployable unit in Kubernetes. It wraps one or more containers, giving them shared networking (same IP, same localhost) and storage. In this project, each pod runs exactly one container.

Pods are ephemeral — Kubernetes can destroy and recreate them at any time. This is why you never address a pod directly. Instead, you go through a Service.

Docker analogy: A pod is like docker run your-image, but managed. If the container crashes, Kubernetes automatically restarts it.

Deployment

A Deployment is a declarative specification: "I want N replicas of this container image running at all times." Kubernetes continuously reconciles reality with your declaration — if a pod crashes, a new one is created automatically.

Key fields you will configure:

  • replicas: 1 — run exactly one pod
  • image — which container image to use
  • imagePullPolicy: Never — don't pull from a registry; the image is pre-loaded locally
  • containerPort — the port your app listens on inside the container
Docker analogy: Like docker run --restart=always, but with rolling updates, rollbacks, and scaling built in.

Service

A Service gives pods a stable internal address. Pods get new IPs every time they restart, but a Service provides a consistent DNS name and port. Your Service maps port 80 → containerPort 8000.

Inside the cluster, anything can reach your app at http://your-service-name:80.

Docker analogy: A Service is like a DNS name for a container. Instead of remembering 172.17.0.5:8000, you just say http://my-app:80.

Ingress

An Ingress exposes a Service to the outside internet. It defines routing rules: "when someone visits say.farewell.cloud, send them to this Service."

An Ingress on its own is just a configuration object — it needs an Ingress Controller (Traefik, in this case) to actually do the routing. The Ingress also references a TLS secret for HTTPS.

Docker analogy: An Ingress is like an nginx reverse proxy config mapping domain names to backend containers — but declarative.

Namespace

A namespace organizes resources into logical groups. Your app runs in the default namespace. cert-manager runs in the cert-manager namespace. This prevents name collisions and keeps things tidy.


k3s-Specific Concepts

k3s — Lightweight Kubernetes

k3s is a lightweight Kubernetes distribution by Rancher, packaged as a single binary. A full Kubernetes install requires many components and significant resources; k3s delivers the same API with a fraction of the overhead — perfect for a single VM.

k3s bundles out of the box:

  • containerd — container runtime (replaces Docker in this stack)
  • Traefik — default Ingress Controller
  • CoreDNS — internal DNS for service discovery
  • SQLite — default datastore (full K8s uses etcd)

containerd and k3s ctr

containerd is the container runtime that actually runs your containers. The k3s ctr command is the CLI for interacting with it directly.

When you import a Docker image with k3s ctr -n k8s.io images import, you're loading it into containerd's image store. The -n k8s.io flag specifies the containerd namespace (not a Kubernetes namespace) — this is where k3s looks for images.

Docker analogy: k3s ctr images import is like docker load — it takes a tar file and makes the image available locally.

kubeconfig

The kubeconfig file (~/.kube/config) tells kubectl how to connect to your cluster — the API server address, authentication credentials, and the cluster CA certificate. k3s stores this at /etc/rancher/k3s/k3s.yaml on the VM.

Kubernetes API Server (port 6443)

The API server is the brain of the cluster. Every kubectl command is an HTTP request to this server on port 6443. Anyone with API access can control the entire cluster.

⚠️ Important: Restricting port 6443 via firewall to only your IP is critical. This is one of the first things the init script does.

TLS and Certificate Concepts

cert-manager

cert-manager is a Kubernetes add-on that automates the entire TLS certificate lifecycle: requesting, validating, issuing, storing, and renewing certificates from Let's Encrypt — all without manual intervention after initial setup.

ClusterIssuer

A ClusterIssuer defines how to obtain certificates. Yours is named letsencrypt-prod and says: "Use ACME with Let's Encrypt production, validate via HTTP-01 challenges, notify this email on expiry." Being cluster-wide, any Ingress in any namespace can reference it.

ACME and HTTP-01 Challenge

ACME (Automatic Certificate Management Environment) is the protocol Let's Encrypt uses:

Certificate flow
⚠️ Port 80 must be open for the HTTP-01 challenge. This is one reason the firewall allows port 80 even though your site uses HTTPS.

Certificate Lifecycle

Certificates are valid for 90 days. cert-manager automatically renews around 30 days before expiry. On first deploy, a new cert is obtained. On subsequent deploys, the existing cert is reused if still valid. Redeploying your app does not trigger re-issuance — only deleting the TLS secret or changing the domain would.


Infrastructure Concepts

Traefik (Ingress Controller)

Traefik is the reverse proxy bundled with k3s. It watches for Ingress resources and automatically configures routing. It also handles TLS termination — reading certificates from Kubernetes Secrets and serving HTTPS to clients.

Docker analogy: Traefik is like running an nginx container with auto-updating config. But instead of editing nginx.conf, you create Ingress objects.

UFW (Firewall)

  • Port 80 — open to world (ACME challenges + HTTP→HTTPS redirects)
  • Port 443 — open to world (HTTPS traffic)
  • Port 6443 — restricted to your IP only (Kubernetes API)

Volumes and hostPath

The deployment mounts a hostPath volume — mapping a directory on the VM's filesystem into the container. This provides persistent storage that survives pod restarts.

Docker analogy: Exactly like docker run -v /host/path:/container/path.

The Complete Request Flow

When a user visits https://say.farewell.cloud:

  1. DNS resolves the domain to the VM's public IP
  2. The request arrives on port 443; UFW allows it through
  3. Traefik receives the request and matches the hostname against Ingress rules
  4. Traefik terminates TLS using the certificate from the Kubernetes Secret
  5. Traefik forwards the request to the Service
  6. The Service routes to the running Pod
  7. Your container handles the request and responds
← Back to homepage