Skip to content

Commit

Permalink
doc: improved spring-boot-helm example to be clear about dev and prod
Browse files Browse the repository at this point in the history
Signed-off-by: Marc Nuri <[email protected]>
  • Loading branch information
manusa committed Dec 4, 2023
1 parent 231fa10 commit ed628ab
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 108 deletions.
143 changes: 85 additions & 58 deletions quickstarts/maven/spring-boot-helm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,115 @@ description: |
Spring Boot application with a single REST endpoint.
Demonstrates how to generate Helm chart (YAML) files using Eclipse JKube's k8s:helm Maven goal.
---
# Eclipse JKube Spring Boot with YAML Quickstart
# Eclipse JKube, Spring Boot, and Helm Quickstart

This is a quickstart project to use Eclipse JKube plugin with customized yaml configurations.
This is a quickstart project to use Eclipse JKube's Kubernetes Maven Plugin with customized YAML configurations.

The project is structured to be used with the following profiles:
- [Developer (Inner Loop)](#Development-environment-(Inner-Loop))
- [Production with Helm charts (Outer Loop)](#Helm-chart-generation-(Outer-Loop))
- [Development environment (Inner Loop)](#development-environment-(inner-loop))
- [Production environment with Helm charts (Outer Loop)](#production-environment-with-helm-charts-(outer-loop))

This example assumes that you are working in a project that will be deployed to production (Outer loop) using Helm charts.

The project is also set up to be deployed to a development environment cluster (Inner loop) using JKube functionality.

## Requirements:

- JDK 8 or 11+
- JDK 17+
- Kubernetes Cluster (Minikube, OpenShift, CRC, etc.)

## YAML fragments

This project contains multiple YAML fragments with placeholders that can be used to set different values depending on the target environment.

For example, the `deployment.yaml` fragment contains (among others) a placeholder for the number of replicas:

```yaml
spec:
replicas: ${deployment.replicas}
```
## Development environment (Inner Loop)
This quickstart assumes the scenario where you have a project that will be deployed to production (Outer loop) using
Helm charts. For this purpose you would run the previously mentioned goals (`k8s:resource k8s:helm`) to generate the
charts. You might even want to configure your CI pipeline to publish the charts for you (`k8s:helm-push`)
<a id="development-environment-(inner-loop)"></a>
Let's start by analyzing the project structure for this use case.
The project `pom.xml` contains the plugin dependency in the generic `<build>` `<plugins>` section.
The plugin is not yet configured since all the default values are suitable for the inner loop scenario.

If we were to generate the Kubernetes resources (`k8s:resource`) without providing further configuration,
JKube would warn us with messages indicating that the generated resources are invalid.
This is mainly because the placeholders defined in the YAML fragments are not yet replaced with actual values.

To overcome this issue, we define a `dev` Maven profile that is active by default (unless another profile is specified).
This profile contains the required properties to replace the placeholders in the YAML fragments for this scenario.

```xml
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<helm_namespace>default</helm_namespace>
<!-- ... -->
</properties>
</profile>
</profiles>
```

However, developer might want to use JKube to test and deploy your project to a development environment
cluster (Inner loop). For this purpose, the placeholders defined for your Helm variables need to be completed with some
values. This showcases the power of JKube, because the same fragments and generated YAMLs can be used for those purposes.
With these properties configured, invoking `k8s:resource` won't log any warnings and the generated resources will be valid.

In this example you'll find an additional Maven profile `dev` that includes the values for those placeholders, so in case
you are using this in a development environment, you can also take advantage of JKube.
If you are running Minikube, you can test this by running the following commands:

```shell
$ mvn clean package k8s:apply -Pdev -Pkubernetes
eval $(minikube docker-env)
mvn clean package k8s:build k8s:resource k8s:apply
```

## Helm chart generation (Outer Loop)
This should deploy the application with a Kubernetes Service exposed as a NodePort.

To generate the helm chart with defaults run:
```shell script
mvn clean package -Pkubernetes
## Production environment with Helm charts (Outer Loop)

<a id="production-environment-with-helm-charts-(outer-loop)"></a>

For the production environment, we want to generate Helm charts instead of raw Kubernetes resources.
This way, our application can be deployed to a Kubernetes cluster using Helm.

To be able to configure the Helm chart template placeholders, we need to define a `prod` Maven profile.
This profile contains the configured Helm parameters that will be used to interpolate the Helm chart templates and generate the `values.yaml` file.

In addition, some of the default values are defined using a `values.helm.yaml` file that you can find in the `src/main/jkube` directory. The values in this file will be merged with those defined in the `pom.xml` file.

In order to generate the Helm chart, we need to invoke the `k8s:helm` goal.

```shell
mvn -Pprod clean package k8s:build k8s:resource k8s:helm
```

### Customize Chart via Maven properties
The resulting Helm chart will be located in the `target/jkube/helm/spring-boot-helm` directory.

If you're testing this in Minikube, you can deploy the Helm chart using the following command:

```shell
helm install spring-boot-helm target/jkube/helm/spring-boot-helm/kubernetes/
```

You can also override some of the values defined in the `values.yaml` file using the `--set` flag:

```shell
helm install spring-boot-helm target/jkube/helm/spring-boot-helm/kubernetes/ --set deployment.replicas=5 --set service.spec.type=NodePort
```

## Customizing Chart via Maven properties

Helm chart properties can be overridden through command line:
```shell script
mvn clean package k8s:helm -Pkubernetes -Djkube.helm.chart="Custom Chart Name" -Djkube.helm.home=https://custom.home
mvn k8s:resource k8s:helm -Pprod -Djkube.helm.chart="Custom Chart Name" -Djkube.helm.home=https://custom.home
```

### Customize Chart using configuration
## Customizing the Chart using configuration

Helm chart can also be customized through `pom.xml` plugin configuration:
```xml
Expand All @@ -74,40 +138,3 @@ Helm chart can also be customized through `pom.xml` plugin configuration:
</configuration>
</plugin>
```

## How to test

### Docker build strategy (default)
With Minikube running, perform the following commands:
```shell script
$ eval $(minikube docker-env)
$ mvn -Pkubernetes clean package
$ helm install spring-boot-helm target/jkube/helm/spring-boot-helm/kubernetes/
$ minikube service spring-boot-helm
```

Or if you want to override the replicas value:
```shell script
$ eval $(minikube docker-env)
$ mvn -Pkubernetes clean package
$ helm install spring-boot-helm target/jkube/helm/spring-boot-helm/kubernetes/ --set replicas=2
$ minikube service spring-boot-helm
```

### JIB build strategy
With Minikube running, perform the following commands:
```shell script
$ mvn -Pkubernetes clean package -Djkube.build.strategy=jib
$ eval $(minikube docker-env)
$ docker load -i target/docker/maven/spring-boot-helm/latest/tmp/docker-build.tar
$ helm install spring-boot-helm target/jkube/helm/spring-boot-helm/kubernetes/
$ minikube service spring-boot-helm
```

### OpenShift (S2I build)
With a valid OpenShift cluster, perform the following commands:
```shell script
$ mvn -Popenshift clean package
$ helm install spring-boot-helm target/jkube/helm/spring-boot-helm/openshift/
$ curl ${route-url}
```
97 changes: 49 additions & 48 deletions quickstarts/maven/spring-boot-helm/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
<version>3.1.3</version>
</parent>

<groupId>org.eclipse.jkube.quickstarts.maven</groupId>
Expand Down Expand Up @@ -75,60 +75,16 @@
<groupId>org.eclipse.jkube</groupId>
<artifactId>kubernetes-maven-plugin</artifactId>
<version>${jkube.version}</version>
<configuration>
<resources>
<labels>
<all>
<testProject>spring-boot-with-yaml-label-for-all</testProject>
</all>
</labels>
</resources>
<helm>
<!-- <chart>This is a Test</chart>-->
<parameters>
<parameter>
<name>deployment.replicas</name>
<value>{{ .Values.deployment.replicas }}</value>
</parameter>
<parameter>
<name>deployment.annotations</name>
<value>
{{- toYaml .Values.common.annotations | nindent 4 }}
{{- toYaml .Values.deployment.annotations | nindent 4 }}
</value>
</parameter>
<parameter>
<name>service.annotations</name>
<value>
{{- toYaml .Values.common.annotations | nindent 4 }}
{{- toYaml .Values.service.annotations | nindent 4 }}
</value>
</parameter>
<parameter>
<name>helm_namespace</name>
<value>{{ .Release.Namespace }}</value>
</parameter>
</parameters>
</helm>
</configuration>

<executions>
<execution>
<phase>package</phase>
<goals>
<goal>resource</goal>
<goal>build</goal>
<goal>helm</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<helm_namespace>default</helm_namespace>
<golang_expression>n/a development</golang_expression>
Expand All @@ -137,9 +93,54 @@
<deployment.annotations>jkube.helm.sh/environment: dev&#10; jkube.helm.sh/other: value</deployment.annotations>
<deployment.resources.limits_memory/>
<deployment.resources.requests_memory/>
<service.spec.type>NodePort</service.spec.type>
<service.annotations>api.service.kubernetes.io/path: /dev</service.annotations>
</properties>
</profile>
<profile>
<id>prod</id>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>kubernetes-maven-plugin</artifactId>
<version>${jkube.version}</version>
<configuration>
<helm>
<parameters>
<parameter>
<name>deployment.replicas</name>
<value>{{ .Values.deployment.replicas }}</value>
</parameter>
<parameter>
<name>deployment.annotations</name>
<value>
{{- toYaml .Values.common.annotations | nindent 4 }}
{{- toYaml .Values.deployment.annotations | nindent 4 }}
</value>
</parameter>
<parameter>
<name>service.annotations</name>
<value>
{{- toYaml .Values.common.annotations | nindent 4 }}
{{- toYaml .Values.service.annotations | nindent 4 }}
</value>
</parameter>
<parameter>
<name>service.spec.type</name>
<value>{{ ((.Values.service).spec).type | default "ClusterIP" }}</value>
</parameter>
<parameter>
<name>helm_namespace</name>
<value>{{ .Release.Namespace }}</value>
</parameter>
</parameters>
</helm>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ metadata:
annotations:
${service.annotations}
spec:
type: NodePort
type: ${service.spec.type}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# Red Hat, Inc. - initial API and implementation
#

## n.b. this approach to define Helm template parameters is deprecated, please consider using XML or Gradle DSL configuration instead
kind: Template
parameters:
- name: deployment.resources.limits_memory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ common:
annotations:
jkube.helm.sh/common: annotation
deployment:
replicas: 1
replicas: 2
annotations:
jkube.helm.sh/annotation-1: value-1
jkube.helm.sh/annotation-2: value-2
Expand Down

0 comments on commit ed628ab

Please sign in to comment.