Skip to content

How to Create a ReplicaSet in Kubernetes

This guide explains how to create and manage ReplicaSets in Kubernetes. A ReplicaSet ensures that a specified number of pod replicas are running at any given time.

Prerequisites

  • Running Kubernetes cluster
  • kubectl installed and configured
  • Basic understanding of Kubernetes Pods

What is a ReplicaSet?

A ReplicaSet's purpose is to maintain a stable set of replica Pods running at any given time. It is often used to guarantee the availability of a specified number of identical Pods. While ReplicaSets can be used directly, they are usually used indirectly through Deployments, which provide declarative updates and additional features.

Key features: - Ensures specified number of replicas are running - Provides pod template for creating new pods - Automatically replaces failed pods - Can be scaled up or down

Creating a ReplicaSet

Basic ReplicaSet Example

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
  labels:
    app: nginx
    tier: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

ReplicaSet with Label Selectors

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
    matchExpressions:
      - {key: env, operator: In, values: [prod, staging]}
  template:
    metadata:
      labels:
        tier: frontend
        env: prod
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3

Common Operations

1. Creating a ReplicaSet

# Create ReplicaSet from YAML
kubectl apply -f replicaset.yaml
Output:
replicaset.apps/nginx-replicaset created

# Verify ReplicaSet creation
kubectl get replicaset
Output:
NAME               DESIRED   CURRENT   READY   AGE
nginx-replicaset   3         3         3       45s

# Check pods created by ReplicaSet
kubectl get pods -l app=nginx
Output:
NAME                     READY   STATUS    RESTARTS   AGE
nginx-replicaset-9j4d9   1/1     Running   0          42s
nginx-replicaset-b2wzl   1/1     Running   0          42s
nginx-replicaset-m8mvz   1/1     Running   0          42s

2. Scaling a ReplicaSet

# Scale using kubectl scale
kubectl scale replicaset nginx-replicaset --replicas=5
Output:
replicaset.apps/nginx-replicaset scaled

# Scale by editing ReplicaSet
kubectl edit replicaset nginx-replicaset
Output:
replicaset.apps/nginx-replicaset edited

# Check scaling status
kubectl get replicaset nginx-replicaset
Output:
NAME               DESIRED   CURRENT   READY   AGE
nginx-replicaset   5         5         5       2m

# Watch pods being created
kubectl get pods -l app=nginx -w
Output:
NAME                     READY   STATUS              RESTARTS   AGE
nginx-replicaset-9j4d9   1/1     Running            0          2m
nginx-replicaset-b2wzl   1/1     Running            0          2m
nginx-replicaset-m8mvz   1/1     Running            0          2m
nginx-replicaset-k9p2x   0/1     ContainerCreating  0          2s
nginx-replicaset-f7t6r   0/1     ContainerCreating  0          2s
nginx-replicaset-k9p2x   1/1     Running            0          3s
nginx-replicaset-f7t6r   1/1     Running            0          4s

3. Deleting a ReplicaSet

# Delete ReplicaSet and its pods
kubectl delete replicaset nginx-replicaset
Output:
replicaset.apps "nginx-replicaset" deleted

# Watch pods being terminated
NAME                     READY   STATUS        RESTARTS   AGE
nginx-replicaset-9j4d9   0/1     Terminating   0         15m
nginx-replicaset-b2wzl   0/1     Terminating   0         15m
nginx-replicaset-m8mvz   0/1     Terminating   0         15m
nginx-replicaset-k9p2x   0/1     Terminating   0         13m
nginx-replicaset-f7t6r   0/1     Terminating   0         13m

# Delete ReplicaSet only (keeping pods)
kubectl delete replicaset nginx-replicaset --cascade=orphan
Output:
replicaset.apps "nginx-replicaset" deleted

