Ravindra BagaleCourses & study guides मराठी

Chapter 18: Kubernetes Workloads

18.6 ReplicationController — the older name

Why: the problem

You join a bank's platform team and open an old repo. The YAML says kind: ReplicationController. Your senior asks you to move it to a Deployment before the next cluster upgrade. If you have never seen a ReplicationController, you will not know what to change. A ReplicationController, or RC, is the first version of a ReplicaSet from the early days of Kubernetes. It keeps N Pods running, just like a ReplicaSet. The big difference is the selector. An RC can only match labels by exact equality. A ReplicaSet also supports set-based rules like "env in (dev, test)". RC also used the old kubectl rolling-update command, which was removed. Kubernetes docs now say: use a Deployment. You still meet RCs in old tutorials, old Helm charts and interviews. In this lesson you will run an RC, see its limits, and migrate it to a Deployment with no downtime.

What we will build

You will apply an old RC with 3 Pods behind a Service, then create a Deployment that serves the same traffic, switch over, and delete the RC without dropping any request.

What: every term in plain English

  • ReplicationController — The older controller that keeps N Pods. apiVersion v1, kind ReplicationController.
  • Equality-based selector — Matches labels exactly, like app = pay.
  • Set-based selector — Matches with in, notin or exists. ReplicaSets and Deployments support it.
  • rolling-update — An old kubectl command for RCs. Removed in kubectl 1.18.
  • Migration — Moving a workload to a new object type without downtime.
  • Deprecated — Still works, but not recommended for new work.
Start a lab cluster Make a practice namespace Write the old RC Apply it and add a Service List it Try the old update command Check the API shape
ReplicationController and migrating to a Deployment

How: step by step

  1. Start a lab cluster

    kind create cluster --name lab
    kubectl get nodes
    

    What it does: Creates a one-node Kubernetes cluster inside Docker. On minikube use: minikube start.

    Output

    Creating cluster "lab" ...
     ✓ Ensuring node image (kindest/node:v1.30.0)
     ✓ Preparing nodes
    Set kubectl context to "kind-lab"
    NAME                STATUS   ROLES           AGE   VERSION
    lab-control-plane   Ready    control-plane   40s   v1.30.0
    
  2. Make a practice namespace

    kubectl create namespace practice
    kubectl config set-context --current --namespace=practice
    

    What it does: Keeps all lab objects in one folder that is easy to delete.

    Output

    namespace/practice created
    Context "kind-lab" modified.
    
  3. Write the old RC

    cat rc.yaml
    

    What it does: An RC with an equality selector.

    Output

    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: pay
    spec:
      replicas: 3
      selector:
        app: pay
      template:
        metadata:
          labels: {app: pay, version: v1}
        spec:
          containers:
          - name: web
            image: nginx:1.25
    
  4. Apply it and add a Service

    kubectl apply -f rc.yaml
    kubectl expose rc pay --port=80
    

    What it does: Three Pods behind one Service.

    Output

    replicationcontroller/pay created
    service/pay exposed
    
  5. List it

    kubectl get rc pay
    

    What it does: Same columns as a ReplicaSet.

    Output

    NAME   DESIRED   CURRENT   READY   AGE
    pay    3         3         3       10s
    
  6. Try the old update command

    kubectl rolling-update pay --image=nginx:1.27
    

    What it does: The command no longer exists.

    Output

    error: unknown command "rolling-update" for "kubectl"
    
  7. Check the API shape

    kubectl explain rc.spec.selector
    

    What it does: The selector is a plain map, no matchLabels.

    Output

    KIND:       ReplicationController
    FIELD:      selector map[string]string
    DESCRIPTION:
        Selector is a label query over pods that should match the Replicas count.
    

Example 1: RC cannot use set-based selectors

Stack. Kubernetes 1.30

Goal. RC cannot use set-based selectors.

rc-set.yaml

apiVersion: v1
kind: ReplicationController
metadata:
  name: pay-set
spec:
  replicas: 1
  selector:
    matchExpressions:
    - {key: env, operator: In, values: [dev, test]}
  template:
    metadata:
      labels: {env: dev}
    spec:
      containers:
      - name: web
        image: nginx:1.27

terminal

kubectl apply -f rc-set.yaml

What each line does

  • matchExpressions — A set-based rule. Valid in ReplicaSet, not in RC.
  • operator: In — Matches if env is dev or test.
  • Error — The RC selector must be a simple map.

Green output

Error from server (BadRequest): error when creating "rc-set.yaml": ReplicationController in version "v1" cannot be handled as a ReplicationController: json: cannot unmarshal object into Go struct field ReplicationControllerSpec.spec.selector of type string

