## Intro

Working with Kubernetes ReplicaSets often starts with a simple goal: make sure a specified number of pod replicas are running at any given time. In practice, you will spend more time inspecting why pods are not becoming ready than creating ReplicaSets. The commands in this guide are arranged to move you from observation to a verified result, with safe defaults and concrete examples.

This article covers the essential kubectl commands for ReplicaSet management. It is written for developers, DevOps engineers, and technical startup teams who need a practical reference. Each section includes the command, expected output, common failure signals, and the recovery decision that matches the situation.

The guiding principle is operational safety: observe before changing, limit the blast radius, use placeholders instead of secrets, verify results, and document recovery paths. Run the commands in a non-production namespace first if you are trying them for the first time.

## Version and Environment Inventory

Before running any ReplicaSet command, confirm the Kubernetes version and environment. ReplicaSet behavior has been stable across many releases, but newer versions often add fields or change default behaviors. Check your client and server versions with:

```bash
kubectl version --short
```

Expected output (versions may differ):

```text
Client Version: v1.27.3
Kustomize Version: v5.0.1
Server Version: v1.27.3
```

A mismatch between client and server is usually acceptable if they are within one minor version, but for production work, keep them aligned. Next, confirm you are in the correct namespace. Many mistakes happen because a command runs in the default namespace while the ReplicaSet lives elsewhere.

```bash
kubectl config view --minify | grep namespace
```

If the output is not the namespace you expect, switch with:

```bash
kubectl config set-context --current --namespace=my-app
```

Now list existing ReplicaSets in that namespace:

```bash
kubectl get replicasets
```

Example output:

```text
NAME       DESIRED   CURRENT   READY   AGE
frontend   3         3         3       2d
backend    2         2         1       5h
```

In this example, the `backend` ReplicaSet is not fully ready. That is a signal to inspect before making changes. Before any intervention, record the current state with timestamps. This gives you a baseline for comparison and rollback. For example:

```bash
kubectl get replicasets -o yaml > replicasets-backup-$(date +%Y%m%d-%H%M%S).yaml
```

Store this file outside the cluster. It will help you restore the ReplicaSet if a subsequent change causes problems.

## Safe Configuration Path

Changing a ReplicaSet should be deliberate. Always use an imperative command to update a live object, or apply a modified manifest after reviewing the diff. Never edit a ReplicaSet directly without a backup.

The safest way to experiment is with a small, local test. Create a manifest named `test-rs.yaml`:

```yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: test-rs
  labels:
    app: guestbook
    tier: frontend
spec:
  replicas: 2
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3
```

Apply it and watch the ReplicaSet create pods:

```bash
kubectl apply -f test-rs.yaml
kubectl get rs test-rs -w
```

Use `Ctrl+C` to stop watching after the desired number of replicas appears. If the pods do not become ready, inspect them with `kubectl describe pods -l tier=frontend`.

Scaling a ReplicaSet is a common configuration change. You can scale imperatively:

```bash
kubectl scale replicaset test-rs --replicas=4
```

Verify that the new pods are running:

```bash
kubectl get rs test-rs
kubectl get pods -l tier=frontend
```

Alternatively, edit the manifest, change `replicas: 2` to `replicas: 4`, and run `kubectl apply -f test-rs.yaml` again. The declarative approach keeps your file as the source of truth.

For a quick local test of connectivity, use port-forward to a pod managed by the ReplicaSet:

```bash
kubectl port-forward pod/test-rs-xxxxx 8080:80
```

Replace `test-rs-xxxxx` with an actual pod name from `kubectl get pods -l tier=frontend`. Then open `http://localhost:8080` in a browser. This avoids exposing a service externally while you validate the pod.

## Verification and Diagnostics

Diagnosing ReplicaSet issues requires a systematic approach. Start with the ReplicaSet status, then drill into pods and events.

Get detailed information about a ReplicaSet:

```bash
kubectl describe rs test-rs
```

Look for events at the bottom. They often indicate problems like image pull errors or insufficient resources.

Check the pods owned by the ReplicaSet:

```bash
kubectl get pods -l tier=frontend -o wide
```

The `-o wide` flag adds node and IP information, which helps identify scheduling issues.

For a pod that is not ready, describe it:

```bash
kubectl describe pod <pod-name>
```

Common failure reasons include `ImagePullBackOff`, `CrashLoopBackOff`, `Pending` due to no available nodes, or `FailedScheduling` because of resource limits.

View logs of a crashing container:

```bash
kubectl logs <pod-name> --previous
```

The `--previous` flag shows logs from the previous container instance, which is crucial for crash loops.

If the ReplicaSet is created by a Deployment, also check the rollout status:

```bash
kubectl rollout status deployment/my-deployment
```

This command waits for the rollout to complete or reports failure.

A quick readiness probe can be tested manually with `kubectl exec`:

```bash
kubectl exec -it <pod-name> -- curl localhost:80/healthz
```

Replace `/healthz` with your actual health endpoint. If the command fails, the readiness probe will also fail.

## Failure Modes and Recovery

ReplicaSets fail for predictable reasons. Recognizing these patterns speeds up recovery.

**Pods stuck in Pending state.** Usually indicates insufficient CPU or memory, or no nodes matching node selectors. Check events:

```bash
kubectl describe rs <rs-name> | grep -A10 Events
```

