Kubernetes Startup Probes - Examples & Common Pitfalls

Levent Ogut
Minute Read

Kubernetes brought an excellent deployment platform to work on. Even monolithic applications can be run in a container. For some of these monolithic applications and for some microservices, a slow start is a problem. Even if we configure readiness and liveness probes using initialDelaySeconds, this is not an ideal way to do this. For this specific problem, startup probes are developed.

Kubernetes Probes Series

Probes

Probes are executed by kubelet to determine pods' health.

All three types of probes have common settings to configure.

  • initialDelaySeconds: How many seconds to wait after the container has started (default: 0)
  • periodSeconds: Wait time between probe executions (default: 10)
  • timeoutSeconds: Timeout of the probe (default: 1)
  • successThreshold: Threshold needed to mark the container healthy. (default: 1)
  • failureThreshold: Threshold needed to mark the container unhealthy. (default: 3)
  • Configuring these parameters vital and crucial.

    Exec Probe

    Exec probe runs a command inside the container as a health check; the command's exit code determines the success.

    startupProbe:
      initialDelaySeconds: 1
      periodSeconds: 5
      timeoutSeconds: 1
      successThreshold: 1
      failureThreshold: 1
      exec:
        command:
          - cat
          - /etc/nginx/nginx.conf
    

    TCP Probe

    TCP probe checks if the specified port is open or not; an open port points to success.

    startupProbe:
      initialDelaySeconds: 1
      periodSeconds: 5
      timeoutSeconds: 1
      successThreshold: 1
      failureThreshold: 1
      tcpSocket:
        host:
        port: 80
    

    HTTP Probe

    HTTP probe sends an HTTP GET request with defined parameters.

    HTTP Probe has additional options to configure.

  • host: Host/IP to connect to (default: pod IP)
  • scheme: Scheme to use when making the request (default: HTTP)
  • path: Path
  • httpHeaders: An array of headers defined as header/value tuples.
  • port: Port to connect to
  • Tip: Host header should be set in httpHeaders.

            startupProbe:
              initialDelaySeconds: 1
              periodSeconds: 2
              timeoutSeconds: 1
              successThreshold: 1
              failureThreshold: 1
              httpGet:
                host:
                scheme: HTTP
                path: /
                httpHeaders:
                - name: Host
                  value: myapplication1.com
                port: 80
              initialDelaySeconds: 5
              periodSeconds: 5
    

    Startup Probes in Kubernetes

    Startup probes are a newly developed feature supported as a beta in Kubernetes v.1.18.
    These probes are very useful on slow-start applications; it is much better than increasing initialDelaySeconds on readiness or liveness probes.
    Startup probe allows our application to become ready, joined with readiness and liveness probes, it can dramatically increase our applications' availability.

    Example: Sample Nginx Deployment

    Let's deploy Nginx as a sample app and see startup probes in action.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: k8s-probes
      labels:
        app: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
            - name: nginx
              image: nginx
              ports:
                - containerPort: 80
              startupProbe:
                initialDelaySeconds: 1
                periodSeconds: 2
                timeoutSeconds: 1
                successThreshold: 1
                failureThreshold: 1
                exec:
                  command:
                    - cat
                    - /etc/nginx/nginx.conf
    

    Create a file and paste the above, if you named the file k8s-probes-deployment.yaml and apply it with kubectl apply -f k8s-probes-deployment.yaml command.

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: nginx
      name: nginx
      namespace: default
    spec:
      ports:
        - name: nginx-http-port
          port: 80
      selector:
        app: nginx
      sessionAffinity: None
      type: NodePort
    

    Create a file and paste the above, if you named the file k8s-probes-svc.yaml and apply it with kubectl apply -f k8s-probes-svc.yaml command.

    Common Pitfalls for Startup Probes

    Although it is great to have such a probe, especially on a legacy application or any application that might take a while to become ready, it is quite important that parameters must be correctly configured. Otherwise, it can break our application and availability.

    Restart Loop

    Startup probes - if misconfigured- can cause a loop of restarts. Let's assume we have an application running on java, and this application takes a while to become ready. If we don't allow enough time for the startup probe to get a successful response, the kubelet might restart the container prematurely, causing a loop of restarts.

    Troubleshooting Startup Probes

    After applying the deployment file, we should see the pod is up and running; let's have a look.

    kubectl get pods
    

    We can see that the pod is up and running.

    NAME                          READY   STATUS    RESTARTS   AGE
    k8s-probes-6cbf7ccbf8-97hz5   1/1     Running   0          7s
    

    Have a look at the events using the kubectl describe pods command.

    kubectl describe pods k8s-probes-6cbf7ccbf8-97hz5
    

    Let's scroll down to events.

    Events:
      Type    Reason     Age   From               Message----------------
      Normal  Scheduled  3s    default-scheduler  Successfully assigned default/k8s-probes-6cbf7ccbf8-97hz5 to k8s-probes
      Normal  Pulling    2s    kubelet            Pulling image "nginx"
      Normal  Pulled     1s    kubelet            Successfully pulled image "nginx" in 925.688112ms
      Normal  Created    1s    kubelet            Created container nginx
      Normal  Started    1s    kubelet            Started container nginx
    

    As you can see, the probe was successful, and no error or warning event is recorded.

    Let's check the applied configuration.

    kubectl describe pods k8s-probes-6cbf7ccbf8-qcpt7 | grep Startup
    

    We can see that the startup probe is configured with the parameters we have set.

        Startup:        exec [cat /etc/nginx/nginx.conf] delay=1s timeout=1s period=2s #success=1 #failure=1
    

    Now change the command parameter to /etc/nginx/nginx.conf-dont-exists on the deployment file and apply with kubectl apply -f k8s-probes-deployment.yaml.

    Let's check the events of the pod.

    kubectl describe pods k8s-probes-5fcc896b6f-97wpg
    

    Let's scroll down to events.

    ...
    Events:
      Type     Reason     Age                     From               Message----------------
      Normal   Scheduled  13m                     default-scheduler  Successfully assigned default/k8s-probes-5fcc896b6f-97wpg to k8s-probes
      Normal   Pulled     13m                     kubelet            Successfully pulled image "nginx" in 944.990287ms
      Normal   Pulled     12m                     kubelet            Successfully pulled image "nginx" in 972.83673ms
      Normal   Pulled     12m                     kubelet            Successfully pulled image "nginx" in 958.559546ms
      Normal   Pulled     11m                     kubelet            Successfully pulled image "nginx" in 1.056812046s
      Normal   Created    11m (x4 over 13m)       kubelet            Created container nginx
      Normal   Started    11m (x4 over 13m)       kubelet            Started container nginx
      Warning  Unhealthy  11m (x4 over 13m)       kubelet            Startup probe failed: cat: /etc/nginx/nginx.conf-dont-exists: No such file or directory
      Normal   Pulling    9m44s (x5 over 13m)     kubelet            Pulling image "nginx"
      Normal   Killing    8m21s (x5 over 12m)     kubelet            Container nginx failed startup probe, will be restarted
      Warning  BackOff    3m41s (x13 over 7m16s)  kubelet            Back-off restarting the failed container
    

    As you can see startup probe executed the command; however, due to a non-existent file, the command returned a non-zero exit code.

    Conclusion

    Startup probes are very helpful to determine our application has started correctly.
    We have explored the config options on a sample Nginx application; we have checked the configuration file as a probe; this is an example of a dynamic configuration generation application, i.e., assume that Nginx configuration is generated dynamically using etcd or similar key-value store.
    Although very useful, we have also explored the side effects of the startup probes. Make sure you allow enough time to let your application startup.

    Further Reading

    Photo by Braden Collum on Unsplash

    Sign up for our newsletter

    Be the first to know about new features, announcements and industry insights.