Deep dive into K8s Probes
Tags: devops, mongodb, kubernetes, microservices
Published: 2024-03-02 16:48:43

## Introduction:

Kubernetes, the powerhouse of container orchestration, has revolutionized the deployment landscape. In this blog, we'll unravel the essential concepts of Readiness Probes, Liveliness Probes, and Startup Probes—three indispensable tools for guaranteeing your applications' reliability and performance in the Kubernetes ecosystem. Join us as we explore how these probes contribute to the seamless operation of your containerized applications.

## Understanding Readiness Probes:

Readiness Probes in Kubernetes play a pivotal role in ensuring that your application is prepared to handle traffic before receiving requests. 


![Readiness Probes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2z3sjct11iw2a06lqlo9.jpeg)

---

Let's illustrate this concept using a StatefulSet with a MongoDB container,  and persistent storage through volumes.


Consider the following YAML definition for a StatefulSet incorporating Readiness Probes:

```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongo-statefulset
spec:
  serviceName: "mongo"
  replicas: 3
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: mongo-container
        image: mongo:latest
        ports:
        - containerPort: 27017
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 2
        volumeMounts:
        - name: mongo-data
          mountPath: /data/db
      volumes:
      - name: mongo-data
        persistentVolumeClaim:
          claimName: mongo-pvc
```

---

In this example:

1. **Readiness Probe Configuration:**
   - `httpGet`: The probe checks the `/health` endpoint on port 8080 to determine readiness.
   - `initialDelaySeconds`: The probe starts 10 seconds after the container starts.
   - `periodSeconds`: It checks every 5 seconds thereafter.
   - `timeoutSeconds`: The probe times out if it takes more than 5 seconds to respond.
   - `successThreshold`: The container needs to succeed once to be considered ready.
   - `failureThreshold`: If the probe fails twice in a row, the container is deemed unready.

2. **MongoDB Container Configuration:**
   - Uses the latest MongoDB image.
   - Exposes port 27017 for MongoDB connections.

3. **Volume Configuration:**
   - Utilizes a persistent volume claim (`mongo-pvc`) to ensure data persistence.
   - Mounts the volume at the path `/data/db` within the container.

By implementing this StatefulSet with a Readiness Probe, you ensure that the MongoDB containers are ready to handle requests only when they've successfully passed the health check. This guards against prematurely directing traffic to an instance that might still be initializing or experiencing issues.

---

## Understanding Liveliness Probes:

Liveliness Probes come into play when ensuring containers are responsive and can restart if they become unresponsive. 


![Liveliness](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wmqghz93o71cu1j9zmap.jpeg)


---

In this scenario, let's dive into a StatefulSet again, this time using an Exec type connection for the Liveliness Probe with a MongoDB container and persistent storage.

```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongo-statefulset
spec:
  serviceName: "mongo"
  replicas: 3
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: mongo-container
        image: mongo:latest
        ports:
        - containerPort: 27017
        livenessProbe:
          exec:
            command:
            - /bin/sh
            - -c
            - mongo --eval "db.runCommand({ ping: 1 })"
          initialDelaySeconds: 15
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        volumeMounts:
        - name: mongo-data
          mountPath: /data/db
      volumes:
      - name: mongo-data
        persistentVolumeClaim:
          claimName: mongo-pvc
```

---

Here's a breakdown:

1. **Liveliness Probe Configuration:**
   - `exec`: Specifies the probe type as Exec.
   - `command`: Executes a shell command to check if the MongoDB instance is responsive using `mongo --eval "db.runCommand({ ping: 1 })"`.
   - `initialDelaySeconds`: The probe starts 15 seconds after the container starts.
   - `periodSeconds`: It checks every 10 seconds thereafter.
   - `timeoutSeconds`: The probe times out if it takes more than 5 seconds to execute.
   - `successThreshold`: The container needs to succeed once to be considered live.
   - `failureThreshold`: If the probe fails three times consecutively, the container is deemed unresponsive and is restarted.

2. **MongoDB Container Configuration:**
   - Uses the latest MongoDB image.
   - Exposes port 27017 for MongoDB connections.

3. **Volume Configuration:**
   - Utilizes a persistent volume claim (`mongo-pvc`) for data persistence.
   - Mounts the volume at the path `/data/db` within the container.

This setup ensures that if the MongoDB container becomes unresponsive, the Liveliness Probe triggers a restart, maintaining the health and availability of your application. The Exec type connection is particularly useful for executing custom commands to check the container's state.


---

## Understanding Startup Probes:


![Startup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrranzuyrq77aosn3ui0.jpeg)

---

Startup Probes are instrumental in managing the initialization phase of your application. In this exploration, let's configure a StatefulSet with a MongoDB container and persistent storage. This time, we'll employ a TCP connection type for the Startup Probe.

```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongo-statefulset
spec:
  serviceName: "mongo"
  replicas: 3
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: mongo-container
        image: mongo:latest
        ports:
        - containerPort: 27017
        startupProbe:
          tcpSocket:
            port: 27017
          initialDelaySeconds: 20
          periodSeconds: 15
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        volumeMounts:
        - name: mongo-data
          mountPath: /data/db
      volumes:
      - name: mongo-data
        persistentVolumeClaim:
          claimName: mongo-pvc
```

---

Here's a breakdown of this configuration:

