Exercise 1: Stateful Applications

Task 1 - Understanding StatefulSets

  1. StatefulSets are Kubernetes controllers that manage the deployment and scaling of a set of pods, providing guarantees about the ordering and uniqueness of these pods.

  2. Key characteristics of StatefulSets:

    • Stable, unique network identifiers
    • Stable, persistent storage
    • Ordered, graceful deployment and scaling
    • Ordered, automated rolling updates

Task 2 - Deploy MongoDB Using StatefulSets

  1. Create the MongoDB StatefulSet manifest:

    $statefulsetYaml = @"
    apiVersion: v1
    kind: Service
    metadata:
      name: mongodb-service
      labels:
        app: mongodb
    spec:
      clusterIP: None
      selector:
        app: mongodb
      ports:
      - port: 27017
        targetPort: 27017
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: mongodb
    spec:
      serviceName: "mongodb-service"
      replicas: 3
      selector:
        matchLabels:
          app: mongodb
      template:
        metadata:
          labels:
            app: mongodb
        spec:
          containers:
          - name: mongodb
            image: k8sonazureworkshoppublic.azurecr.io/mongo:4.4
            ports:
            - containerPort: 27017
              name: mongodb
            resources:
              requests:
                memory: "256Mi"
                cpu: "250m"
              limits:
                memory: "512Mi"
                cpu: "500m"
    cat << EOF | kubectl apply -f -
    apiVersion: v1
    kind: Service
    metadata:
      name: mongodb-service
      labels:
        app: mongodb
    spec:
      clusterIP: None
      selector:
        app: mongodb
      ports:
      - port: 27017
        targetPort: 27017
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: mongodb
    spec:
      serviceName: "mongodb-service"
      replicas: 3
      selector:
        matchLabels:
          app: mongodb
      template:
        metadata:
          labels:
            app: mongodb
        spec:
          containers:
          - name: mongodb
            image: k8sonazureworkshoppublic.azurecr.io/mongo:4.4
            ports:
            - containerPort: 27017
              name: mongodb
            resources:
              requests:
                memory: "256Mi"
                cpu: "250m"
              limits:
                memory: "512Mi"
                cpu: "500m"
    EOF

    This manifest defines:

    • A headless service (clusterIP: None)
    • A StatefulSet with 3 replicas
    • Resource requests and limits
  2. Verify the StatefulSet deployment:

    kubectl get statefulset
    kubectl get statefulset

    You should see output similar to:

    StatefulSet Output StatefulSet Output

    You may need to wait a few minutes for all pods to start.

Task 3 - Observe StatefulSet Behavior

  1. List the pods created by the StatefulSet:

    kubectl get pods -l app=mongodb
    kubectl get pods -l app=mongodb

    Notice the predictable pod names: mongodb-0, mongodb-1, mongodb-2

Task 4 - Test StatefulSet Ordering

  1. Delete a pod to observe the recreation behaviour:

    kubectl delete pod mongodb-1
    kubectl delete pod mongodb-1
  2. Watch the pod recreation:

    kubectl get pods -l app=mongodb --watch
    kubectl get pods -l app=mongodb --watch

    Notice that Kubernetes recreates the exact same pod with the same name, maintaining the StatefulSet’s guarantee of identity.

Task 5 - Scale the StatefulSet

  1. Scale the StatefulSet to 4 replicas:

    kubectl scale statefulset mongodb --replicas=4
    kubectl scale statefulset mongodb --replicas=4
  2. Observe the scaling process:

    kubectl get pods -l app=mongodb 
    kubectl get pods -l app=mongodb 

    Notice that pods are created one at a time, in order.

  3. Scale back down to 2 replicas:

    kubectl scale statefulset mongodb --replicas=2
    kubectl scale statefulset mongodb --replicas=2
  4. Observe the termination order:

    kubectl get pods -l app=mongodb
    kubectl get pods -l app=mongodb

    Notice that pods are terminated in reverse order (highest to lowest index).

Task 6 - Clean Up

  1. Delete the StatefulSet and associated resources:

    kubectl delete statefulset mongodb
    kubectl delete service mongodb-service