Kubernetes orchestrates containers using a set of core objects: Pods, Deployments, and ReplicaSets. Understanding how these relate to each other is fundamental to working with GKE.

Resource Hierarchy

flowchart TD
    D["Deployment"] --> RS["ReplicaSet"]
    RS --> P1["Pod 1"]
    RS --> P2["Pod 2"]
    RS --> P3["Pod 3"]
    P1 --> C1["Container"]
    P2 --> C2["Container"]
    P3 --> C3["Container"]
LevelWhat It DoesManaged By
DeploymentDeclares desired state, manages rollout strategyYou (via kubectl or YAML)
ReplicaSetEnsures the correct number of pod replicas are runningDeployment controller
PodRuns one or more containers with shared network/storageReplicaSet controller
ContainerYour actual application imagePod lifecycle

Key Insight: You almost always interact with Deployments, not ReplicaSets directly. The Deployment creates and manages the ReplicaSet for you.

Pods

A Pod is the smallest deployable unit in Kubernetes. It encapsulates one or more containers that share the same network namespace (IP address) and storage volumes.

Pod Structure

apiVersion: v1
kind: Pod
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  containers:
    - name: app
      image: nginx:1.25
      ports:
        - containerPort: 80
      resources:
        requests:
          cpu: "100m"      # 0.1 vCPU
          memory: "128Mi"
        limits:
          cpu: "500m"      # 0.5 vCPU
          memory: "256Mi"
  restartPolicy: Always

Key Pod Concepts

ConceptDescription
EphemeralPods are not self-healing. If a pod dies, a new one is created (by a controller)
Single IPAll containers in a pod share one IP address
Co-locatedAll containers in a pod run on the same node
Shared storageContainers in a pod can share volumes
Resource requests/limitsDefine CPU/memory needs for scheduling and QoS

Tip: Use one container per pod unless you have a tightly-coupled sidecar (like a logging agent). Multi-container pods share the same lifecycle — they start, stop, and scale together.

Pod Lifecycle

Pending → Running → Succeeded/Failed
                 ↘ CrashLoopBackOff (repeated failures)
PhaseMeaning
PendingPod accepted but not yet running (scheduling or image pull)
RunningAt least one container is still running
SucceededAll containers completed successfully (batch jobs)
FailedAt least one container terminated with an error
UnknownPod state cannot be determined (usually node communication issue)

Common Pod Commands

# List pods
kubectl get pods
kubectl get pods -o wide         # with node and IP info
kubectl get pods --show-labels   # show labels
 
# Pod details
kubectl describe pod POD_NAME
 
# Pod logs
kubectl logs POD_NAME
kubectl logs POD_NAME -c CONTAINER_NAME   # specific container
kubectl logs POD_NAME --previous          # previous crashed container
 
# Execute commands inside a pod
kubectl exec -it POD_NAME -- /bin/bash
 
# Delete a pod (controller will recreate it)
kubectl delete pod POD_NAME

Deployments

A Deployment manages a ReplicaSet and provides declarative updates for Pods. It handles rollout strategy, rollback, and scaling.

Deployment YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1         # allow 1 extra pod during rollout
      maxUnavailable: 0   # keep all existing pods running
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: nginx:1.25
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "256Mi"

Deployment Strategies

StrategyHow It WorksWhen to Use
RollingUpdate (default)Gradually replaces old pods with new onesMost production deployments
RecreateKills all old pods before starting new onesWhen you cannot run old and new versions simultaneously
flowchart LR
    subgraph RollingUpdate
        direction TB
        R1["v1: 3 pods"] --> R2["v1: 2 pods, v2: 1 pod"] --> R3["v1: 1 pod, v2: 2 pods"] --> R4["v2: 3 pods"]
    end

    subgraph Recreate
        direction TB
        C1["v1: 3 pods"] --> C2["0 pods"] --> C3["v2: 3 pods"]
    end

Deployment Commands

# Create a deployment
kubectl create deployment my-app --image=nginx:1.25 --replicas=3
 
# Apply from YAML
kubectl apply -f deployment.yaml
 
# Check rollout status
kubectl rollout status deployment/my-app
 
# View rollout history
kubectl rollout history deployment/my-app
 
# Rollback to previous version
kubectl rollout undo deployment/my-app
 