1. **Startup Probe Configuration:**
   - `tcpSocket`: Specifies the probe type as TCP connection on port 27017.
   - `initialDelaySeconds`: The probe starts 20 seconds after the container starts.
   - `periodSeconds`: It checks every 15 seconds thereafter.
   - `timeoutSeconds`: The probe times out if it takes more than 5 seconds to establish a connection.
   - `successThreshold`: The container needs to succeed once to is considered started.
   - `failureThreshold`: If the probe fails five times consecutively, the container is considered unsuccessful in its startup.

2. **MongoDB Container Configuration:**
   - Uses the latest MongoDB image.
   - Exposes port 27017 for MongoDB connections.

3. **Volume Configuration:**
   - Utilizes a persistent volume claim (`mongo-pvc`) for data persistence.
   - Mounts the volume at the path `/data/db` within the container.

With this setup, the TCP connection in the Startup Probe ensures that the MongoDB container is fully initialized and ready to handle requests before it's marked as ready. Adjust the parameters as needed for your specific application requirements.

---

## Fine-Tuning Kubernetes Deployments: Maximizing Reliability with Probes

In this advanced Kubernetes deployment, we'll seamlessly integrate Readiness, Liveness, and Startup Probes to ensure robust application performance. Leveraging a StatefulSet with a MongoDB container and persistent storage, we'll follow industry standards for probe configurations.

```yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongo-statefulset
spec:
  serviceName: "mongo"
  replicas: 3
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - name: mongo-container
        image: mongo:latest
        ports:
        - containerPort: 27017
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 2
        livenessProbe:
          exec:
            command:
            - /bin/sh
            - -c
            - mongo --eval "db.runCommand({ ping: 1 })"
          initialDelaySeconds: 15
          periodSeconds: 10
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        startupProbe:
          tcpSocket:
            port: 27017
          initialDelaySeconds: 20
          periodSeconds: 15
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        volumeMounts:
        - name: mongo-data
          mountPath: /data/db
      volumes:
      - name: mongo-data
        persistentVolumeClaim:
          claimName: mongo-pvc
```

---

Breaking it down:

1. **Readiness Probe:**
   - Checks the `/health` endpoint using HTTP every 5 seconds.
   - Starts after 10 seconds, with a timeout of 5 seconds.
   - Success is defined by one successful check, and failure occurs after two consecutive failures.

2. **Liveness Probe:**
   - Executes a MongoDB ping check using an Exec type connection every 10 seconds.
   - Begins after 15 seconds, with a 5-second timeout.
   - Success is determined by one successful execution, and failure occurs after three consecutive failures.

3. **Startup Probe:**
   - Establishes a TCP connection on port 27017 every 15 seconds during startup.
   - Initiates after 20 seconds, with a 5-second timeout.
   - Success is marked by one successful connection, and failure is declared after five consecutive failures.

By incorporating these probes with industry-standard configurations, this deployment ensures a well-managed application lifecycle, from readiness to liveness and seamless startup, promoting resilience and reliability within the Kubernetes environment. Adjust the parameters based on your specific application requirements and performance characteristics.

---

## Best Practices for Kubernetes Probes:

1. **Set Appropriate Initial Delays:**
   - Ensure that the `initialDelaySeconds` parameter is carefully configured for each probe type. This delay allows the container some time to start or initialize before probes commence. Setting it too low may result in false positives, marking a container as unhealthy prematurely.

2. **Fine-Tune Periodic Checks:**
   - Adjust the `periodSeconds` parameter to strike a balance between responsiveness and resource usage. Too frequent checks may impose unnecessary load, while infrequent checks may lead to delayed detection of issues.

3. **Use Timeout Sensibly:**
   - Configure the `timeoutSeconds` parameter judiciously to match the expected response time of your application. An excessively low timeout might lead to false negatives, marking healthy containers as unhealthy due to timeout, while a high timeout may delay detection of unresponsive containers.

4. **Set Failure and Success Thresholds:**
   - Determine appropriate `failureThreshold` and `successThreshold` values. These thresholds help stabilize the probe's decision-making process. For instance, a probe might temporarily fail due to transient issues, and adjusting these thresholds can prevent unnecessary container restarts.

5. **Select the Right Probe Type:**
   - Choose the probe type that best suits your application's needs. HTTP probes are great for web services, while Exec and TCP probes offer more flexibility for custom checks. Tailor the probe type to the specifics of your application's health and readiness indicators.

6. **Log Probe Output for Troubleshooting:**
   - Enable logging for probe actions to facilitate troubleshooting. Kubernetes allows you to view the probe results, aiding in identifying issues with container health, readiness, or startup. Use this information to refine probe configurations and enhance overall application reliability.

Implementing these best practices ensures that your Kubernetes probes contribute effectively to the health, readiness, and startup behaviors of your containerized applications, promoting resilience and optimal performance.

---

## Conclusion


Kubernetes probes - including Readiness, Liveliness, and Startup probes - are indispensable tools for maintaining the health, responsiveness, and initialization of containerized applications. By carefully configuring these probes with appropriate parameters and following best practices, developers can ensure the reliability and performance of their applications in Kubernetes environments.

**Thank you to all our readers for joining us on this journey through Kubernetes probes. I hope this guide has provided valuable insights into optimizing your containerized applications for resilience and efficiency. Happy coding!**