Skip to content

Portal | Level: L0: Entry | Topics: Kubernetes Concept Chain, Kubernetes Core | Domain: Kubernetes

Kubernetes Concept Chain - Primer

Why This Matters

Kubernetes has dozens of resource types. Beginners memorize definitions. Operators understand why each one exists — what problem it solves that the previous layer couldn't. This primer walks through the concept chain: each abstraction exists because the one before it wasn't enough.

If you understand the chain, you can predict what Kubernetes will do before you read the docs.


The Chain

1. Pod — Run Your Container

You have a container image. You need it running somewhere. A pod wraps your container and runs it on a node.

apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  containers:
    - name: web
      image: nginx:1.27
      ports:
        - containerPort: 80

The problem: the pod crashes and nobody restarts it. It is just gone.


2. Deployment — Keep It Running

A Deployment declares how many replicas you want. One pod dies, another comes back. You want 3 running, it keeps 3 running.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:1.27
          ports:
            - containerPort: 80

Under the hood, a Deployment creates a ReplicaSet. The ReplicaSet owns the pods. The Deployment manages ReplicaSets for rolling updates — it spins up a new ReplicaSet with the updated spec while scaling down the old one.

The problem: every pod gets a new IP when it restarts. Other services need to talk to your app, but the IPs keep changing. You cannot hardcode them at scale.


3. Service — Stable Networking

A Service provides one stable IP (ClusterIP) that always finds your pods using label selectors, not IPs. Pods die and come back. The Service does not care.

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 80

Now other pods reach your app at web.<namespace>.svc.cluster.local:80.

The four Service types, in order of exposure:

Type Scope Use case
ClusterIP Cluster-internal only Default. Backend services.
NodePort Every node IP at port 30000-32767 Dev/testing, bare-metal.
LoadBalancer External cloud LB provisioned Production external traffic.
ExternalName DNS CNAME redirect Alias for external services.

The problem: you have 10 services and 10 LoadBalancers. Your cloud bill doesn't care that 6 of them handle almost no traffic.


4. Ingress — One Load Balancer, Many Services

Ingress defines routing rules: hostname + path to service. One load balancer, all services behind it, smart Layer-7 routing.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
spec:
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web
                port:
                  number: 80
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api
                port:
                  number: 80

The problem: Ingress is just rules. Nobody executes them without an Ingress Controller.


5. Ingress Controller — Make the Rules Work

An Ingress Controller watches for Ingress resources and configures itself to actually route traffic. Popular choices:

Controller Notes
ingress-nginx Community NGINX-based, most common
Traefik Auto-discovery, Let's Encrypt built in
AWS Load Balancer Controller Provisions ALB/NLB natively
Contour Envoy-based, projectcontour.io

Without an Ingress Controller running in the cluster, Ingress resources do nothing. This is the single most common "Ingress doesn't work" mistake.


6. ConfigMap — Externalize Configuration

Hardcoding config inside the container means wrong database in staging, wrong API key in production, and rebuilding the image every time config changes.

A ConfigMap stores configuration outside the container. The same image runs in dev, staging, and production with different configs injected at runtime.

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DATABASE_HOST: "db.production.internal"
  LOG_LEVEL: "info"
  FEATURE_FLAGS: "dark-mode=true,beta-api=false"
---
# Reference in Deployment
env:
  - name: DATABASE_HOST
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: DATABASE_HOST

The problem: your database password is sitting in a ConfigMap unencrypted. Anyone with basic kubectl access can read it.


7. Secret — Sensitive Data, Stored Separately

Secrets store sensitive data (passwords, tokens, TLS certs) with separate RBAC controls. They are base64-encoded by default — not encrypted at rest unless you enable encryption at the API server level.

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  password: cGFzc3dvcmQxMjM=    # base64 of "password123"
---
# Reference in Deployment
env:
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-credentials
        key: password

For real secret management, integrate with an external provider: - AWS Secrets Manager + External Secrets Operator - HashiCorp Vault + Vault Secrets Operator - GCP Secret Manager + Config Connector


8. HPA — Automatic Horizontal Scaling

Some days 100 users, some days 10,000. Manual scaling means pods sit idle at night or crash under load at peak.

HPA (Horizontal Pod Autoscaler) watches metrics and adjusts replica count automatically.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

CPU crosses 70% and pods are added. Traffic drops and they scale back down.

The problem: HPA creates pods, but your nodes are full. New pods sit in Pending state. HPA did its job — your cluster had nowhere to put the pods.


9. Cluster Autoscaler / Karpenter — Scale the Nodes

When pods are stuck Pending because no node has capacity, you need node-level autoscaling.

Tool Approach
Cluster Autoscaler Adjusts node group size. Works with ASGs/MIGs. Slower.
Karpenter Provisions right-sized nodes directly. Faster. AWS-native.

Karpenter sees pods stuck Pending, launches a node that fits, and removes it when load drops. You only pay for what you actually use.

The problem: a pod starts consuming 4GB of memory with no limits set. It starves every other pod on the node. One rogue pod takes down everything around it.


10. Resource Requests and Limits — Predictable Scheduling

Requests tell Kubernetes the minimum resources a pod needs to be scheduled. Limits cap what it can consume. Together they prevent resource starvation.

resources:
  requests:
    cpu: 250m        # Guaranteed minimum: 0.25 CPU
    memory: 256Mi    # Guaranteed minimum: 256 MB
  limits:
    cpu: 1000m       # Hard cap: 1 CPU
    memory: 512Mi    # Hard cap: 512 MB (OOMKilled if exceeded)
Field Purpose What happens without it
requests.cpu Scheduling guarantee Pod scheduled on overcommitted node
requests.memory Scheduling guarantee Same — memory contention under load
limits.cpu Throttling cap Pod consumes entire node CPU
limits.memory OOM kill threshold Pod grows until node OOM killer fires

QoS classes follow directly from how you set requests and limits:

QoS Class Condition Eviction priority
Guaranteed requests == limits for all containers Last to be evicted
Burstable requests < limits (or only requests set) Middle
BestEffort No requests or limits set First to be evicted

The Complete Chain

Container crashes → Deployment (self-healing replicas)
IPs keep changing → Service (stable endpoint)
Too many LBs      → Ingress (shared routing)
Rules need engine  → Ingress Controller
Config in image    → ConfigMap (external config)
Passwords exposed  → Secret (sensitive data)
Manual scaling     → HPA (auto-scale pods)
Nodes full         → Karpenter (auto-scale nodes)
Rogue resource use → Requests & Limits (predictable scheduling)

Every concept exists because the previous layer had an unresolved problem. Understanding the chain means you can predict what K8s resource to reach for when you hit a new problem.


Quick Reference

Concept One-liner Key command
Pod Runs your container kubectl get pods
Deployment Keeps N replicas alive kubectl rollout status deploy/NAME
Service Stable IP for a set of pods kubectl get svc
Ingress L7 routing rules kubectl get ingress
Ingress Controller Executes Ingress rules kubectl get pods -n ingress-nginx
ConfigMap Non-sensitive config kubectl get configmap NAME -o yaml
Secret Sensitive config kubectl get secret NAME -o jsonpath='{.data.key}'
HPA Auto-scale pods on metrics kubectl get hpa
Karpenter Auto-scale nodes kubectl get nodeclaims
Requests/Limits Resource guarantees/caps kubectl describe pod NAME

Wiki Navigation