Pods, Deployments, Services, scaling, ConfigMaps, Ingress, Helm, and production best practices.
Welcome everyone! Today we're diving into Kubernetes Fundamentals, focusing on container orchestration for production workloads. Over the next few slides, we'll explore the core architecture of Kubernetes, understand its fundamental building blocks like Pods, Services, and Deployments, and walk through practical examples of deploying and managing applications at scale. Whether you're new to Kubernetes or looking to solidify your understanding, this session will give you the essential knowledge to run containerized workloads in production. Let's get started.
Let's start by understanding how Kubernetes is structured. As you can see in the diagram, Kubernetes follows a control plane and worker node architecture. The control plane at the top consists of four key components: the API Server in blue, which is the central management point for all cluster operations; the Scheduler in purple, which decides where pods should run; the Controller Manager in green, which maintains the desired state; and etcd in orange, the distributed key-value store that holds all cluster data. Below, we have two worker nodes, each running a kubelet that manages pods, and a kube-proxy that handles networking. The Scheduler communicates with the kubelets to place pods like Pod A, B, C, and D across the worker nodes. This separation of concerns allows Kubernetes to scale horizontally while maintaining centralized control.
Now let's look at the four core concepts you'll work with every day. First, the Pod — this is the smallest deployable unit in Kubernetes, containing one or more containers that share network and storage. Think of it as a wrapper around your containers. Second, Services provide a stable network endpoint that routes traffic to a set of Pods using label selectors, solving the problem of ephemeral pod IP addresses. Third, Deployments give you declarative updates for Pods, managing replicas, handling rollouts, and enabling rollbacks if something goes wrong. Finally, ConfigMaps let you inject configuration data into Pods, either as environment variables or mounted files, keeping your configuration separate from your container images. These four primitives form the foundation of almost every Kubernetes application.
Understanding the pod lifecycle is crucial for debugging. Looking at this flow diagram, a pod starts in the Pending state, then moves to Scheduled once the scheduler assigns it to a node. During ContainerCreating, the kubelet pulls images and starts containers. Once ready, the pod enters the Running state shown in green. From Running, a pod can transition to Succeeded if it completes successfully, or Failed in red if it crashes. Notice the CrashLoopBackOff state in dark red — this is what happens when a container repeatedly crashes. Kubernetes applies exponential backoff delays starting at ten seconds, then twenty, forty, up to five minutes before restarting. The callout box here is important: when you see CrashLoopBackOff, use kubectl logs with the previous flag to check logs from the crashed container. This will show you exactly what went wrong before the restart.
Let's see Deployments in action with a real example. Looking at this YAML file, we're defining a Deployment for an API server with three replicas. The selector uses the label app equals api to identify which pods belong to this deployment. The template section defines the pod specification, running a container with the image myapp slash api version two point one point zero, exposing port eighty eighty. Now watch what happens when we apply this with kubectl. The terminal output shows the deployment is created, and we can monitor the rollout status. Notice how it progresses: first one of three replicas is updated, then two, and finally all three are running. When we list the pods with the app equals api label, we see three pods all in Running status with the green indicator, each with a unique generated name. This is declarative infrastructure — we stated what we wanted, and Kubernetes made it happen.
Services solve the networking challenge in Kubernetes. This diagram shows how the three service types work together. At the top, internet traffic comes in through a LoadBalancer Service in blue, which creates a cloud load balancer. This routes to a NodePort Service in purple, which opens a port on every node between thirty thousand and thirty-two thousand seven sixty-seven. Finally, the ClusterIP Service in green provides an internal stable IP that load balances across Pod one, two, and three. Looking at the table, ClusterIP is internal only and used for pod-to-pod communication. NodePort exposes services externally via the node IP, mainly for dev and testing. LoadBalancer is your production solution for external traffic, creating a cloud load balancer automatically. And ExternalName creates a DNS alias for external services. Choose the right type based on whether you need internal or external access and whether you're in development or production.
Let's look at essential kubectl commands you'll use daily. First, kubectl cluster-info shows you where the control plane and core services like CoreDNS are running. The get pods command with all namespaces and wide output gives you a comprehensive view across your cluster. In this output, we see pods in the default namespace colored in cyan, like our api-server pods running on worker one and two, plus a prometheus pod in the monitoring namespace shown in yellow. The describe command is invaluable for debugging — here we're piping it through tail to see the last five events, showing the pod was scheduled, the image was pulled, and the container started successfully, all marked as Normal events in green. Finally, port-forward is perfect for local debugging. This command forwards local port eight thousand eighty to port eighty on the service, letting you test without exposing anything externally. These four commands will solve ninety percent of your day-to-day Kubernetes tasks.
Let's talk about scaling and health checks, which are critical for production reliability. The code on the left shows a HorizontalPodAutoscaler that automatically scales our deployment between three and twelve replicas based on CPU utilization, targeting seventy percent. Below that, we define two types of probes: readiness and liveness. Both hit the healthz endpoint on port eighty eighty. The readiness probe starts checking after five seconds — if it fails, the pod is removed from the service and won't receive traffic. The liveness probe runs every ten seconds — if it fails, Kubernetes restarts the container. The callout on the right clarifies the difference: readiness controls traffic routing, liveness controls container restarts. This is crucial to understand. Always set both probes, with readiness checking your application-level health like database connectivity, and liveness checking basic responsiveness like whether the process is still running. Without these, Kubernetes can't tell a healthy pod from a broken one.
Configuration management in Kubernetes uses ConfigMaps and Secrets. Looking at the ConfigMap YAML at the top, we're storing simple key-value pairs like DATABASE_HOST and LOG_LEVEL, plus a full config file under the config.yaml key using the pipe syntax for multiline strings. Below that, the Secret stores sensitive data like the database password and API key using stringData, which Kubernetes will base64 encode automatically. The Deployment snippet shows how to use both: envFrom injects all ConfigMap and Secret keys as environment variables, while volumeMounts lets you mount the ConfigMap as files at slash etc slash config. This gives you flexibility to use either approach. The important callout here: Secrets are only base64 encoded by default, not encrypted. For real security, enable encryption at rest in etcd, or better yet, use an external secrets manager like Vault or AWS Secrets Manager with an operator that syncs secrets into your cluster automatically.
Ingress controllers provide sophisticated HTTP routing. The diagram shows how this works: internet traffic hits a single Ingress Controller, which could be nginx or traefik, and it routes requests to different services based on paths. Requests to slash api go to the api service, the root path goes to the web service, and slash docs goes to the docs service. Looking at the Ingress YAML, we define host-based and path-based routing rules. The annotations configure nginx-specific features like SSL redirect and rate limiting. The TLS section references a secret containing our certificate for HTTPS. Each path maps to a backend service with specific ports. The callout explains the key benefit: a LoadBalancer Service creates one expensive cloud load balancer per service. An Ingress controller is one load balancer handling multiple services, which is far more cost-effective. Use Ingress for HTTP and HTTPS workloads, and only use LoadBalancer services for non-HTTP protocols like databases or gRPC that don't work with path-based routing.
Helm is the package manager for Kubernetes, and it dramatically simplifies deployment management. In the terminal, we first add the Prometheus community repository, then install a complete monitoring stack with a single command. Notice we can set values inline, like the Grafana admin password. Below that, we create our own chart with helm create, which generates a standard directory structure. The tree output shows Chart.yaml for metadata, values.yaml for default configuration, and a templates directory with deployment, service, and ingress templates. The callout at the bottom explains why Helm matters: instead of maintaining separate YAML files for dev, staging, and production, you define templates once and override values per environment. The upgrade command shows this in action, setting replica count and image tag inline, plus loading production-specific values from a file. Helm also handles rollbacks — if a deployment goes wrong, helm rollback restores the previous release instantly. This is essential for managing complex applications across multiple environments.
Monitoring is non-negotiable in production Kubernetes. The diagram shows how Prometheus scrapes metrics from multiple sources: your application pods expose a slash metrics endpoint, Node Exporter provides host-level metrics like CPU and memory, and kube-state-metrics exposes cluster-level data like pod and deployment status. Prometheus feeds into Alertmanager for notifications to Slack or PagerDuty, and Grafana for visualization. The ServiceMonitor YAML shows how you tell Prometheus what to scrape — it selects services with the app equals api label and scrapes the metrics port every fifteen seconds. The table shows five critical metrics to monitor: request rate for traffic patterns, error rate to catch failures where you should alert if it exceeds one percent for five minutes, P99 latency to catch performance degradation alerting above five hundred milliseconds, pod restarts to detect instability alerting on more than three per hour, and CPU usage to prevent resource exhaustion alerting above eighty percent of limits. These five metrics cover the fundamentals of Kubernetes observability.
Let's talk about the most common production mistakes that cause real outages. The warning callout emphasizes these are serious issues you need to address before going live. The first card: no resource limits. Without CPU and memory limits, one misbehaving pod can consume all node resources and starve every other pod. Always set both requests for scheduling and limits for enforcement. Second, missing health checks. Without readiness and liveness probes, Kubernetes has no idea if your containers are actually working, so traffic routes to broken pods and users see errors. Third, using the latest tag in production is a disaster because you lose reproducibility and rollbacks become impossible. Always pin specific image versions like two point one point zero. Finally, no Pod Disruption Budget means that during cluster upgrades or node maintenance, Kubernetes might take down all your replicas simultaneously, causing a complete outage. A PDB ensures a minimum number of pods stay running during voluntary disruptions. Learn from others' mistakes and avoid these four pitfalls from day one.
Let's look at how to organize a real Kubernetes project. While we don't have the detailed tree structure displayed here, a well-organized project typically separates manifests by environment, with directories for base configurations, overlays for environment-specific changes, and Helm charts if you're using them. You might have folders for development, staging, and production, each with their own values files. Configuration should live in a separate directory from application code, and secrets should never be committed to git — use sealed secrets or external secret management. Documentation belongs at the root level explaining how to deploy and manage the application. This structure makes it easy for team members to understand what's deployed where, and enables automation through CI CD pipelines. Good project organization is the difference between a maintainable system and a tangled mess of YAML files.
Let's wrap up with four key takeaways you should remember. First, pods are ephemeral by design. They come and go, they get rescheduled, they crash. Never manage pods directly — always use Deployments to get replicas, automated rollouts, and self-healing behavior. Second, Services provide stable networking. Pod IP addresses change constantly, so Services decouple service discovery from the pod lifecycle. Use ClusterIP for internal communication, NodePort for testing, and LoadBalancer for production traffic. Third, health checks are absolutely non-negotiable. Liveness and readiness probes are the only way Kubernetes knows if your application is actually working. Without them, you're flying blind. Finally, always set resource limits and use autoscaling. Define CPU and memory requests and limits on every pod to prevent resource starvation, then use Horizontal Pod Autoscalers to scale automatically with demand. These four principles will keep your Kubernetes deployments reliable and scalable in production. Thank you for joining this session on Kubernetes Fundamentals!
Hands-on implementation guides with detailed code examples, step-by-step instructions, and expanded explanations for each topic.