# Rollback to specific revision
kubectl rollout undo deployment/my-app --to-revision=2
 
# Scale a deployment
kubectl scale deployment my-app --replicas=5
 
# Update the container image (triggers rollout)
kubectl set image deployment/my-app app=nginx:1.26
 
# Edit the deployment directly
kubectl edit deployment my-app

How Deployments Manage Rollouts

sequenceDiagram
    participant User
    participant Deployment
    participant ReplicaSet as New ReplicaSet
    participant OldRS as Old ReplicaSet

    User->>Deployment: Update image to v2
    Deployment->>ReplicaSet: Create with v2 image
    ReplicaSet->>ReplicaSet: Scale up to 1 pod
    Deployment->>OldRS: Scale down to 2 pods
    ReplicaSet->>ReplicaSet: Scale up to 2 pods
    Deployment->>OldRS: Scale down to 1 pod
    ReplicaSet->>ReplicaSet: Scale up to 3 pods
    Deployment->>OldRS: Scale down to 0 pods
    Note over Deployment: Rollout complete

Key Insight: Each time you update a Deployment, a new ReplicaSet is created. Old ReplicaSets are kept (scaled to zero) for rollback. This is why kubectl rollout undo works.

ReplicaSets

A ReplicaSet ensures a specified number of pod replicas are running at all times. In practice, you rarely create ReplicaSets directly — Deployments manage them for you.

ReplicaSet YAML (rarely used directly)

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-app-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: nginx:1.25

Deployment vs ReplicaSet vs Pod

AspectDeploymentReplicaSetPod
PurposeDeclarative updates and rolloutsMaintain replica countRun containers
Self-healingYes (via ReplicaSet)Yes (recreates failed pods)No
Rolling updatesYesNo (creates new RS manually)No
RollbackYesNoNo
ScalingYes (kubectl scale)YesNo
Use directly?Yes — primary workload objectRarely — let Deployments manage themRarely — let controllers manage them

Labels and Selectors

Labels and selectors are the glue that connects Kubernetes objects:

# Deployment has a selector
spec:
  selector:
    matchLabels:
      app: my-app       # This must match the pod template labels
 
# Pod template has labels
  template:
    metadata:
      labels:
        app: my-app     # This must match the deployment selector

Warning: The selector in a Deployment is immutable after creation. You cannot change which pods a Deployment manages. If you need different labels, create a new Deployment.

Common Label Conventions

LabelPurposeExample
appApplication nameapp: my-app
versionApplication versionversion: v2
tierArchitecture tiertier: frontend
environmentDeployment environmentenvironment: production

Probes

Probes let Kubernetes check the health of containers in a pod:

Probe TypePurposeFailure Result
livenessProbeIs the container still running correctly?Kubernetes restarts the container
readinessProbeCan the container serve traffic?Pod is removed from Service endpoints
startupProbeHas the container finished starting?Liveness/readiness probes delayed until success
containers:
  - name: app
    image: nginx:1.25
    livenessProbe:
      httpGet:
        path: /healthz
        port: 80
      initialDelaySeconds: 15
      periodSeconds: 10
    readinessProbe:
      httpGet:
        path: /ready
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5

Tip: Always define a readiness probe. Without it, Kubernetes sends traffic to pods that may not be ready to serve requests.

Common Commands Summary

CommandPurpose
kubectl get podsList all pods
kubectl describe pod NAMEDetailed pod information and events
kubectl logs NAMEView pod logs
kubectl exec -it NAME -- bashShell into a container
kubectl get deploymentsList deployments
kubectl rollout status deploy/NAMEWatch rollout progress
kubectl rollout undo deploy/NAMERollback to previous version
kubectl scale deploy/NAME --replicas=NScale deployment
kubectl set image deploy/NAME container=image:tagUpdate container image
kubectl get rsList ReplicaSets
kubectl get events --sort-by='.lastTimestamp'View recent cluster events

TL;DR

  • Pods run containers — they are ephemeral and not self-healing on their own
  • ReplicaSets maintain a desired number of pod replicas — rarely used directly
  • Deployments manage ReplicaSets and provide rolling updates and rollbacks — the primary workload object
  • Always define resource requests and limits and readiness probes
  • Use kubectl apply -f for declarative management; avoid imperative commands in production
  • Labels and selectors connect Deployments to Pods — get them right

Resources