Containers transformed how software is packaged, but running hundreds of container instances across a distributed cluster of bare-metal or cloud servers introduced immense operational complexity: scheduling, self-healing, horizontal autoscaling, rolling upgrades, and network ingress.
Kubernetes (K8s), originally engineered by Google based on their internal Borg system, is the undisputed operating system of the modern cloud. In this architectural guide, we dissect the inner machinery of Kubernetes from a software developer's perspective, exploring Control Plane components, Pod lifecycles, Services, and Ingress routing.
1. The Control Plane vs Worker Node Topology
A Kubernetes cluster is divided into two distinct functional layers:
The Control Plane (The Brain)
- kube-apiserver: The central REST gateway. Every internal component and
kubectlcommand interacts through the API server. - etcd: A distributed, consistent, highly available key-value store holding the entire cluster state, configuration, and secret data.
- kube-scheduler: Evaluates resource requests (CPU/RAM) and constraints, assigning newly created Pods to optimal worker nodes.
- kube-controller-manager: Runs core control loops (Node Controller, Replication Controller, EndpointSlice Controller) ensuring the current state matches the desired state.
Worker Nodes (The Muscle)
- kubelet: The primary node agent that communicates with the API server, instructing the Container Runtime (containerd, CRI-O) to run containers.
- kube-proxy: Manages IP tables and IPVS routing rules on each node to distribute traffic to Pods across Services.
2. Pods, Deployments, and ReplicaSets
In Kubernetes, you never deploy containers directly. The smallest deployable unit is a Pod: a wrapper containing one or more tightly coupled containers sharing the same network namespace (IP address) and storage volumes.
apiVersion: apps/v1
kind: Deployment
metadata:
name: devinsights-api-deployment
labels:
app: devinsights-api
spec:
replicas: 3
selector:
matchLabels:
app: devinsights-api
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Allow 1 extra pod during rolling deploy
maxUnavailable: 0 # Zero downtime guarantee!
template:
metadata:
labels:
app: devinsights-api
spec:
containers:
- name: api-container
image: devinsights/api:v2.4.0
ports:
- containerPort: 8080
resources:
requests:
cpu: "250m" # 0.25 Core guaranteed
memory: "256Mi" # 256MB RAM guaranteed
limits:
cpu: "1000m" # 1 Core maximum
memory: "512Mi" # Hard kill (OOMKilled) if exceeded
readinessProbe:
httpGet:
path: /healthz/ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz/live
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
3. Service Discovery: ClusterIP, NodePort, and LoadBalancer
Pods are ephemeral: when a node crashes or autoscaling scales down, Pods are destroyed and recreated with completely new IP addresses. To provide a permanent, stable network address, Kubernetes uses Services:
- ClusterIP (Default): Exposes the Service on an internal cluster-only IP. Accessible only within the cluster.
- NodePort: Exposes the Service on a static high-range port (30000-32767) on every node's external IP address.
- LoadBalancer: Provisions an external cloud load balancer (AWS NLB/ALB, Google Cloud Network Load Balancer) forwarding external internet traffic to the service.
apiVersion: v1
kind: Service
metadata:
name: devinsights-api-service
spec:
type: ClusterIP
selector:
app: devinsights-api # Matches Pod template labels!
ports:
- port: 80 # Port exposed by the Service
targetPort: 8080 # Port listening inside the Container
4. Ingress: Layer 7 HTTP Routing and SSL Termination
Creating a separate cloud LoadBalancer for each microservice is prohibitively expensive. An Ingress Controller (e.g., NGINX Ingress, Traefik) acts as a unified Layer 7 reverse proxy, routing traffic based on hostnames and URI paths while terminating SSL certificates.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: devinsights-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- codingtutorials.site
secretName: codingtutorials-tls-cert
rules:
- host: codingtutorials.site
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: devinsights-api-service
port:
number: 80
Frequently Asked Questions (FAQ)
Q: What is the difference between Readiness and Liveness probes?
Liveness Probe: Checks if the container has crashed or deadlocked. If it fails, kubelet kills and restarts the container. Readiness Probe: Checks if the container is ready to accept incoming traffic (e.g., database connections established). If it fails, Kubernetes stops routing traffic to the Pod without restarting it.
Q: What happens when a container exceeds its resource memory limit?
If a container exceeds its CPU limit, Kubernetes throttles its CPU cycles (slowing execution). But if it exceeds its memory limit (limits.memory), the Linux kernel triggers an Out-Of-Memory kill (OOMKilled - Exit Code 137), terminating the pod immediately!
Conclusion
Kubernetes provides a declarative, resilient infrastructure platform for modern microservices. By defining explicit resource boundaries, configuring liveness and readiness health probes, and orchestrating ingress routing, developers ensure applications scale seamlessly across the global cloud.
💡 Engineering Key Takeaway
Always configure explicit CPU/memory requests and limits, and separate liveness from readiness probes to achieve seamless rolling deployments.
Practical Ingress Routing Manifest with Automated TLS
Configure automated HTTPS termination and host-based routing across multiple microservices:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: main-web-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- codingtutorials.site
secretName: codingtutorials-tls-cert
rules:
- host: codingtutorials.site
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-frontend-service
port:
number: 80
ConfigMaps & Secrets: Decoupling Configuration from Code
Never hardcode API keys, database credentials, or environment flags into container images. Kubernetes provides two native resources for configuration management:
- ConfigMaps: Store non-sensitive configuration parameters (such as log levels, service URLs, and feature flags) as key-value pairs or mounted configuration files.
- Secrets: Store base64-encoded sensitive data (such as database passwords, TLS certificates, and OAuth tokens). When mounted into pods, secrets appear as in-memory tmpfs files, preventing exposure to physical node disks.
Horizontal Pod Autoscaling (HPA) Based on Metrics
Under heavy traffic spikes, Kubernetes automatically scales the number of running pod replicas based on observed CPU utilization or custom application metrics:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-autoscaler
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-service-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70