# Pods still exist and are now independent
NAME                     READY   STATUS    RESTARTS   AGE
nginx-replicaset-9j4d9   1/1     Running   0         16m
nginx-replicaset-b2wzl   1/1     Running   0         16m
nginx-replicaset-m8mvz   1/1     Running   0         16m
nginx-replicaset-k9p2x   1/1     Running   0         14m
nginx-replicaset-f7t6r   1/1     Running   0         14m

# Verify pods are no longer controlled by the ReplicaSet
kubectl get pods nginx-replicaset-9j4d9 -o yaml | grep controller
# No output - pod is no longer controlled by ReplicaSet

## Advanced Configurations

### 1. ReplicaSet with Resource Limits

```yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
          requests:
            memory: "64Mi"
            cpu: "250m"

Apply and verify the resource-limited ReplicaSet:

# Create the ReplicaSet
kubectl apply -f frontend-rs.yaml
Output:
replicaset.apps/frontend-rs created

# Check resource allocation
kubectl get pods -l tier=frontend -o yaml | grep -A 5 resources:
Output:
    resources:
      limits:
        cpu: 500m
        memory: 128Mi
      requests:
        cpu: 250m
        memory: 64Mi

# Monitor resource usage
kubectl top pods -l tier=frontend
Output:
NAME               CPU(cores)   MEMORY(bytes)
frontend-rs-x4k8z   125m         75Mi
frontend-rs-b2wzl   142m         82Mi
frontend-rs-m8mvz   138m         78Mi

### 2. ReplicaSet with Node Selection

```yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeSelector:
        disktype: ssd
      containers:
      - name: nginx
        image: nginx:1.14.2

First, label the nodes and then deploy the ReplicaSet:

# Label nodes with SSD
kubectl label nodes worker-node1 disktype=ssd
kubectl label nodes worker-node2 disktype=ssd
Output:
node/worker-node1 labeled
node/worker-node2 labeled

# Create the ReplicaSet
kubectl apply -f nginx-rs.yaml
Output:
replicaset.apps/nginx-rs created

# Verify pod placement
kubectl get pods -l app=nginx -o wide
Output:
NAME            READY   STATUS    RESTARTS   AGE   IP            NODE           NOMINATED NODE
nginx-rs-x4k8z   1/1    Running   0          45s   10.244.2.12   worker-node1   <none>
nginx-rs-b2wzl   1/1    Running   0          45s   10.244.1.15   worker-node2   <none>
nginx-rs-m8mvz   1/1    Running   0          45s   10.244.2.13   worker-node1   <none>

# Verify node selection
kubectl describe pods -l app=nginx | grep "Node:"
Output:
Node:         worker-node1/192.168.1.101
Node:         worker-node2/192.168.1.102
Node:         worker-node1/192.168.1.101

## Best Practices

### 1. Using Labels Effectively