Expected result. This is the main technical difference you can quote in an interview.

Example 2: The same app as a Deployment

Stack. kind, Kubernetes 1.30

Goal. The same app as a Deployment.

pay-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pay-v2
spec:
  replicas: 3
  selector:
    matchLabels: {app: pay, version: v2}
  template:
    metadata:
      labels: {app: pay, version: v2}
    spec:
      containers:
      - name: web
        image: nginx:1.27

terminal

kubectl apply -f pay-deploy.yaml
kubectl rollout status deploy/pay-v2
kubectl get endpoints pay

What each line does

  • apiVersion: apps/v1 — Deployments live in the apps group.
  • selector.matchLabels — The new selector shape.
  • version: v2 — Keeps the new Pods separate from the RC Pods.
  • app: pay — The Service selects app=pay, so it now sends traffic to both sets.

Green output

deployment.apps/pay-v2 created
deployment "pay-v2" successfully rolled out
NAME   ENDPOINTS                                               AGE
pay    10.244.0.5:80,10.244.0.6:80,10.244.0.7:80 + 3 more...  2m

Expected result. Six endpoints: three old, three new. Traffic flows to both, so there is no gap.

Example 3: Switch over and remove the RC with no dropped requests

Stack. busybox load loop

Goal. Switch over and remove the RC with no dropped requests.

terminal

# terminal 1: keep calling the Service
kubectl run load --image=busybox:1.36 --restart=Never -- sh -c 'while true; do wget -qO- -T 1 pay >/dev/null && echo ok || echo FAIL; sleep 0.2; done'

# terminal 2: scale the RC down, then delete it
kubectl scale rc pay --replicas=0
kubectl delete rc pay
kubectl logs load | sort | uniq -c

What each line does

  • load Pod — Calls the Service five times a second.
  • scale rc --replicas=0 — Removes the old Pods slowly while new ones serve.
  • delete rc pay — Removes the old object.
  • uniq -c — Counts ok and FAIL lines.

Green output

replicationcontroller/pay scaled
replicationcontroller "pay" deleted
    412 ok

Expected result. Zero FAIL lines. The Service kept selecting app=pay, which the Deployment Pods also carry.

Verify: did it work?

  1. Confirm no RCs are left

    kubectl get rc -A
    

    What it does: Should return nothing in a clean cluster.

    Output

    No resources found
    
  2. Confirm the Service points to the Deployment

    kubectl get pods -l app=pay -L version
    

    What it does: All Pods now say v2.

    Output

    NAME                     READY   STATUS    VERSION
    pay-v2-7d9c8b6f5-2kq8x   1/1     Running   v2
    pay-v2-7d9c8b6f5-8vwz3   1/1     Running   v2
    pay-v2-7d9c8b6f5-m4tn1   1/1     Running   v2
    

When it is red 1

error: unknown command "rolling-update" for "kubectl"

Cause. The command was removed in kubectl 1.18.

Fix, step by step

  1. Move the workload to a Deployment.
  2. Use kubectl rollout for updates.

When it is red 2

The Deployment Pods get deleted right after creation

Cause. The RC selector app: pay also matched the new Pods and it deleted extras.

Fix, step by step

  1. Give the RC an extra label like version: v1 in its selector first, or scale the RC to 0 before creating the Deployment.

When it is red 3

Service has no endpoints after deleting the RC

Cause. The Deployment Pods do not carry the label the Service selects.

Fix, step by step

  1. Run kubectl get svc pay -o yaml and check the selector.
  2. Add the label to the Deployment template.

Cleanup

  1. Delete the lesson objects

    kubectl delete deploy pay-v2
    kubectl delete svc pay
    kubectl delete pod load
    

    What it does: Removes the Deployment, Service and load Pod.

    Output

    deployment.apps "pay-v2" deleted
    service "pay" deleted
    pod "load" deleted
    
  2. Delete the practice namespace

    kubectl delete namespace practice
    

    What it does: Deletes every object you made in this lesson in one go.

    Output

    namespace "practice" deleted
    

Ravindra Bagale's Tip

ReplicationController juna aahe. Navin kaamat Deployment vapra, ani migrate kartana Service cha label same theva. Lakshat theva!

Practice tasks

Easy Find RCs

Why: Old clusters still have them.

What to do: List RCs in every namespace.

How:
  1. kubectl get rc -A

Check: You know if any exist.

Medium Convert an RC file

Why: A common clean-up ticket.

What to do: Turn rc.yaml into a Deployment file by hand.

How:
  1. Change apiVersion and kind.
  2. Put the selector under matchLabels.

Check: kubectl apply works.

Hard Use kubectl-convert

