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>
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.
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
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!
!