```yaml
metadata:
  labels:
    app: myapp
    tier: frontend
    environment: production
    version: v1.0.0

2. Setting Resource Constraints

spec:
  template:
    spec:
      containers:
      - resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

3. Implementing Health Checks

spec:
  template:
    spec:
      containers:
      - name: nginx
        livenessProbe:
          httpGet:
            path: /healthz
            port: 80
          initialDelaySeconds: 3
          periodSeconds: 3

Production Examples

1. High-Availability Web Server

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: web-rs
  labels:
    app: web
    tier: frontend
spec:
  replicas: 5
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - web
              topologyKey: kubernetes.io/hostname
      containers:
      - name: nginx
        image: nginx:1.19
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 200m
            memory: 256Mi
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 20

Deploy and verify the high-availability setup:

# Create the ReplicaSet
kubectl apply -f ha-web-rs.yaml
Output:
replicaset.apps/web-rs created

# Check pod distribution across nodes
kubectl get pods -l app=web -o wide
Output:
NAME           READY   STATUS    RESTARTS   AGE   IP            NODE           
web-rs-x4k8z   1/1     Running   0         45s   10.244.2.12   worker-node1   
web-rs-b2wzl   1/1     Running   0         45s   10.244.1.15   worker-node2   
web-rs-m8mvz   1/1     Running   0         45s   10.244.3.11   worker-node3   
web-rs-k9p2x   1/1     Running   0         45s   10.244.1.16   worker-node2   
web-rs-f7t6r   1/1     Running   0         45s   10.244.2.13   worker-node1   

# Verify pod anti-affinity is working
kubectl describe pods -l app=web | grep Node:
Output:
Node:         worker-node1/192.168.1.101
Node:         worker-node2/192.168.1.102
Node:         worker-node3/192.168.1.103
Node:         worker-node2/192.168.1.102
Node:         worker-node1/192.168.1.101

# Check readiness probe status
kubectl describe pods -l app=web | grep Readiness:
Output:
    Readiness:  http-get http://:80/ delay=5s timeout=1s period=10s #success=1 #failure=3
    Readiness:  http-get http://:80/ delay=5s timeout=1s period=10s #success=1 #failure=3
    Readiness:  http-get http://:80/ delay=5s timeout=1s period=10s #success=1 #failure=3
    Readiness:  http-get http://:80/ delay=5s timeout=1s period=10s #success=1 #failure=3
    Readiness:  http-get http://:80/ delay=5s timeout=1s period=10s #success=1 #failure=3

# Monitor resource usage
kubectl top pods -l app=web
Output:
NAME           CPU(cores)   MEMORY(bytes)   
web-rs-x4k8z   12m          65Mi           
web-rs-b2wzl   15m          68Mi           
web-rs-m8mvz   11m          64Mi           
web-rs-k9p2x   14m          67Mi           
web-rs-f7t6r   13m          66Mi

## Troubleshooting

### Common Issues and Solutions

1. **Pods Not Starting**
```bash
# Check ReplicaSet events
kubectl describe rs nginx-replicaset
Output:
Events:
  Type     Reason        Age   From                   Message
  ----     ------        ----  ----                   -------
  Warning  FailedCreate  10s   replicaset-controller  Error creating: pods "nginx-replicaset-f4f7b" is forbidden: exceeded quota: compute-resources, requested: cpu=500m, used: cpu=2, limited: cpu=2

# Check pod status
kubectl get pods -l app=nginx
Output:
NAME                     READY   STATUS    RESTARTS   AGE
nginx-replicaset-9j4d9   0/1     Pending   0         45s
nginx-replicaset-k8d2p   0/1     Pending   0         45s

# Check pod details
kubectl describe pod nginx-replicaset-9j4d9
Output:
Name:           nginx-replicaset-9j4d9
Namespace:      default
Priority:       0
Node:           <none>
Status:         Pending
IP:             
Controlled By:  ReplicaSet/nginx-replicaset

Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  2m     default-scheduler  0/3 nodes are available: insufficient cpu
  Warning  FailedScheduling  2m     default-scheduler  0/3 nodes are available: insufficient memory

2. **Scaling Issues**
```bash
# Verify ReplicaSet status
kubectl get rs nginx-replicaset -o wide
Output:
NAME               DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES         SELECTOR
nginx-replicaset   5         3         3       5m    nginx        nginx:1.14.2   app=nginx

# Check available resources
kubectl describe nodes
Output:
Name:            worker-node1
Roles:           <none>
Labels:          beta.kubernetes.io/arch=amd64
                 kubernetes.io/hostname=worker-node1
Capacity:
  cpu:           2
  memory:        4Gi
  pods:          110
Allocatable:
  cpu:           1800m
  memory:        3624Mi
  pods:          110
Allocated resources:
  Resource           Requests    Limits
  --------           --------    ------
  cpu                1600m       2000m
  memory             2Gi         2.5Gi
  ephemeral-storage  0           0

# View ReplicaSet details
kubectl describe rs nginx-replicaset
Output:
Name:         nginx-replicaset
Namespace:    default
Selector:     app=nginx
Labels:       app=nginx
Replicas:     5 desired | 3 current | 3 ready
Pods Status:  3 Running / 2 Waiting / 0 Failed
Events:
  Type     Reason            Age   From                   Message
  ----     ------            ----  ----                   -------
  Warning  FailedCreate      2m    replicaset-controller  Error creating: pods "nginx-replicaset-f4f7b" is forbidden: exceeded quota
  Normal   SuccessfulCreate  5m    replicaset-controller  Created pod: nginx-replicaset-9j4d9

3. **Label Selector Issues**
```bash
# Check ReplicaSet selector
kubectl get rs nginx-replicaset -o yaml
Output:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx-wrong  # Mismatch between selector and pod template labels