Why: Upgrades need tooling.

What to do: Install the kubectl-convert plugin and try it on old YAML.

How:
  1. Read the plugin docs on kubernetes.io.
  2. kubectl convert -f old.yaml

Check: You can explain its output.

Easy Say ReplicationController versus ReplicaSet in two lines

Why: If you can say it simply, you understand it. Interviewers want the short version first.

What to do: Write two short lines about ReplicationController versus ReplicaSet for a fresher who knows only Docker basics.

How:
  1. Write what problem it solves.
  2. Write the one kubectl command you use for it.
  3. Read it aloud to a friend.

Check: A fresher understands it without asking a question.

Easy Start a fresh lab cluster

Why: Practice needs a throwaway cluster. If you break it, you delete it and start again.

What to do: Create a kind cluster, or a minikube cluster, and check the node is Ready.

How:
  1. kind create cluster --name lab
  2. kubectl get nodes
  3. kubectl get pods -A

Check: One node shows STATUS Ready and the kube-system Pods are Running.

Medium Break it on purpose

Why: You must know the red message by face. During an outage there is no time to read slowly.

What to do: Cause one error from the "When it is red" part of this lesson and fix it.

How:
  1. Follow the error section.
  2. Copy the exact message and the kubectl describe Events into your notes.
  3. Write the fix in one line.

Check: You fixed it using only the steps, without searching the web.

Medium Write a one-page runbook

Why: At 2 a.m. nobody remembers the right command. A short page saves the on-call person.

What to do: Write a runbook page for this lesson.

How:
  1. Title, when to use, exact kubectl command, how to check, how to undo.

Check: A teammate can follow it alone.

Medium Repeat it on a cloud cluster

Why: kind is a laptop toy. Real clusters run on EKS, GKE, AKS or k3s on a VM.

What to do: Do the main steps of this lesson again on a small k3s VM or a free-tier managed cluster.

How:
  1. Install k3s on one Ubuntu 22.04 VM: curl -sfL https://get.k3s.io | sh -
  2. Copy the kubeconfig.
  3. Apply the same YAML and compare the output.

Check: Same output on the cloud cluster as on kind.

Hard Explain it like an interview

Why: Interviewers want real stories, not definitions.

What to do: Record a 60 second answer about this lesson.

How:
  1. Say the problem, the YAML field you used, the kubectl command you ran, and one error you hit.

Check: Your answer has a real command and a real error message.

Hard Draw the flow top to bottom

Why: A drawing shows who talks to whom and in what order.

What to do: Draw this lesson as boxes from top to bottom.

How:
  1. Start at kubectl apply, go through the API server, controller and scheduler, end at the running container.

Check: Each box matches a real thing you saw in kubectl output.

Homework: try at home

Try at home

At home, write an RC, put a Service on it, and migrate it to a Deployment while a busybox loop calls the Service. Count the FAIL lines. The goal is zero.

Recap

  • A ReplicationController is the old ReplicaSet.
  • It supports only equality selectors.
  • kubectl rolling-update is gone.
  • Migrate to a Deployment behind the same Service label.
  • You will meet RCs in old repos and interviews.

FAQ

Is RC removed?

No, it still works in v1, but docs say use a Deployment.

ReplicaSet or RC in an interview answer?

Say RC is legacy, ReplicaSet adds set-based selectors, and in practice you use Deployments.

Do Helm charts still use RC?

Very old ones. Modern charts use Deployments.

Does an RC keep revision history?

No. That is another reason to move.

Can a Deployment adopt RC Pods?

Not directly. Use the side-by-side switch shown here.

Interview questions

  1. Difference between ReplicationController and ReplicaSet?

    ReplicaSet supports set-based selectors and is used by Deployments; RC supports equality selectors only and is legacy.

  2. How would you migrate an RC to a Deployment?

    Create a Deployment with the Service label, verify endpoints, scale the RC to 0 and delete it.

  3. What happened to kubectl rolling-update?

    It was removed; Deployments handle rolling updates on the server side.

  4. Why are server-side rollouts better?

    They continue if your laptop disconnects and they keep history for rollback.

  5. Where might you still see RCs?

    Old tutorials, legacy clusters and old Helm charts.

Quick quiz

Q1. What apiVersion does an RC use?

v1.

Q2. What selector type does an RC support?

Equality only.

Q3. What replaced kubectl rolling-update?

Deployments with kubectl rollout.

Q4. How do you migrate with no downtime?

Run a Deployment with the label the Service selects, then scale the RC to 0.

Q5. Should new apps use RC?

No.

Samajla ka?

Ravi Sir's Cards for this lesson

मराठी cards