Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Scale a Deployment Manually

Learn to scale a Kubernetes Deployment manually — practical step-by-step guide for controlling replica count, with tips on when to use manual scaling vs autoscaling.

Focus: scale a deployment manually

Sponsored

You've deployed your application to Kubernetes, and it's running — but now traffic spikes, and your single pod can't keep up. Without the ability to add or remove replicas on demand, your app becomes a bottleneck. Scaling a deployment manually is the fastest, most direct way to control how many pod replicas serve your traffic, and it's a skill you'll use constantly when managing production workloads.

The Problem This Lesson Solves

A Kubernetes Deployment guarantees a desired state — for example, "I want 3 replicas of my nginx server running." When that desired state is too low (or too high), your application suffers.

  • Too few replicas → request timeouts, high latency, 503 errors.
  • Too many replicas → wasted compute resources, unnecessary cloud costs.

Manual scaling gives you immediate control. No waiting for metrics to trigger autoscaling — you, the operator, decide the replica count right now. This is essential for: - Handling predictable traffic spikes (e.g., Black Friday, product launches). - Performing rolling updates with safety buffers. - Testing how your app behaves under different load levels.

But scaling isn't just about changing numbers — it's about understanding what changes, how it happens, and when to use it over other strategies.

Core Concept / Mental Model

Think of a Deployment as a host managing a flock of identical birds (your pods). Each bird does exactly the same job — handling requests equally.

  • Manual scaling = you tell the host: "I need 5 birds right now. Not 4, not 6 — exactly 5."
  • The host immediately sends out or recalls birds to hit that exact count.

Under the hood, the Deployment interacts with a ReplicaSet — the component responsible for creating and destroying pods. When you scale a Deployment, you update its replicas field. The Deployment controller then adjusts the ReplicaSet's desired size, which in turn creates or terminates pods.

Pro Tip: Manual scaling is declarative. You set the desired replica count, and Kubernetes converges toward that state. If a pod crashes, Kubernetes will recreate it to maintain the desired number — scaling is about the target count, not just the initial count.

Key Definitions

  • ReplicaSet: An older API object (still used internally) that ensures a specific number of identical pods are running.
  • Desired replicas: The value specified in spec.replicas in the Deployment YAML.
  • Current replicas: The actual number of pods running at any moment.

How It Works Step by Step

When you scale a Deployment manually, Kubernetes performs a predictable sequence:

  1. You issue a scale command — either via kubectl scale, by editing the YAML file, or through a dashboard.
  2. The Deployment controller receives the update and checks the new spec.replicas value.
  3. The Deployment updates its underlying ReplicaSet to match the new desired count.
  4. The ReplicaSet controller calculates the difference between desired and current pod count: - If desired > current → creates new pods using the pod template. - If desired < current → terminates excess pods gracefully (with terminationGracePeriodSeconds).
  5. Pods are scheduled onto available nodes (or terminated).
  6. The Deployment status shows updated readyReplicas and availableReplicas.

The entire process takes seconds for stateless apps, but can take longer if container images need pulling or if resource limits prevent scheduling.

Blockquote Pro Tip: Scaling down (reducing replicas) terminates pods in no particular order by default. Use pod-management-policy: OrderedReady (for StatefulSets) if you need ordered termination, but for Deployments, it's typically fine to let Kubernetes pick.

Hands-On Walkthrough

Let's practice manual scaling with a real nginx Deployment. We'll start without any YAML and use imperative commands, then move to declarative YAML.

