Skip to main content
DevopsIntermediate18 min readUpdated March 2025

Pods, Deployments & Services

Pods, Deployments, and Services are the three most fundamental Kubernetes objects. Pods run containers, Deployments manage Pod lifecycle and rolling updates, and Services provide stable network access to a set of Pods.

Pods: The Smallest Deployable Unit

A Pod is the smallest and simplest Kubernetes object. It represents a single instance of a running process in your cluster.

Key characteristics: - A Pod can contain one or more containers that share the same network namespace (same IP, same ports) and storage volumes - Containers in a Pod communicate via localhost - Pods are ephemeral — they are created and destroyed, never repaired. If a Pod dies, Kubernetes creates a new one (with a new IP) - Pods are scheduled to a single node and cannot span multiple nodes

In practice, you rarely create Pods directly. You use higher-level controllers (Deployments, StatefulSets) that manage Pods for you.

Deployments: Managing Pod Replicas

A Deployment is a higher-level object that manages a set of identical Pods (replicas). It provides:

- Desired state management — Ensures the specified number of Pod replicas are always running - Rolling updates — Gradually replace old Pods with new ones (zero downtime) - Rollback — Instantly revert to a previous version if something goes wrong - Self-healing — Automatically replaces failed or evicted Pods

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  replicas: 3                        # Run 3 identical Pods
  selector:
    matchLabels:
      app: web-app                   # Manage Pods with this label
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1                    # Max extra Pods during update
      maxUnavailable: 0              # Zero downtime: never kill before new is ready
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web-app
        image: myrepo/web-app:2.1
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
        readinessProbe:              # Only send traffic when ready
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:               # Restart if unhealthy
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 15
          periodSeconds: 20

Services: Stable Network Access

Pods are ephemeral — they come and go, and each new Pod gets a new IP address. A Service provides a stable IP address and DNS name that load-balances traffic across a set of Pods.

Service types:

  • ClusterIP (default) — Exposes the service on an internal cluster IP. Only reachable from within the cluster. Use for internal microservice communication.
  • NodePort — Exposes the service on each node's IP at a static port (30000-32767). Accessible from outside the cluster via NodeIP:NodePort.
  • LoadBalancer — Provisions an external load balancer from the cloud provider (AWS ELB, GCP LB). The standard way to expose services to the internet.
  • ExternalName — Maps the service to a DNS name (e.g., an external database). Returns a CNAME record.

Service YAML and DNS

Services use label selectors to find their target Pods. Kubernetes automatically creates DNS entries for every Service:

yaml
# ClusterIP Service (internal)
apiVersion: v1
kind: Service
metadata:
  name: web-app-service
  namespace: production
spec:
  type: ClusterIP
  selector:
    app: web-app              # Routes to Pods with this label
  ports:
  - protocol: TCP
    port: 80                  # Service port (what clients connect to)
    targetPort: 3000          # Container port (where app listens)

---
# LoadBalancer Service (external, cloud)
apiVersion: v1
kind: Service
metadata:
  name: web-app-lb
spec:
  type: LoadBalancer
  selector:
    app: web-app
  ports:
  - port: 80
    targetPort: 3000

# DNS: web-app-service.production.svc.cluster.local
# Short form within same namespace: web-app-service

ConfigMaps and Secrets

ConfigMaps store non-sensitive configuration data as key-value pairs. Secrets store sensitive data (passwords, tokens, keys) in base64-encoded form (with encryption at rest in production).

Both can be injected into Pods as environment variables or mounted as files.

yaml
# ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  APP_ENV: "production" LOG_LEVEL:"info" MAX_CONNECTIONS:"100"

---
# Secret (values are base64 encoded)
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  password: cGFzc3dvcmQxMjM=   # base64("password123")
  username: YWRtaW4=            # base64("admin")

# Create secret from command line (auto base64 encodes):
# kubectl create secret generic db-secret #   --from-literal=password=password123 #   --from-literal=username=admin

Key Takeaways

  • Pods are ephemeral — never create them directly; use Deployments to manage their lifecycle.
  • Deployments provide rolling updates, rollback, and self-healing for stateless applications.
  • Services provide a stable IP/DNS name that load-balances traffic across matching Pods via label selectors.
  • Use ClusterIP for internal services, LoadBalancer for internet-facing services.
  • ConfigMaps store non-sensitive config; Secrets store sensitive data — both inject into Pods as env vars or files.

Contact Us

Have a question or feedback? Fill out the form below or reach us directly at support@nvaitraining.com