Using Quarkus Cert-Manager
The Quarkus Cert-Manager extension supports generating an X.509 certificate with the help of the Certificate and Issuer CRD resources handled by the Cert-Manager. When these CRD resources are deployed on the cluster, the Cert-Manager will process them to populate a Secret containing for example a: CA certificate, private key, server certificate, or java keystores, etc.
Under the hood, this extension uses Dekorate to generate all the Cert-Manager manifests at build time.
Before getting started, make sure you’re using the right Quarkus Helm version that is compatible with the Quarkus version you’re using in your project. See the following table to see the compatibility among versions:
Quarkus Cert-Manager Version | Quarkus Version |
---|---|
0.0.2 |
Quarkus 2.12+ |
0.0.1 |
Quarkus 2.12+ |
Create a Quarkus application with the Cert-Manager extension
In this example, we’ll create a Quarkus application with the Quarkus Cert-Manager and the Quarkus Kubernetes extensions by running the following command:
mvn io.quarkus.platform:quarkus-maven-plugin:2.16.0.Final:create \
-DprojectGroupId=org.acme \
-DprojectArtifactId=certmanager-quickstart \
-DclassName="org.acme.quickstart.GreetingResource" \
-Dpath="/hello" \
-Dextensions="resteasy-reactive,kubernetes,certmanager"
cd certmanager-quickstart
If you already have your Quarkus project configured, you can add the certmanager
extension to your project by running the following command in your project base directory:
./mvnw quarkus:add-extension -Dextensions="certmanager"
This command will add the following dependency to your pom.xml
file:
<dependency>
<groupId>io.quarkiverse.certmanager</groupId>
<artifactId>quarkus-certmanager</artifactId>
<version>0.0.2</version>
</dependency>
Once we add the Quarkus Cert-Manager extension to your project, you can now generate the resources by running the following Maven command:
./mvnw clean package
And next, we need to provide the certificate configuration. The minimal information that the extension needs is:
* secretName
: the name of the Kubernetes Secret resource that will include the Cert-Manager generated files.
* the Issuer that represents the certificate authority (CA). See all the supported options in the Issuer section.
For all the configuration options, please go to the Configuration guide.
The minimal configuration can be provided using the properties file and the following keys:
quarkus.certificate.secret-name=tls-secret
# The selfSigned issuer:
quarkus.certificate.self-signed.enabled=true
This configuration will generate up to two resources under the target/kubernetes/kubernetes.yml
file that should look like this:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: kubernetes-example
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: kubernetes-example
spec:
encodeUsagesInRequest: false
isCA: false
issuerRef:
name: kubernetes-example
secretName: tls-secret
The Quarkus Cert-Manager extension will add, part of the Deployment, a volume mounted from the secret that contains the Cert-Manager generated files to allow the application to access them and to configure the HTTPS/TLS endpoint:
apiVersion: apps/v1
kind: Deployment
metadata:
name: kubernetes-example
spec:
replicas: 1
template:
spec:
containers:
- name: kubernetes-example
volumeMounts:
- mountPath: /etc/certs
name: volume-certs
readOnly: true
volumes:
- name: volume-certs
secret:
optional: false
secretName: tls-secret
Moreover, the Quarkus Cert-Manager extension will also autoconfigure the application to accept SSL connections. By default, it will autoconfigure only the Ingress/Route resource if exposed, otherwise, it will enable the HTTPS/TLS configuration for the internal communications of the application. This configuration can be controlled using the property quarkus.certificate.autoconfigure
which values:
-
(Default) AUTOMATIC: It will secure Ingress/Route resources if exposed, otherwise the HTTP endpoints.
-
NONE: It won’t autoconfigure anything.
-
ALL: It will secure the HTTP endpoints and also the Ingress/Route resources if exposed.
-
HTTPS_ONLY: It will secure only the HTTP endpoints.
-
CLUSTER_ONLY: It will secure only the Ingress/Route resources. It will throw an exception if it was not exposed.
For example, if you want to secure both the internal HTTPs connections and the ingress resource by setting the property quarkus.certificate.autoconfigure=ALL
, it will update the Ingress resource as follows if the property quarkus.kubernetes.ingress.expose
is true:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
...
spec:
rules:
...
tls:
- hosts:
- kubernetes-example.com
- localhost
secretName: tls-secret
And it will also autoconfigure the HTTP SSL configuration part of the Deployment resource:
apiVersion: apps/v1
kind: Deployment
metadata:
...
name: quarkus-certmanager-integration-tests-certmanager-ssl
spec:
replicas: 1
selector:
...
template:
...
spec:
containers:
- env:
- name: KUBERNETES_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_FILE_TYPE
value: PKCS12
- name: QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: pkcs12-pass
- name: QUARKUS_HTTP_SSL_CERTIFICATE_KEY_STORE_FILE
value: /etc/certs/keystore.p12
Securing Resources
When securing your resources, it’s important to validate that the requests are coming from known host names. For this purpose, we can use the dnsNames
property which is part of the certificate configuration. For example, by adding the following quarkus.certificate.dns-names
property (it’s a comma separated list of strings):
quarkus.certificate.dns-names=foo.bar.com
The certificate will only allow requests accessing the server host foo.bar.com
. Remark: If the DNS Host name does not exist, then you will get an error.
Note that the applications in Kubernetes can be publicly exposed using Ingress resources, for example:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kubernetes-example
spec:
rules:
- host: foo.bar.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: kubernetes-example
port:
number: 8080
tls:
- hosts:
- foo.bar.com
secretName: tls-secret # < cert-manager will store the created certificate in this secret.
Issuers
The Issuer
is a Kubernetes resource that represents a certificate issuing authority that can generate signed certificates by honoring certificate signing requests. All cert-manager certificates require a referenced issuer to attempt to honor the request.
The supported issuers of this extension are SelfSigned, CA, Vault, and IssuerRef.
Only one issuer must be set between |
SelfSigned
Using the SelfSigned issuer, the certificate will sign itself using the given private key. To use the SelfSigned issuer, you need to add the following key property:
quarkus.certificate.self-signed.enabled=true
CA
Using the CA issuer, the certificate and private key are stored inside the cluster as a Kubernetes Secret and will be used to sign incoming certificate requests. To use the CA issuer, you need to add the following key properties:
quarkus.certificate.ca.secret-name=ca-key-pair
When this certificate is installed in the cluster, Cert-Manager will issue the certificate and generate the CA secret resource ca-key-pair
which the following content:
apiVersion: v1
kind: Secret
metadata:
name: ca-key-pair
data:
tls.crt: <auto generated encrypted data>
tls.key: <auto generated encrypted data>
Vault
Using the Vault issuer, the certificate will be issued by the certificate authority Vault. To use the Vault issuer, you need the following key properties:
quarkus.certificate.vault.server=https://vault.example.com:8200
quarkus.certificate.vault.path=my_pki_mount/sign/my-role-name
# Any of the auth mechanisms to login into Vault:
## 1.- Via token secret resource reference:
quarkus.certificate.vault.auth-token-secret-ref...
## 2.- Via using Application Role:
quarkus.certificate.vault.auth-app-role...
## 3.- Via using Kubernetes service account:
quarkus.certificate.vault.auth-kubernetes...
Using a pre-existing issuer
To use a pre-existing issuer type that is separately installed in the cluster, you can use the issuerRef
type. For example:
quarkus.certificate.issuer-ref.name=my-issuer
quarkus.certificate.issuer-ref.kind=ClusterIssuer
In this example, we are using a ClusterIssuer resource that is part of the Cert-Manager API and that should have previously been installed in the cluster.
Configuration Reference
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Type |
Default |
|
---|---|---|
The name of the certificate resource to be generated. If not provided, it will use the default name for the application resources. Environment variable: |
string |
|
SecretName is the name of the secret resource that will be automatically created and managed by this Certificate resource. It will be populated with a private key and certificate, signed by the denoted issuer. Environment variable: |
string |
required |
CommonName is a common name to be used on the Certificate. The CommonName should have a length of 64 characters or fewer to avoid generating invalid CSRs. Environment variable: |
string |
|
The lifetime of the Certificate. Environment variable: |
string |
|
How long before the currently issued certificate’s expiry cert-manager should renew the certificate. The default is 2⁄3 of the issued certificate’s duration. Environment variable: |
string |
|
The list of Subject Alternative Names. Environment variable: |
list of string |
|
The list of IP address subjectAltNames to be set on the Certificate. Environment variable: |
list of string |
|
The list of URI subjectAltNames to be set on the Certificate. Environment variable: |
list of string |
|
The list of email subjectAltNames to be set on the Certificate. Environment variable: |
list of string |
|
If true, it will mark this Certificate as valid for certificate signing. Environment variable: |
boolean |
|
The set of x509 usages that are requested for the certificate. Environment variable: |
list of string |
|
Environment variable: |
boolean |
|
Environment variable: |
string |
|
Environment variable: |
|
|
The reference to the issuer for this certificate This configuration section is optional |
Type |
Default |
Environment variable: |
string |
required |
Environment variable: |
string |
|
Environment variable: |
string |
|
The CA issuer configuration This configuration section is optional |
Type |
Default |
Environment variable: |
string |
required |
Environment variable: |
list of string |
|
The Vault issuer configuration This configuration section is optional |
Type |
Default |
Environment variable: |
string |
required |
Environment variable: |
string |
required |
Environment variable: |
string |
|
Environment variable: |
string |
required |
#quarkus-certificate_quarkus.certificate.vault.auth-token-secret-ref This configuration section is optional |
Type |
Default |
Environment variable: |
string |
required |
Environment variable: |
string |
required |
Environment variable: |
string |
required |
Environment variable: |
string |
required |
Environment variable: |
string |
required |
Environment variable: |
string |
required |
Environment variable: |
|
|
Environment variable: |
|
|
Environment variable: |
|
|
Environment variable: |
int |
|
#quarkus-certificate_quarkus.certificate.vault.auth-app-role.secret-ref This configuration section is optional |
Type |
Default |
Environment variable: |
string |
required |
Environment variable: |
string |
required |
Environment variable: |
string |
required |
Environment variable: |
string |
required |
The self-signed issuer configuration This configuration section is optional |
Type |
Default |
Environment variable: |
boolean |
|
Environment variable: |
list of string |
|
Full X509 name specification (https://golang This configuration section is optional |
Type |
Default |
Environment variable: |
list of string |
|
Environment variable: |
list of string |
|
Environment variable: |
list of string |
|
Environment variable: |
list of string |
|
Environment variable: |
list of string |
|
Environment variable: |
list of string |
|
Environment variable: |
list of string |
|
Environment variable: |
string |
|
The Keystores generation configuration This configuration section is optional |
Type |
Default |
#quarkus-certificate_quarkus.certificate.keystores.jks This configuration section is optional |
Type |
Default |
Environment variable: |
boolean |
|
Environment variable: |
string |
required |
Environment variable: |
string |
required |
Environment variable: |
boolean |
|
Environment variable: |
string |
required |
Environment variable: |
string |
required |