OpenShift Route Support for cert-manager
This project supports automatically getting a certificate for OpenShift routes from any cert-manager Issuer.
Prerequisites:
- Ensure you have cert-manager installed through the method of your choice. But make sure you install cert-manager and openshift-routes-deployment in the same namespace. By default this is in the namespace cert-manager. For example, with the regular manifest:
oc apply -f https://github.com/jetstack/cert-manager/releases/download/v1.8.0/cert-manager.yaml
Both ClusterIssuer and namespace based Issuer are possible. Here a ClusterIssuer is used:
- For example, create the ClusterIssuer (no additional ingress class is needed for the openshift-ingress router. The example.com email must be replaced by another one):
apiVersion: v1
items:
- apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
annotations:
name: letsencrypt-prod
spec:
acme:
email: [email protected]
preferredChain: ""
privateKeySecretRef:
name: letsencrypt-prod
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- http01:
ingress: {}
oc apply -f clusterissuer.yaml
- Make sure that there is an A record on the load balancer IP or a CNAME record on the load balancer hostname in your DNS system for the HTTP-01 subdomain.
CNAME:
Name: *.service.clustername.domain.com
Alias: your-lb-domain.cloud
Usage
Install in your cluster using the static manifests:
oc apply -f https://github.com/cert-manager/openshift-routes/releases/latest/download/cert-manager-openshift-routes.yaml
If you follow the above prerequisites, use this annotations below
...
metadata:
annotations:
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-prod
...
spec:
host: app.service.clustername.domain.com
...
Annotate your routes:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: example-route
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, could be 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 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
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
Observe the route.Spec.TLS
section of your route being populated automatically by cert-manager.
The route's TLS certificate will be rotated 2/3 of the way through the certificate's lifetime, or cert-manager.io/renew-before
time before it expires.
Now the website can be called: https://app.service.clustername.domain.com
Why is This a Separate Project?
We do not wish to support non Kubernetes (or kubernetes-sigs) APIs in cert-manager core. This adds a large maintenance burden, and it's hard for us to e2e test everyone's CRDs. However, OpenShift is widely used, so it makes sense to have some support for it in the cert-manager ecosystem.
Ideally we would have contributed this controller to an existing project, e.g. https://github.com/redhat-cop/cert-utils-operator. Unfortunately, cert-manager is not really designed to be imported as a module. It has a large number of transitive dependencies that would add an unfair amount of maintenance to whichever project we submitted it to. In the future, we would like to split the cert-manager APIs and typed clients out of the main cert-manager repo, at which point it would be easier for other people to consume in their projects.
Enhancing README with full tutorial on production okd.
Worked together with Jake Sanders and the openshift slack community to test the newly repo out on a production okd cluster. Additional steps to be taken are added to the README.md. An edge + redirect route is assumed here.
release needed to make README.md instructions valid.
The manifest deployment of the cert-manager-openshift-routes mentioned in the README.md pulls from the latest release on Github which includes a security context that won't be allowed without anyuid set for the service account. Since this was removed in 857bb1481d9703d1d629a8eadb8d36113b2b92b1 i'm assuming that a run of the release process would include that commit which makes the instructions in the README.md work.
Cheers for putting this together btw, this is great.
Ignore CA as it may cause extended validation errors
The CA field in the cert-manager CertificateRequest may not be set, or be useful at all. I've had reports of having the CA set causing extendedValidation errors in openshift, so I'd rather ignore the CA field entirely for now.
default ClusterRole needs PATCH on Events
It seems that at least for certificate issuance failures that cert-manager-openshift-routes needs the ability to PATCH routes in addition to creating them:
Ignore the actual error it's trying to stick into the Event, that's certainly a separate issue. This issue is just about giving the SA the ability to do the thing.
Namespace is hardcoded
Hi,
I have modified the cert-manager-route to match the namespace where my cert-manager was installed but the application failed to work and create the certs for routes. When I checked the logs of the pod I saw that it kept searching for namespace
cert-manager
, although it is running in a different namespace.possible interop issue with new cert-manager operator version v1.10.0
We're using this plugin to configure our Routes in our OKD4 clusters and started getting a cert error (incorrect subject name) talking to the cert-manager service.
I don't see anything related in the v1.10.0 changelog so i'm not sure where it came from.
The services defined do seem to be a little odd as well (20h ago was when we pulled in the v1.10.0 update to the cert-manager operator):
I'm not sure if this is a cert-manager operator bug, a cert-manager/openshift-routes bug or just an "us" bug.
Feature: Support for ECC certs
https://cert-manager.io/docs/faq/#is-ecc-elliptic-curve-cryptography-supported indicates ECC keys can be used if the
privateKey
is properly set in theCertificate
object.It would be great if we could have access to do this through openshift-routes.
This may be related to #4.
Annotation generates CertificatesRequests repeatedly until blocked by letsencrypt
The following annotation generates CertificatesRequests in a row and Lets Encrypt block it for requesting too many certificates for the same domain.
cert-manager.io/duration: 2160h cert-manager.io/issuer-kind: ClusterIssuer cert-manager.io/issuer-name: letsencrypt-clusterissuer cert-manager.io/renew-before: 360h
Can the plugin be configured to use a wildcard certificate?
Judging by description, this plugin issues a multi-domain certificate that includes SANs from each route host. But can it somehow generate one wildcard certificate to cover all routes at once? (By the way this question is connected with the DNS validation, since wildcard certificates do not support HTTP validation)
Support for the route subdomain enhancement
Upcoming OpenShift releases (maybe 4.11) support to specify
.spec.subdomain
in OpenShift Route resources instead of.spec.host
. The.spec.subdomain
value will be extended by the Routers domain..spec.host
will not be filled for such routes. The hostname(s) can be found in.status.ingress[].host
. Multiple OpenShift Routers can expose a single Route - so multiple host values can exist.Enhancement docs: https://github.com/openshift/enhancements/blob/master/enhancements/ingress/route-subdomain.md