If resources are the issue, reduce requests or add nodes. If node selectors are wrong, fix the selector in the pod template.

**Pods crash looping (CrashLoopBackOff).** The application exits immediately after start. Inspect logs:

```bash
kubectl logs <pod-name> --previous
```

Fix the application error, then delete the pod to force the ReplicaSet to create a new one:

```bash
kubectl delete pod <pod-name>
```

The ReplicaSet controller will automatically replace it.

**ReplicaSet does not create pods.** This can happen if the selector does not match the pod template labels. The ReplicaSet will show `0` desired but no error. Validate the selector:

```bash
kubectl get rs <rs-name> -o jsonpath='{.spec.selector}' && echo
kubectl get rs <rs-name> -o jsonpath='{.spec.template.metadata.labels}' && echo
```

If they do not match, edit the ReplicaSet to align them. Note that changing the selector is restricted in newer Kubernetes versions; you may need to delete and recreate the ReplicaSet.

**Image pull errors.** If the image name or tag is wrong, or registry credentials are missing, pods show `ImagePullBackOff`. Confirm the image exists and the registry is accessible. For private registries, ensure the pod has an image pull secret:

```bash
kubectl get pods <pod-name> -o jsonpath='{.spec.imagePullSecrets}' && echo
```

If empty, add an image pull secret to the pod template.

Recovery always involves fixing the root cause, then either deleting the pod or updating the ReplicaSet.

## Operations Checklist

Use this checklist for routine ReplicaSet operations. Assign a single owner to each item if you are working in a team, and revisit the checklist monthly or after any incident.

- [ ] **Version alignment**: `kubectl version` shows client and server within one minor version. Owner: DevOps lead.
- [ ] **Namespace verification**: `kubectl config get-contexts` shows the correct current namespace. Owner: Operator on duty.
- [ ] **Current state recorded**: `kubectl get rs -o yaml > backup-rs-$(date +%F).yaml`. Owner: Operator on duty.
- [ ] **ReplicaSet status checked**: `kubectl get rs` shows desired, current, and ready counts. Owner: Application owner.
- [ ] **Pods healthy**: `kubectl get pods -l <selector>` shows all pods running and ready. Owner: Application owner.
- [ ] **Logs reviewed for errors**: `kubectl logs <pod> --tail=50` for each pod. Owner: Developer responsible for the service.
- [ ] **Scaling operation verified**: After scaling, `kubectl get rs <name>` confirms new replica count. Owner: Operator on duty.
- [ ] **Rollback plan documented**: The previous ReplicaSet YAML is stored and accessible. Owner: DevOps lead.
- [ ] **Events checked for warnings**: `kubectl get events --sort-by=.metadata.creationTimestamp | tail -20`. Owner: Operator on duty.

Run through this checklist before and after any ReplicaSet change. Consistency prevents surprises.

## Common Pitfalls and How to Avoid Them

ReplicaSet management has several recurring mistakes. Understanding them saves time.

**Pitfall 1: Using ReplicaSet directly instead of a Deployment.** ReplicaSets do not support rolling updates. If you need to update the pod template, you must manually delete pods or create a new ReplicaSet. Use a Deployment for stateless applications; it manages a ReplicaSet for you.

**Pitfall 2: Confusing labels and selectors.** The ReplicaSet selector must match the pod template labels exactly. A mismatch results in no pods being created, or the ReplicaSet adopting pods it does not own. Always verify with `kubectl get rs -o yaml`.

**Pitfall 3: Ignoring pod readiness.** A pod can be running but not ready, and the ReplicaSet counts it as ready only if it passes readiness probes. If your pods never become ready, the ReplicaSet will scale up endlessly (if using a HorizontalPodAutoscaler). Define readiness probes that reflect actual service readiness.

**Pitfall 4: Deleting a ReplicaSet before deleting its pods.** If you delete a ReplicaSet, its pods are not automatically deleted unless you use `--cascade=true` (the default in recent kubectl). Otherwise, orphaned pods remain. Use `kubectl delete rs <name> --cascade=orphan` only if you intend to keep pods and adopt them later.

**Pitfall 5: Not setting resource requests and limits.** Without requests, the scheduler may place too many pods on a node, causing CPU starvation or OOM kills. Always set requests and limits in the pod template.

**Pitfall 6: Forgetting to update the ReplicaSet image tag.** If you update the image in the pod template but do not trigger a rollout, existing pods remain on the old image. With a Deployment, use `kubectl set image`, but with a ReplicaSet, you must delete pods manually or use a Deployment.

Avoid these pitfalls by following the verification steps in each section and keeping the Operations Checklist handy.

## Conclusion

Kubernetes ReplicaSet commands are straightforward, but safe operation requires attention to detail. The commands in this guide provide a structured way to observe, diagnose, and recover from common issues. Remember to always back up current state, change one thing at a time, and verify after each change.

As a next step, pick one low-risk verification from the Operations Checklist. Run it in a test namespace, record the result, and compare with the expected output. Then, extend your practice to a Deployment, which is the recommended way to manage ReplicaSets for stateless workloads.

A reliable workflow makes failure visible, protects sensitive values, limits changes to the intended resource, and defines recovery steps before an incident forces the decision. Use these commands daily and review them with your team to build operational confidence.