Cert-Manager
Dekorate 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.
To let Dekorate generate the certificate and issuer resources, simply declare the following dependency part of your pom file:
<dependency>
<groupId>io.dekorate</groupId>
<artifactId>certmanager-annotations</artifactId>
<version>4.1.4</version>
</dependency>
And provide the certificate configuration. The minimal information that the Dekorate needs are:
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 of the Cert-Manager.
The minimal configuration can be provided using the properties file and the following keys:
dekorate.certificate.secret-name=tls-secret
# The selfSigned issuer:
dekorate.certificate.self-signed.enabled=true
Or via the @Certificate
annotation:
@Certificate(secretName = "tls-secret", selfSigned = @SelfSigned(enabled = true))
public class Main {
// ...
}
This configuration will generate up to two resources under the target/classes/dekorate/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
Apart from these two resources, the Cert-Manager Dekorate extension will also configure, 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
Usage
For an application (Quarkus, Spring Boot, …) to be able to access the files mounted under /etc/certs
from the secret, the application properties must also be updated. To see a practical working example, please go to the Spring Boot with Cert-Manager example which uses a PKCS Keystore.
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 dekorate.certificate.dnsNames
property (it’s a comma separated list of strings):
dekorate.certificate.dnsNames=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.
In Dekorate, you can generate the above Ingress resource by simply adding the following key properties:
dekorate.kubernetes.ingress.host=foo.bar.com
dekorate.kubernetes.ingress.expose=true
dekorate.kubernetes.ingress.tlsSecretName=tls-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.
Note: Only one issuer must be set between selfSigned
, ca
, vault
, and issuerRef
.
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:
dekorate.certificate.selfSigned.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:
dekorate.certificate.ca.secretName=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:
dekorate.certificate.vault.server=https://vault.example.com:8200
dekorate.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:
dekorate.certificate.vault.authTokenSecretRef...
## 2.- Via using Application Role:
dekorate.certificate.vault.authAppRole...
## 3.- Via using Kubernetes service account:
dekorate.certificate.vault.authKubernetes...
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:
dekorate.certificate.issuerRef.name=my-issuer
dekorate.certificate.issuerRef.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.