Skip to content

Commit

Permalink
Support of startup probes in Kubernetes/OpenShift/Knative manifests
Browse files Browse the repository at this point in the history
  • Loading branch information
Sgitario committed Mar 8, 2023
1 parent d213830 commit e60ec35
Show file tree
Hide file tree
Showing 15 changed files with 173 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem;
import io.quarkus.kubernetes.spi.KubernetesJobBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
Expand Down Expand Up @@ -108,6 +109,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
Optional<KubernetesProbePortNameBuildItem> portName,
Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
Optional<KubernetesHealthStartupPathBuildItem> startupPath,
List<KubernetesRoleBuildItem> roles,
List<KubernetesRoleBindingBuildItem> roleBindings,
Optional<CustomProjectRootBuildItem> customProjectRoot) {
Expand All @@ -117,6 +119,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
portName,
livenessPath,
readinessPath,
startupPath,
roles, roleBindings, customProjectRoot);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem;
import io.quarkus.kubernetes.spi.KubernetesJobBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
Expand Down Expand Up @@ -104,6 +105,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
Optional<KubernetesProbePortNameBuildItem> portName,
Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
Optional<KubernetesHealthStartupPathBuildItem> startupPath,
List<KubernetesRoleBuildItem> roles,
List<KubernetesRoleBindingBuildItem> roleBindings,
Optional<CustomProjectRootBuildItem> customProjectRoot) {
Expand All @@ -113,6 +115,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
portName,
livenessPath,
readinessPath,
startupPath,
roles, roleBindings, customProjectRoot);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem;
import io.quarkus.kubernetes.spi.KubernetesJobBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
Expand Down Expand Up @@ -67,6 +68,7 @@ public static List<DecoratorBuildItem> createDecorators(String clusterKind,
Optional<KubernetesProbePortNameBuildItem> portName,
Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
Optional<KubernetesHealthStartupPathBuildItem> startupPath,
List<KubernetesRoleBuildItem> roles,
List<KubernetesRoleBindingBuildItem> roleBindings,
Optional<CustomProjectRootBuildItem> customProjectRoot) {
Expand All @@ -80,7 +82,7 @@ public static List<DecoratorBuildItem> createDecorators(String clusterKind,
result.addAll(KubernetesCommonHelper.createDecorators(project, clusterKind, name, config,
metricsConfiguration,
annotations, labels, command,
port, livenessPath, readinessPath, roles, roleBindings));
port, livenessPath, readinessPath, startupPath, roles, roleBindings));

