Skip to content

KubernetesAssistant : improve detection of ready containers in pod #1051

@dcdh

Description

@dcdh

Using the KubernetesAssistant (or OpenshiftAssistant) we can programmatically wait for a pod to be ready by using the method: awaitApplicationReadinessOrFail

This method use another one called isRunning(Pod pod) to detect if the Pod is running.

Currently the implementation is:

private boolean isRunning(Pod pod) {
    return "running".equalsIgnoreCase(pod.getStatus().getPhase());
}

However, after multiple manual tests, the check made by the isRunning method is inadequate.

Inadequate in term of the main objective of the method awaitApplicationReadinessOrFail because we want to know if the pod is ready meaning that each containers in the pod are ready.

Next, I've noticed that when the phase return running it does not mean that all containers in pod are ready (ie the readiness probe is ok for each of them).

So, having a pod phase defined to running means that containers have been started with readiness probe currently not check and the pod is in "Not ready" state displayed on the web console. Furthermore after all readiness probes are ok the phase will also return running.

So I propose this implementation instead which will check that all containers in the pod are ready:

private boolean isRunning(Pod pod) {
	return pod.getStatus()
			.getContainerStatuses()
			.stream()
			.allMatch(ContainerStatus::getReady);
}

And I guess that it should be a good point to rename the method isRunning to isReady or areAllContainersReady or something else.

Eratum

I confirm this code works :)

private boolean isRunning(Pod pod) {
    Readiness.isPodReady(pod);
}

So this is working:

public void awaitApplicationReadinessOrFail() {
        await().atMost(5, TimeUnit.MINUTES).until(() -> {
                List<Pod> list = client.pods().inNamespace(namespace).list().getItems();
                return list.stream()
                    .filter(pod -> pod.getMetadata().getName().startsWith(applicationName) && !pod.getMetadata().getName().endsWith("-deploy"))
                    .filter(Readiness::isPodReady)
                    .collect(Collectors.toList()).size() >= 1;
            }
        );
}

Workaround:

Expose a route and use awaitUrl method to wait for the application to be ready.

Regards,
Damien

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions