Skip to content

Latest commit

 

History

History

spring-boot-on-kubernetes-with-certmanager-example

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Spring Boot with Cert-Manager

The purpose of this Spring Boot example is to demonstrate how we can configure an HTTPS/TLS microservice using the Cert-Manager Dekorate extension.

Apart from the Dekorate Kubernetes starter dependency, the application must declare the Cert-Manager dekorate dependency part of the pom.xml file:

<dependency>
  <groupId>io.dekorate</groupId>
  <artifactId>certmanager-annotations</artifactId>
  <version>${project.version}</version>
</dependency>

Enable HTTPS transport

To enable the HTTPS/TLS transport in Spring Boot, we need to add the following properties:

server.port=8443
server.ssl.enabled=true

Next, we need to configure the Java PKCS12 Keystore properties that our Spring Boot application will use to get the Server certificate signed and the private key:

server.ssl.key-store-type=PKCS12
server.ssl.key-store=/path/to/keystore.p12
server.ssl.key-store-password=the password

Where is the keystore.p12 Keystore and what is its password? This is where Cert-Manager comes to play. This Java Keystore will be generated by the Cert-Manager on the Kubernetes platform as a secret resource. Then, what we need to do is to mount a volume from this generated secret, so the Spring Boot application can read the generated Keystore by Cert-Manager. In the following sections, we'll see how we can instruct Cert-Manager to generate the Keystore and how to configure the application to mount the secret and use it.

Generate a Self-Signed Certificate and the Keystore

Let's configure the different properties to request the generation of the Self-Signed certificate and the keystore.p12 PKCS12 Keystore file:

dekorate.certificate.secret-name=tls-secret
dekorate.certificate.self-signed.enabled=true
dekorate.certificate.keystores.pkcs12.create=true
# the secret name of the password:
dekorate.certificate.keystores.pkcs12.passwordSecretRef.name=pkcs12-pass 
dekorate.certificate.keystores.pkcs12.passwordSecretRef.key=password

Using this configuration, Dekorate will create the Certificate and Issuer resources that, once installed on the Kubernetes platform, will be used by the Certificate Manager to generate a self-signed certificate and the Keystore files within the secret tls-secret.

NOTE: As the Keystore file (pkcs12, ...) is password protected, this is then the reason why we have to create a secret including the needed password. For that purpose, we are going to create, part of the file src/main/resources/k8s/common.yml, a secret named "pkcs12-pass". The data field will include the key password where the string supersecret will be encoded in base64:

---
apiVersion: v1
kind: Secret
metadata:
  name: pkcs12-pass
data:
  # "supersecret" in base64:
  password: c3VwZXJzZWNyZXQ=
type: Opaque

To tell to Dekorate where it can find the file src/main/resources/k8s/common.yml, we will then set the property dekorate.options.input-path to specify the name folder under src/main/resources where they can be found (e.g. k8s):

dekorate.options.input-path=k8s

At this point, when we install the generated resources by Dekorate on the Kubernetes platform, Certificate Manager will generate the generated PKCS12 Keystore file named keystore.p12 within the secret tls-secret. Also, the Cert-Manager Dekorate extension will configure the Spring Boot application to automatically mount a volume using this secret tls-secret at the path /etc/certs (it can be configured using dekorate.certificate.volume-mount-path). Therefore, what we need to do next is to simply map the Keystore file and password into the Spring Boot properties server.ssl.key-store and server.ssl.key-store-password:

dekorate.kubernetes.env-vars[0].name=SERVER_SSL_KEY_STORE
dekorate.kubernetes.env-vars[0].value=/etc/certs/keystore.p12
dekorate.kubernetes.env-vars[1].name=SERVER_SSL_KEY_STORE_PASSWORD
dekorate.kubernetes.env-vars[1].secret=pkcs12-pass
dekorate.kubernetes.env-vars[1].value=password

Run the application in Kubernetes

First, make sure you have access to a Kubernetes cluster and that the Cert-Manager is deployed.

Next, we need to generate the manifests and push the application container image to our container registry:

mvn clean install -Ddekorate.push=true -Ddekorate.docker.registry=<your container registry. Example: quay.io> -Ddekorate.docker.group=<the container group. Example: user>

After executing the above command, the generated manifests, which are available at this path target/classes/META-INF/dekorate/kubernetes.yml, can be installed as such:

kubectl apply -f target/classes/META-INF/dekorate/kubernetes.yml

After a few moments, we should be able to see the secret resource named tls-secret that the Cert-Manager has created like the pkcs12 keystore file:

kubectl get secret/tls-secret -o yaml | grep keystore.p12

After some minutes, our application should be up and running:

kubectl get pods

Output:

NAME                                                    READY   STATUS    RESTARTS   AGE
spring-boot-with-certmanager-example-566546987c-nj94n   1/1     Running   0          2m23s

Let's try it out by port-forwarding the port 8443:

kubectl port-forward spring-boot-with-certmanager-example-566546987c-nj94n 8443:8443

Then, if we browse to https://localhost:8443/, we should see Hello world from HTTPS!!