Prerequisites

  • A running Kubernetes cluster (minikube, kind, or cloud cluster). -namespace created (we'll use default for simplicity).

Step 1: Create a Deployment (1 replica)

kubectl create deployment nginx-demo --image=nginx:alpine --replicas=1
kubectl get deployments

Expected output:

NAME         READY   UP-TO-DATE   AVAILABLE   AGE
nginx-demo   1/1     1            1           5s

Step 2: Scale up to 3 replicas

kubectl scale deployment nginx-demo --replicas=3
kubectl get pods

Expected output:

NAME                          READY   STATUS    RESTARTS   AGE
nginx-demo-7f7c6c7b4c-abc12   1/1     Running   0          12s
nginx-demo-7f7c6c7b4c-def34   1/1     Running   0          3s
nginx-demo-7f7c6c7b4c-ghi56   1/1     Running   0          3s

Notice two new pods appeared within seconds.

Step 3: Scale down to 2 replicas

kubectl scale deployment nginx-demo --replicas=2
kubectl get pods

One pod disappears (terminated gracefully).

Step 4: Scaling via YAML (declarative)

Create a file deployment-scaled.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-demo
spec:
  replicas: 5
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - name: nginx
        image: nginx:alpine

Apply the change:

kubectl apply -f deployment-scaled.yaml
kubectl get deployments nginx-demo

Expected output:

NAME         READY   UP-TO-DATE   AVAILABLE   AGE
nginx-demo   5/5     5            5           2m

Blockquote Pro Tip: kubectl scale is imperative and convenient, but for reproducibility, always version your YAML files and use kubectl apply to keep your cluster in sync with your source of truth.

Step 5: Verify with kubectl describe

kubectl describe deployment nginx-demo | grep -E "Replicas|ReplicaSet:"

Sample output:

Replicas:               5 desired | 5 updated | 5 total | 5 available | 0 unavailable
OldReplicaSets:         <none>
NewReplicaSet:          nginx-demo-7f7c6c7b4c (5/5 replicas created)

Compare Options / When to Choose What

Approach Command / Method When to Use Pros Cons
Imperative kubectl scale kubectl scale deploy/name --replicas=X Quick ad-hoc changes, testing Fast, no file edits Not idempotent, harder to audit
Declarative YAML edit & apply kubectl edit deployment name or kubectl apply -f file.yaml Production changes, CI/CD pipelines Reproducible, version-controlled Slightly heavier workflow
Horizontal Pod Autoscaler (HPA) kubectl autoscale deployment name --min=X --max=Y Dynamic traffic, variable load Auto-scales, no manual intervention Requires metrics server, more complex

When to scale manually: - You know the exact load profile (e.g., scheduled batch jobs). - You're debugging and need deterministic replica count. - You want full control over cost vs. performance trade-offs.

When to use HPA: - Unpredictable traffic patterns. - You want to avoid under- or over-provisioning automatically. - You have metrics (CPU, memory, custom) available.

Troubleshooting & Edge Cases

Pods Not Scaling Up

  • Symptom: kubectl scale succeeds, but pods stay at old count.
  • Root cause: Deployment name typo, or pod template has invalid image (always pull fails).
  • Fix: bash kubectl get events --sort-by='.lastTimestamp' kubectl describe deployment nginx-demo Check for FailedCreate, ImagePullBackOff errors.

Scaling Down but Pods Not Terminating

  • Symptom: kubectl get pods shows terminating state for too long.
  • Root cause: PodDisruptionBudget (PDB) preventing healthy quorum, or preStop hooks taking time.
  • Fix: Check PDB: kubectl get pdb, or delete forcefully: kubectl delete pod <name> --grace-period=0 --force (use sparingly).

Wrong Replica Count Objected to by Cluster

  • Symptom: kubectl scale returns the server rejected our request for an unknown reason.
  • Root cause: You're exceeding resource quota or node capacity.
  • Fix: bash kubectl describe quota kubectl top nodes Add more nodes or reduce desired replicas.

Accidental Scale to Zero

  • Symptom: All pods disappear — but you meant to scale down, not kill everything.
  • Cure: Always double-check the number. Use --dry-run=client to preview: bash kubectl scale deployment nginx-demo --replicas=0 --dry-run=client

Blockquote Pro Tip: If you scale to zero, the Deployment still exists but has no running pods. To delete the Deployment entirely, use kubectl delete deployment.

What You Learned & What's Next

You now understand how to scale a deployment manually using both imperative and declarative approaches, the underlying ReplicaSet mechanism, and when to choose manual scaling over autoscaling. You can confidently: - Use kubectl scale for rapid adjustments. - Update spec.replicas in YAML and apply it. - Diagnose common scaling failures.

Next step: Manual scaling is great for quick changes, but what if you want your Deployment to survive node failures automatically? That's where self-healing and pod anti-affinity come in — your next lesson covers how Deployments stay healthy even when nodes go down. Continue to Node Failure & Pod Rescheduling.

Practice recap

Practice exercise: Create a Deployment with 2 replicas running nginx:alpine. Scale it to 4 using kubectl scale, then check that all 4 pods are running. Next, edit the YAML to reduce spec.replicas to 1 and apply the change — confirm only 1 pod remains. Finally, try scaling to 0 and back to 2, observing the pod lifecycle.

Common mistakes

  • Using kubectl scale on a Deployment that is already managed by an HPA — the HPA will override your manual change within moments.
  • Forgetting that scaling down terminates pods gracefully; if your app has long-lived connections, clients may experience disconnection until readiness probes stabilize.
  • Typing kubectl scale deployment nginx-demo --replicas=0 by accident — which kills all pods but keeps the Deployment intact.
  • Assuming scaling changes are immediate on nodes with limited resources — pods may remain pending until resources free up.

Variations

  1. Use kubectl autoscale to create an HPA that automatically adjusts replicas based on CPU usage, with commands like kubectl autoscale deployment nginx-demo --min=2 --max=10 --cpu-percent=50.
  2. Edit the Deployment spec directly via kubectl edit deployment nginx-demo and change the replicas field interactively.
  3. Use a Helm chart with --set replicaCount=X to scale as part of a deploy pipeline declaratively.

Real-world use cases

  • E-commerce site during Black Friday: operations manually scale a front-end Deployment from 20 to 150 replicas an hour before the sale starts.
  • Batch job worker pool: an admin scales a worker Deployment to 0 after processing completes, then back to 20 for the next batch.
  • Canary rollout: a team scales a new version Deployment to 1 replica, tests it, then scales to 50 while scaling the old version to 0.

Key takeaways

  • Manual scaling changes the spec.replicas field, and the Deployment controller adjusts the ReplicaSet accordingly.
  • Use kubectl scale deployment <name> --replicas=<n> for quick, imperative scaling; use YAML apply for version-controlled changes.
  • Scaling down terminates pods gracefully, respecting preStop hooks and terminationGracePeriodSeconds.
  • Manual scaling gives immediate, deterministic control — ideal for predictable traffic or testing.
  • Do not use manual scaling on Deployments controlled by an HPA, as they will fight for control.
  • Always verify scaling outcomes with kubectl get pods and kubectl describe deployment.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.