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
replicaset.apps/nginx-replicaset created
# Verify ReplicaSet creation
kubectl get replicaset
NAME DESIRED CURRENT READY AGE
nginx-replicaset 3 3 3 45s
# Check pods created by ReplicaSet
kubectl get pods -l app=nginx
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
replicaset.apps/nginx-replicaset scaled
# Scale by editing ReplicaSet
kubectl edit replicaset nginx-replicaset
replicaset.apps/nginx-replicaset edited
# Check scaling status
kubectl get replicaset nginx-replicaset
NAME DESIRED CURRENT READY AGE
nginx-replicaset 5 5 5 2m
# Watch pods being created
kubectl get pods -l app=nginx -w
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
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
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
replicaset.apps/frontend-rs created
# Check resource allocation
kubectl get pods -l tier=frontend -o yaml | grep -A 5 resources:
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 250m
memory: 64Mi
# Monitor resource usage
kubectl top pods -l tier=frontend
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
node/worker-node1 labeled
node/worker-node2 labeled
# Create the ReplicaSet
kubectl apply -f nginx-rs.yaml
replicaset.apps/nginx-rs created
# Verify pod placement
kubectl get pods -l app=nginx -o wide
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:"
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
replicaset.apps/web-rs created
# Check pod distribution across nodes
kubectl get pods -l app=web -o wide
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:
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:
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
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
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
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
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
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
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
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
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
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
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
NAME DESIRED CURRENT READY AGE
nginx-replicaset 5 5 5 5m
frontend-rs 3 3 3 2m
# Describe ReplicaSet
kubectl describe rs nginx-replicaset
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
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
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¶
- Learn about Deployments (which manage ReplicaSets)
- Implement advanced scaling strategies
- Set up monitoring and alerting
- Configure horizontal pod autoscaling
- Implement rolling updates using Deployments