# Verify pod labels
kubectl get pods --show-labels
Output:
NAME                     READY   STATUS    RESTARTS   AGE   LABELS
nginx-replicaset-9j4d9   1/1     Running   0         10m   app=nginx-wrong
manual-nginx-pod         1/1     Running   0         5m    app=nginx
Note: The ReplicaSet selector looks for pods with label app=nginx, but the pod template creates pods with label app=nginx-wrong, causing the mismatch.

Monitoring ReplicaSets

Commands for Monitoring

# Get ReplicaSet status
kubectl get rs
Output:
NAME               DESIRED   CURRENT   READY   AGE
nginx-replicaset   5         5         5       5m
frontend-rs        3         3         3       2m

# Describe ReplicaSet
kubectl describe rs nginx-replicaset
Output:
Name:         nginx-replicaset
Namespace:    default
Selector:     app=nginx
Labels:       app=nginx
              tier=frontend
Annotations:  <none>
Replicas:     5 current / 5 desired
Pods Status:  5 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx:1.14.2
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  5m    replicaset-controller  Created pod: nginx-replicaset-9j4d9
  Normal  SuccessfulCreate  5m    replicaset-controller  Created pod: nginx-replicaset-b2wzl
  Normal  SuccessfulCreate  5m    replicaset-controller  Created pod: nginx-replicaset-m8mvz
  Normal  SuccessfulCreate  3m    replicaset-controller  Created pod: nginx-replicaset-k9p2x
  Normal  SuccessfulCreate  3m    replicaset-controller  Created pod: nginx-replicaset-f7t6r

# Monitor pod creation/deletion
kubectl get pods -w -l app=nginx
Output:
NAME                     READY   STATUS    RESTARTS   AGE
nginx-replicaset-9j4d9   1/1     Running   0          5m
nginx-replicaset-b2wzl   1/1     Running   0          5m
nginx-replicaset-m8mvz   1/1     Running   0          5m
nginx-replicaset-k9p2x   1/1     Running   0          3m
nginx-replicaset-f7t6r   1/1     Running   0          3m

# Check ReplicaSet events
kubectl get events --field-selector involvedObject.kind=ReplicaSet
Output:
LAST SEEN   TYPE     REASON              OBJECT                      MESSAGE
5m          Normal   SuccessfulCreate    replicaset/nginx-replicaset Created pod: nginx-replicaset-9j4d9
5m          Normal   SuccessfulCreate    replicaset/nginx-replicaset Created pod: nginx-replicaset-b2wzl
5m          Normal   SuccessfulCreate    replicaset/nginx-replicaset Created pod: nginx-replicaset-m8mvz
3m          Normal   SuccessfulCreate    replicaset/nginx-replicaset Created pod: nginx-replicaset-k9p2x
3m          Normal   SuccessfulCreate    replicaset/nginx-replicaset Created pod: nginx-replicaset-f7t6r

Next Steps

  1. Learn about Deployments (which manage ReplicaSets)
  2. Implement advanced scaling strategies
  3. Set up monitoring and alerting
  4. Configure horizontal pod autoscaling
  5. Implement rolling updates using Deployments