Skip to content

Configuring OpenShift Routes for cert-manager

After installing OpenShift Routes for cert-manager, you need to configure a cert-manager issuer and annotate your routes so that OpenShift Routes for cert-manager automatically provisions and renews their TLS certificates.

You will configure an issuer, annotate routes, and optionally mount the issued certificate into your application pods so the workload can use the same certificate as the route.

Prerequisites

You have cert-manager and OpenShift Routes for cert-manager installed in the same namespace. By default, this is in the venafi namespace.

Step 1: Configure an issuer

  1. You can use either a ClusterIssuer or a namespace-based Issuer.

The following example creates an Issuer with a self-signed CA. In production, use Enterprise Issuer instead.

```yaml title="my-ca-issuer.yaml"
apiVersion: v1
kind: Namespace
metadata:
  name: demo
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: selfsigned-issuer
  namespace: demo
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: my-ca-cert
  namespace: demo
spec:
  isCA: true
  commonName: my-ca
  secretName: my-ca-secret
  privateKey:
    algorithm: ECDSA
    size: 256
  issuerRef:
    name: selfsigned-issuer
    kind: Issuer
    group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: my-ca-issuer
  namespace: demo
spec:
  ca:
    secretName: my-ca-secret
```
  1. Apply my-ca-issuer.yaml:

    oc apply -f my-ca-issuer.yaml
    

Step 2: Create an annotated route

  1. If you used the example Issuer above, you can now use the following annotations:

    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      name: example-route
      namespace: demo
      annotations:
        cert-manager.io/issuer-group: cert-manager.io
        cert-manager.io/issuer-kind: Issuer
        cert-manager.io/issuer-name: my-ca-issuer
    spec:
      host: app.service.clustername.domain.com
    
  2. Annotate your routes:

    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      name: example-route
      namespace: demo
      annotations:
        cert-manager.io/issuer-name: my-issuer # This is the only required annotation.
        cert-manager.io/issuer-group: cert-manager.io # Optional, defaults to cert-manager.io.
        cert-manager.io/issuer-kind: Issuer # Optional, defaults to Issuer. Other options are ClusterIssuer or an External Issuer
        cert-manager.io/duration: 1h # Optional, defaults to 90 days
        cert-manager.io/renew-before: 30m # Optional, defaults to 1/3 of the total certificate duration.
        cert-manager.io/common-name: "My Certificate" # Optional, no default.
        cert-manager.io/alt-names: "mycooldomain.com,mysecondarydomain.com" # Optional, no default.
        cert-manager.io/ip-sans: "10.20.30.40,192.168.192.168" # Optional, no default.
        cert-manager.io/uri-sans: "spiffe://trustdomain/workload" # Optional, no default.
        cert-manager.io/private-key-algorithm: "ECDSA" # Optional, defaults to RSA.
        cert-manager.io/private-key-rotation-policy: "Always" # Optional, valid values are Never and Always. If a rotation policy is unset, it will never be used. Set this to `Always` unless you have a good reason not to.
        cert-manager.io/private-key-size: "384" # Optional, defaults to 265 for ECDSA and 2048 for RSA.
        cert-manager.io/revision-history-limit: "5" # Optional, controls how many CertificateRequests are preserved when certificates are (re-)issued. Set this to a low number to reduce cluster clutter. The minimum value is 1. If unset, all CertificateRequests will be kept.
        cert-manager.io/email-sans: "me@example.com,you@example.com" # Optional, no default.
        cert-manager.io/subject-organizations: "company" # Optional, no default.
        cert-manager.io/subject-organizationalunits: "company division" # Optional, no default.
        cert-manager.io/subject-countries: "My Country" # Optional, no default.
        cert-manager.io/subject-provinces: "My Province" # Optional, no default.
        cert-manager.io/subject-localities: "My City" # Optional, no default.
        cert-manager.io/subject-postalcodes: "123ABC" # Optional, no default.
        cert-manager.io/subject-streetaddresses: "1 Example St" # Optional, no default.
        cert-manager.io/subject-serialnumber: "123456" # Optional, no default.
    spec:
      host: app.service.clustername.domain.com # Will be added to the Subject Alternative Names of the CertificateRequest.
      port:
        targetPort: 8080
      to:
        kind: Service
        name: hello-openshift
    
  1. The route.Spec.TLS section of your route is now populated automatically by cert-manager.

    The route's TLS certificate will be rotated two-thirds of the way through the certificate's lifetime, or the cert-manager.io/renew-before time, before it expires.

    You can now access the website at https://app.service.clustername.domain.com, served by the route with a certificate signed by the CA from Step 1.

Step 3: (Optional) Use the certificate in your workloads

When OpenShift Routes for cert-manager issues a certificate for a route, it creates a certificate resource and a secret. You can mount this secret to a pod so your workload uses the same certificate as the route.

Certificates and secret names

OpenShift Routes for cert-manager names the certificate and secret using the pattern <route name>-cert and <route name>-tls. For example, for a route called example-route, the names are example-route-cert and example-route-tls.

If the route name exceeds 247 characters, OpenShift Routes for cert-manager trims the name and appends a hash to avoid collisions. For example, <trimmed route name>-<hash>-cert and <trimmed route name>-<hash>-tls.

The following example mounts a route's secret to a pod:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  volumes:
    - name: secret-volume
      secret:
        secretName: example-route-tls
  containers:
    - name: my-test-container
      image: registry.k8s.io/busybox
      command:
        - ls
        - "-l"
        - "/etc/secret-volume"
      volumeMounts:
        - name: secret-volume
          readOnly: true
          mountPath: "/etc/secret-volume"