image.ifPresent(i -> {
result.add(new DecoratorBuildItem(clusterKind, new ApplyContainerImageDecorator(name, i.getImage())));
Expand Down Expand Up @@ -127,6 +129,10 @@ public static List<DecoratorBuildItem> createDecorators(String clusterKind,
KubernetesCommonHelper.createProbeHttpPortDecorator(name, clusterKind, "readinessProbe", config.readinessProbe,
portName,
ports));
result.add(
KubernetesCommonHelper.createProbeHttpPortDecorator(name, clusterKind, "startupProbe", config.startupProbe,
portName,
ports));

// Handle init Containers
result.addAll(KubernetesCommonHelper.createInitContainerDecorators(clusterKind, name, initContainers, result));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ public class KnativeConfig implements PlatformConfiguration {
@ConfigItem
ProbeConfig readinessProbe;

/**
* The startup probe
*/
@ConfigItem
ProbeConfig startupProbe;

/**
* Prometheus configuration
*/
Expand Down Expand Up @@ -324,6 +330,10 @@ public ProbeConfig getReadinessProbe() {
return readinessProbe;
}

public ProbeConfig getStartupProbe() {
return startupProbe;
}

public PrometheusConfig getPrometheusConfig() {
return prometheus;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
import io.quarkus.kubernetes.spi.KubernetesPortBuildItem;
import io.quarkus.kubernetes.spi.KubernetesResourceMetadataBuildItem;
Expand Down Expand Up @@ -141,6 +142,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
List<KubernetesPortBuildItem> ports,
Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
Optional<KubernetesHealthStartupPathBuildItem> startupProbePath,
List<KubernetesRoleBuildItem> roles,
List<KubernetesRoleBindingBuildItem> roleBindings,
Optional<CustomProjectRootBuildItem> customProjectRoot,
Expand All @@ -157,7 +159,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
packageConfig);
Optional<Port> port = KubernetesCommonHelper.getPort(ports, config, "http");
result.addAll(KubernetesCommonHelper.createDecorators(project, KNATIVE, name, config, metricsConfiguration, annotations,
labels, command, port, livenessPath, readinessPath, roles, roleBindings));
labels, command, port, livenessPath, readinessPath, startupProbePath, roles, roleBindings));

image.ifPresent(i -> {
result.add(new DecoratorBuildItem(KNATIVE, new ApplyContainerImageDecorator(name, i.getImage())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import io.dekorate.kubernetes.decorator.AddRoleBindingResourceDecorator;
import io.dekorate.kubernetes.decorator.AddSecretVolumeDecorator;
import io.dekorate.kubernetes.decorator.AddServiceAccountResourceDecorator;
import io.dekorate.kubernetes.decorator.AddStartupProbeDecorator;
import io.dekorate.kubernetes.decorator.ApplicationContainerDecorator;
import io.dekorate.kubernetes.decorator.ApplyArgsDecorator;
import io.dekorate.kubernetes.decorator.ApplyCommandDecorator;
Expand Down Expand Up @@ -80,6 +81,7 @@
import io.quarkus.kubernetes.spi.KubernetesCommandBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem;
import io.quarkus.kubernetes.spi.KubernetesJobBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
Expand Down Expand Up @@ -184,6 +186,7 @@ public static List<DecoratorBuildItem> createDecorators(Optional<Project> projec
Optional<Port> port,
Optional<KubernetesHealthLivenessPathBuildItem> livenessProbePath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessProbePath,
Optional<KubernetesHealthStartupPathBuildItem> startupPath,
List<KubernetesRoleBuildItem> roles,
List<KubernetesRoleBindingBuildItem> roleBindings) {
List<DecoratorBuildItem> result = new ArrayList<>();
Expand All @@ -201,7 +204,7 @@ public static List<DecoratorBuildItem> createDecorators(Optional<Project> projec
//Handle Probes
if (!port.isEmpty()) {
result.addAll(createProbeDecorators(name, target, config.getLivenessProbe(), config.getReadinessProbe(),
livenessProbePath, readinessProbePath));
config.getStartupProbe(), livenessProbePath, readinessProbePath, startupPath));
}

//Handle RBAC
Expand Down Expand Up @@ -706,7 +709,7 @@ private static List<DecoratorBuildItem> createAnnotationDecorators(Optional<Proj
*
* @param name The name of the deployment / container.
* @param target The deployment target
* @param the probe kind (e.g. readinessProbe, livenessProbe etc)
* @param probeKind The probe kind (e.g. readinessProbe, livenessProbe etc)
* @param portName the probe port name build item
* @paramt ports a list of kubernetes port build items
* @return a decorator for configures the port of the http action of the probe.
Expand Down Expand Up @@ -738,11 +741,14 @@ public static DecoratorBuildItem createProbeHttpPortDecorator(String name, Strin
*/
private static List<DecoratorBuildItem> createProbeDecorators(String name, String target, ProbeConfig livenessProbe,
ProbeConfig readinessProbe,
ProbeConfig startupProbe,
Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath) {
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
Optional<KubernetesHealthStartupPathBuildItem> startupPath) {
List<DecoratorBuildItem> result = new ArrayList<>();
createLivenessProbe(name, target, livenessProbe, livenessPath).ifPresent(d -> result.add(d));
createReadinessProbe(name, target, readinessProbe, readinessPath).ifPresent(d -> result.add(d));
createStartupProbe(name, target, startupProbe, startupPath).ifPresent(d -> result.add(d));
return result;
}

Expand Down Expand Up @@ -770,6 +776,18 @@ private static Optional<DecoratorBuildItem> createReadinessProbe(String name, St
return Optional.empty();
}

private static Optional<DecoratorBuildItem> createStartupProbe(String name, String target, ProbeConfig startupProbe,
Optional<KubernetesHealthStartupPathBuildItem> startupPath) {
if (startupProbe.hasUserSuppliedAction()) {
return Optional.of(new DecoratorBuildItem(target,
new AddStartupProbeDecorator(name, ProbeConverter.convert(startupProbe))));
} else if (startupPath.isPresent()) {
return Optional.of(new DecoratorBuildItem(target, new AddStartupProbeDecorator(name,
ProbeConverter.builder(startupProbe).withHttpActionPath(startupPath.get().getPath()).build())));
}
return Optional.empty();
}

private static Map<String, Integer> verifyPorts(List<KubernetesPortBuildItem> kubernetesPortBuildItems) {
final Map<String, Integer> result = new HashMap<>();
final Set<Integer> usedPorts = new HashSet<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ public enum DeploymentResourceKind {
@ConfigItem
ProbeConfig readinessProbe;

/**
* The startup probe
*/
@ConfigItem
ProbeConfig startupProbe;

/**
* Prometheus configuration
*/
Expand Down Expand Up @@ -480,6 +486,10 @@ public ProbeConfig getReadinessProbe() {
return readinessProbe;
}

public ProbeConfig getStartupProbe() {
return startupProbe;
}

public PrometheusConfig getPrometheusConfig() {
return prometheus;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ public static enum DeploymentResourceKind {
@ConfigItem
ProbeConfig readinessProbe;

/**
* The startup probe
*/
@ConfigItem
ProbeConfig startupProbe;

/**
* Prometheus configuration
*/
Expand Down Expand Up @@ -417,6 +423,10 @@ public ProbeConfig getReadinessProbe() {
return readinessProbe;
}

public ProbeConfig getStartupProbe() {
return startupProbe;
}

public PrometheusConfig getPrometheusConfig() {
return prometheus;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem;
import io.quarkus.kubernetes.spi.KubernetesJobBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
Expand Down Expand Up @@ -183,6 +184,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
List<KubernetesPortBuildItem> ports,
Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
Optional<KubernetesHealthStartupPathBuildItem> startupPath,
List<KubernetesRoleBuildItem> roles,
List<KubernetesRoleBindingBuildItem> roleBindings,
Optional<CustomProjectRootBuildItem> customProjectRoot,
Expand All @@ -202,7 +204,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
result.addAll(KubernetesCommonHelper.createDecorators(project, OPENSHIFT, name, config,
metricsConfiguration,
annotations, labels, command,
port, livenessPath, readinessPath, roles, roleBindings));
port, livenessPath, readinessPath, startupPath, roles, roleBindings));

if (config.flavor == v3) {
//Openshift 3.x doesn't recognize 'app.kubernetes.io/name', it uses 'app' instead.
Expand Down Expand Up @@ -309,6 +311,10 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, "readinessProbe", config.readinessProbe,
portName,
ports));
result.add(
KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, "startupProbe", config.startupProbe,
portName,
ports));

// Handle non-openshift builds
if (deploymentKind == DeploymentResourceKind.DeploymentConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public interface PlatformConfiguration extends EnvVarHolder {

ProbeConfig getReadinessProbe();

ProbeConfig getStartupProbe();

PrometheusConfig getPrometheusConfig();

Map<String, MountConfig> getMounts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesHealthStartupPathBuildItem;
import io.quarkus.kubernetes.spi.KubernetesInitContainerBuildItem;
import io.quarkus.kubernetes.spi.KubernetesJobBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
Expand Down Expand Up @@ -134,7 +135,9 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
Optional<ContainerImageInfoBuildItem> image, Optional<KubernetesCommandBuildItem> command,
Optional<KubernetesProbePortNameBuildItem> portName,
List<KubernetesPortBuildItem> ports, Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath, List<KubernetesRoleBuildItem> roles,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
Optional<KubernetesHealthStartupPathBuildItem> startupPath,
List<KubernetesRoleBuildItem> roles,
List<KubernetesRoleBindingBuildItem> roleBindings, Optional<CustomProjectRootBuildItem> customProjectRoot,
List<KubernetesDeploymentTargetBuildItem> targets) {

Expand All @@ -149,7 +152,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
packageConfig);
Optional<Port> port = KubernetesCommonHelper.getPort(ports, config);
result.addAll(KubernetesCommonHelper.createDecorators(project, KUBERNETES, name, config, metricsConfiguration,
annotations, labels, command, port, livenessPath, readinessPath, roles, roleBindings));
annotations, labels, command, port, livenessPath, readinessPath, startupPath, roles, roleBindings));

KubernetesConfig.DeploymentResourceKind deploymentKind = config.getDeploymentResourceKind(capabilities);
if (deploymentKind != KubernetesConfig.DeploymentResourceKind.Deployment) {
Expand Down Expand Up @@ -250,6 +253,10 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, "readinessProbe", config.readinessProbe,
portName,
ports));
result.add(
KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, "startupProbe", config.startupProbe,
portName,
ports));

// Handle remote debug configuration
if (config.remoteDebug.enabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ public void assertGeneratedResources() throws IOException {
assertThat(p.getInitialDelaySeconds()).isEqualTo(20);
assertProbePath(p, "/q/health/live");

assertNotNull(p.getHttpGet());
assertNull(p.getHttpGet().getPort());
});
assertThat(c.getStartupProbe()).isNotNull().satisfies(p -> {
assertThat(p.getInitialDelaySeconds()).isEqualTo(5);
assertProbePath(p, "/q/health/started");

assertNotNull(p.getHttpGet());
assertNull(p.getHttpGet().getPort());
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ public void assertGeneratedResources() throws IOException {
assertThat(p.getInitialDelaySeconds()).isEqualTo(20);
assertProbePath(p, "/liveness");

assertNotNull(p.getHttpGet());
assertEquals(p.getHttpGet().getPort().getIntVal(), 9090);
});
assertThat(container.getStartupProbe()).isNotNull().satisfies(p -> {
assertThat(p.getInitialDelaySeconds()).isEqualTo(5);
assertProbePath(p, "/q/health/started");

assertNotNull(p.getHttpGet());
assertEquals(p.getHttpGet().getPort().getIntVal(), 9090);
});
Expand Down
Loading

0 comments on commit e60ec35

Please sign in to comment.