ReplicaSets
Welcome to the ReplicaSets chapter. This section covers fundamental concepts and best practices necessary to master this topic in depth.
1. The Genesis of ReplicaSets
A Pod on its own is mortal. If the Node it runs on crashes, the Pod dies with it. To build a highly available system, you cannot rely on individual Pods.
The solution is the ReplicaSet. A ReplicaSet ensures that a specified number of pod replicas are running at any given time.
The Control Loop (The “Thermometer” Analogy)
Think of a ReplicaSet like a thermostat.
- Desired State: You set the thermostat to 72°F (e.g.,
replicas: 3). - Current State: The thermostat reads the room temperature at 68°F (e.g., currently
2Pods running). - Reconciliation: The thermostat turns on the heater to reach 72°F (e.g., the Controller Manager starts
1more Pod).
The Kubernetes Control Plane constantly runs this loop, comparing the Current State to the Desired State and taking action to reconcile them.
2. Labels and Ownership
How does a ReplicaSet know which Pods belong to it? It uses Labels and Selectors.
A ReplicaSet manifest contains a selector block. It actively scans the cluster for Pods matching those labels. If it finds too few, it creates more. If it finds too many, it deletes some.
[!WARNING] If you manually create a standalone Pod with labels that match an existing ReplicaSet’s selector, the ReplicaSet will “adopt” it. If the ReplicaSet already has its desired number of Pods, it will immediately terminate your manually created Pod!
3. Interactive: ReplicaSet Control Loop
Adjust the desired replicas and simulate node failures to see the control loop in action.
Desired Replicas: 3
Current Pods: 3
4. Implementation Details
You define the Desired State in YAML. Here is a standard ReplicaSet manifest. Note the selector that ties it to the Pod template.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend-rs
labels:
app: guestbook
tier: frontend
spec:
# 1. Desired State
replicas: 3
# 2. How to find the Pods
selector:
matchLabels:
tier: frontend
# 3. What to create if Pods are missing
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
// Using Fabric8 Kubernetes Client to scale a ReplicaSet
try (KubernetesClient client = new KubernetesClientBuilder().build()) {
// Read current state
ReplicaSet rs = client.apps().replicaSets()
.inNamespace("default")
.withName("frontend-rs")
.get();
System.out.println("Current replicas: " + rs.getSpec().getReplicas());
// Update desired state
client.apps().replicaSets()
.inNamespace("default")
.withName("frontend-rs")
.scale(5, true); // Scale to 5 replicas
System.out.println("Scaled successfully.");
}
// Using client-go to scale a ReplicaSet
import (
"context"
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
func scaleReplicaSet(clientset *kubernetes.Clientset, ns string, name string, replicas int32) error {
// Get current ReplicaSet
rs, err := clientset.AppsV1().ReplicaSets(ns).Get(context.TODO(), name, metav1.GetOptions{})
if err != nil {
return err
}
// Update desired replicas
rs.Spec.Replicas = &replicas
// Apply changes
_, err = clientset.AppsV1().ReplicaSets(ns).Update(context.TODO(), rs, metav1.UpdateOptions{})
if err != nil {
return err
}
fmt.Printf("Scaled ReplicaSet %s to %d replicas\n", name, replicas)
return nil
}