Helm charts are a popular and convenient way to support different environments on Kubernetes. My previous article, How Helm and JKube simplify Kubernetes management, part 1, explained why generating Helm charts for Java applications can be difficult and how it's made easier by Eclipse JKube, which has Maven and Gradle plugins.
In Part 1, you learned how to generate Helm charts for Java automatically without any configuration and to publish them to desired Helm registries. While a zero-configuration approach is a great way to get started, most projects tune the Eclipse JKube plugins to generate the Helm charts to meet their requirements.
This follow-up article explains how to configure Helm charts generated by JKube's Maven and Gradle plugins via various configuration options provided by Eclipse JKube.
Specifically, we will cover:
- XML
- Java properties
- Resource fragments
Then we will conclude by demonstrating how to configure your Helm registry where you store your configuration.
Assuming you completed part one, you should already have the JKube Maven plugin (available in this Github repository) in your sample project:
<dependency>
<groupId>org.eclipse.jkube</groupId>
<artifactId>openshift-maven-plugin</artifactId>
<version>${jkube.version}</version>
</dependency>
For this series of articles, we use the Maven plugin provided specifically for Red Hat Openshift. You can configure the Helm chart generated by JKube by overriding the opinionated default Helm configuration. The following sections describe how to customize charts via XML, Java properties, and resource fragments.
Edit XML to configure Helm
One way to configure a Helm chart managed by JKube is to directly edit the pom.xml
file in the JKube plugin configuration section. Override the default configuration by providing a helm
configuration option in the plugin's configuration
section. Here is an example:
<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>openshift-maven-plugin</artifactId>
<version>${jkube.version}</version>
<configuration>
<helm>
<chart>${project.artifactId}</chart>
<version>${project.version}</version>
<description>JKube Helm Maven demo Helm Chart</description>
<home>https://www.eclipse.org/jkube/</home>
<sources>
<source>https://github.com/eclipse/jkube</source>
</sources>
<maintainers>
<maintainer>
<name>Maintainer1</name>
<email>maintainer1@maintainer1.org</email>
<url>maintainer1.org</url>
</maintainer>
<maintainer>
<name>Maintainer2</name>
<email>maintainer2@maintainer2.org</email>
<url>maintainer2.org</url>
</maintainer>
</maintainers>
<icon>https://helm.sh/img/helm.svg</icon>
<keywords>eclipse,jkube,kubernetes,maven</keywords>
<sourceDir>${project.basedir}/target/classes/META-INF/jkube</sourceDir>
<outputDir>${project.basedir}/target/jkube/helm</outputDir>
<chartExtension>tar.gz</chartExtension>
<dependencies>
<dependency>
<name>ingress-nginx</name>
<version>3.16.1</version>
<repository>https://kubernetes.github.io/ingress-nginx</repository>
</dependency>
</dependencies>
</helm>
</configuration>
</plugin>
The complete set of supported configuration options is in the oc:helm documentation.
Now run OpenShift Maven Plugin's resource and the Helm goal to regenerate the YAML manifests and Helm chart. I have added the plugin configuration in a separate xml-configuration profile.
$ ./mvnw oc:resource oc:helm -Pxml-configuration
After running that command, you should be able to see this generated Helm Chart:
apiVersion: v1
name: jkube-helm-maven
home: https://www.eclipse.org/jkube/
sources:
- https://github.com/eclipse/jkube
version: 1.0.0-SNAPSHOT
description: JKube Helm Maven demo Helm Chart
keywords:
- eclipse
- jkube
- kubernetes
- maven
maintainers:
- name: Maintainer1
email: maintainer1@maintainer1.org
url: maintainer1.org
- name: Maintainer2
email: maintainer2@maintainer2.org
url: maintainer2.org
icon: https://helm.sh/img/helm.svg
dependencies:
- name: ingress-nginx
version: 3.16.1
repository: https://kubernetes.github.io/ingress-nginx
Configuring Helm using Java properties
JKube also exposes the Helm configuration via Java properties. Here is an example of how to provide the configuration from the previous section using Maven properties:
<profile>
<id>property-configuration</id>
<properties>
<jkube.helm.chart>${project.artifactId}</jkube.helm.chart>
<jkube.helm.version>${project.version}</jkube.helm.version>
<jkube.helm.description>JKube Helm Maven demo Helm Chart (Properties)</jkube.helm.description>
<jkube.helm.home>https://www.eclipse.org/jkube/</jkube.helm.home>
<jkube.helm.icon>https://helm.sh/img/helm.svg</jkube.helm.icon>
<jkube.helm.type>openshift</jkube.helm.type>
<jkube.helm.sourceDir>${project.basedir}/target/classes/META-INF/jkube</jkube.helm.sourceDir>
<jkube.helm.outputDir>${project.basedir}/target/jkube/helm</jkube.helm.outputDir>
<jkube.helm.chartExtension>tar.gz</jkube.helm.chartExtension>
</properties>
</profile>
NOTE: You can't configure complex elements such as maintainers and sources via properties.
Run the OpenShift Maven Plugin's resource and the Helm goal to regenerate the YAML manifests and Helm chart. As in the previous section, I have added the plugin configuration in a separate property-configuration profile.
$ ./mvnw oc:resource oc:helm -Pproperty-configuration
You should see the generated Helm chart in the target/jkube/helm/openshift/
directory. The chart's contents should be similar to the chart generated with the xml-configuration
profile in the previous step.
Configuring Helm using resource fragments
Suppose you want to apply a CustomResource object along with your regular Kubernetes resources during the "resource and apply" phase of the OpenShift Maven Plugin's run. It is impossible to provide a custom resource via an XML configuration or property. Instead, use the third method of generating a Helm chart: JKube resource fragments.
JKube allows users to provide their Kubernetes YAML manifests in a specific directory. The manifests are automatically picked up during oc:resource goal and added to the Helm chart.
For this article, we will use the crontab CustomResource from the Kubernetes documentation. To start, apply the crontab CustomResourceDefinition on OpenShift using the command-line tool:
$ oc create -f crontab-crd.yml
customresourcedefinition.apiextensions.k8s.io/crontabs.stable.example.com created
Let's take a look at our crontab custom resource manifest. Usually, you would add this file to the src/main/jkube
directory (the default location of the resource directory). But in our case, we have configured a different resource directory (the fragments
folder in the root directory). The fragments/jkube/crontab-cr.yaml
file contains:
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
name: ${project.artifactId}
labels:
helm.sh/chart: "${project.artifactId}-${crontab.release}"
app.kubernetes.io/managed-by: "${crontab.managedby}"
spec:
cronSpec: ${crontab.spec}
image: ${crontab.image}
Note how we provide some of the values in this crontab resource fragment using fields enclosed in ${...}
. You must define these values in the Helm parameter configurations, as in the following example:
<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>kubernetes-maven-plugin</artifactId>
<version>${jkube.version}</version>
<configuration>
<resourceDir>${project.basedir}/fragments/jkube</resourceDir>
<helm>
<parameters>
<parameter>
<name>crontab.spec</name>
<value>{{ .spec | default "* * * * */5" | quote }}</value>
</parameter>
<parameter>
<name>crontab.image</name>
<value>{{ .image | default "my-awesome-cron-image" | upper | quote }}</value>
</parameter>
<parameter>
<name>crontab.release</name>
<value>{{ .Chart.Version }}</value>
</parameter>
<parameter>
<name>crontab.managedby</name>
<value>jkube</value>
</parameter>
</parameters>
</helm>
</configuration>
</plugin>
You can specify strings, Maven properties, or Helm template directives as values. Helm parameters can contain non-string fields and periods. JKube automatically resolves Maven properties in a values.yaml
file.
Run the OpenShift Maven Plugin's resource and the Helm goal to regenerate the YAML manifests and Helm chart. I have added the plugin configuration in a separate fragment-configuration
profile.
$ ./mvnw oc:resource oc:helm -Pfragment-configuration
This results in the following crontab template:
$ cat target/jkube/helm/jkube-helm-maven/openshift/templates/jkube-helm-maven-cr.yaml
---
apiVersion: stable.example.com/v1
kind: CronTab
metadata:
labels:
helm.sh/chart: "jkube-helm-maven-{{ .Chart.Version }}"
app.kubernetes.io/managed-by: {{ .Values.crontab.managedby | default "jkube" }}
app: jkube-helm-maven
provider: jkube
version: 1.0.0-SNAPSHOT
group: org.eclipse.jkube.demos
name: jkube-helm-maven
spec:
cronSpec: {{ .spec | default "* * * * */5" | quote }}
image: {{ .image | default "my-awesome-cron-image" | upper | quote }}
JKube has replaced ${...}
placeholders with values specified in the parameter
configurations. JKube also generated a values.yaml
file for later use by Helm for resolving values. You can inspect the generated values.yaml
file as follows:
$ cat target/jkube/helm/jkube-helm-maven/openshift/values.yaml
---
crontab:
managedby: jkube
Next, install this Helm chart. You should see the crontab custom resource applied to the target cluster:
$ helm install --generate-name target/jkube/helm/jkube-helm-maven/openshift/
NAME: openshift-1657293004
LAST DEPLOYED: Fri Jul 8 20:40:05 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
Check the applied crontab resource:
$ oc get crontab
NAME AGE
jkube-helm-maven 86s
$ oc get crontab jkube-helm-maven -o yaml
apiVersion: stable.example.com/v1
kind: CronTab
metadata:
annotations:
meta.helm.sh/release-name: openshift-1657293004
meta.helm.sh/release-namespace: default
labels:
app: jkube-helm-maven
app.kubernetes.io/managed-by: Helm
group: org.eclipse.jkube.demos
helm.sh/chart: jkube-helm-maven-1.0.0-SNAPSHOT
provider: jkube
version: 1.0.0-SNAPSHOT
name: jkube-helm-maven
namespace: default
resourceVersion: "43872"
uid: c7b8547e-d0c1-404f-842c-f8e265340b34
spec:
cronSpec: '* * * * */5'
image: MY-AWESOME-CRON-IMAGE
Configuring the Helm registry
Apart from configuring Helm charts, you must configure the registry to which you will push your Helm chart. Like Helm charts, Helm registries can be configured via XML configuration or properties.
I used ChartMuseum for my Helm registry. I have set up a local instance on my machine. You need to change the examples that follow to reflect your Helm registry.
If your project version is a snapshot, use the snapshotRepository
field for Helm registry configuration. Otherwise, use stableRepository
. We will use snapshotRepository
for this demo since it has a 1.0.0-SNAPSHOT Maven version:
<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>kubernetes-maven-plugin</artifactId>
<version>${jkube.version}</version>
<configuration>
<helm>
<snapshotRepository>
<name>ChartMuseum</name>
<url>http://localhost:8080/api/charts</url>
<type>CHARTMUSEUM</type>
<username>user1</username>
</snapshotRepository>
</helm>
</configuration>
</plugin>
Once you have configured your Helm registry details, run the Helm push goal:
$ ./mvnw oc:helm-push -Djkube.helm.snapshotRepository.password=secret
This should upload the Helm chart to the specified registry. You can also provide all this configuration in the form of properties, as shown in the following command:
$ ./mvnw oc:helm-push -Djkube.helm.snapshotRepository.name=ChartMuseum \
> -Djkube.helm.snapshotRepository.url=http://localhost:8080/api/charts \
> -Djkube.helm.snapshotRepository.type=CHARTMUSEUM \
> -Djkube.helm.snapshotRepository.username=user1 \
> -Djkube.helm.snapshotRepository.password=secret
It is also possible to provide registry credentials in Maven settings (~/.m2/settings.xml
) by specifying the Helm registry name and URL:
<plugin>
<groupId>org.eclipse.jkube</groupId>
<artifactId>openshift-maven-plugin</artifactId>
<version>${jkube.version}</version>
<configuration>
<helm>
<snapshotRepository>
<name>ChartMuseum</name>
<url>http://localhost:8080/api/charts</url>
<type>CHARTMUSEUM</type>
</snapshotRepository>
</helm>
</configuration>
</plugin>
You can provide Helm registry credentials in the server
section of settings.xml
. The server ID must match the Helm registry name specified in the plugin configuration. JKube can automatically infer credentials from Maven settings:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>ChartMuseum</id>
<username>user1</username>
<password>secret</password>
</server>
</servers>
</settings>
Customized JKube configurations
So far, you have learned the different methods for generating and publishing Helm charts using Eclipse JKube plugins. We demonstrated how easy it is to customize various aspects of Helm charts and registries utilizing a rich set of configuration options. Please try one or more of these options and provide feedback regarding how we can improve your experience.
For more information, check out the Eclipse JKube website. Feel free to follow us on these channels:
Last updated: October 31, 2023