In Red Hat OpenShift Container Platform, Certificates are used to encrypt communications to the applications exposed using Routes/Ingress as well as Web Console access. When deploying OpenShift Container Platform, the installer will automatically generate self-signed certificates which are configured for cluster use without any further customizations. While using self-signed certificates, you’ll often see security warnings about unknown certificates in most web browsers when accessing the Web Console or any application exposed via HTTPS.
It is recommended to use proper certificates, signed by a known CA to encrypt the API endpoints and applications exposed on routes. Let’s Encrypt is one viable option towards getting secure Certificates for free, the beauty of open source!. I’m running an OpenShift 4.8 cluster in my Lab environment. In OpenShift 4.x, the process of updating or changing self-signed certificates generated and the time of cluster setup has been simplified and is reasonably straightforward.
In this article we walk you through the process of getting Let’s Encrypt SSL Certificates and using it in an OpenShift 4.x cluster. The main requirements for this setup are:
- A running OpenShift / OKD 4.x Cluster
- API endpoint URL (Example – api.ocp4.example.com)
- Ingress Controller Wildcard Domain (Example – apps.ocp4.example.com)
- Access to OpenShift Cluster with oc as admin user
Step 1: Download acme.sh Project Code
We’ll use the acme.sh client tool to request for Let’s Encrypt certificates on our Bastion machine. The ACME protocol client is written purely in Shell (Unix shell) language with no dependencies on python. It has support for SAN and wildcard certificates. In fact, we will request Wildcard Let’s Encrypt certificates for our Ingress Controller Wildcard Domain.
Clone the acme.sh GitHub repository.
cd ~/
git clone https://github.com/acmesh-official/acme.sh.git
Change your current working directory to acme.sh:
cd acme.sh
Step 2: Configure DNS API / CNAME on your DNS Provider
Since we will be requesting for a Wildcard certificate, there is a need to get your DNS API credentials for automated certificates generation with acme.sh.
Requesting Let’s Encrypt Certificates
Make sure you’re logged in to Red Hat OpenShift Cluster as a user with cluster administrator permissions
$ oc whoami
system:admin
Obtain OpenShift API Endpoint fully qualified domain name and set to variable OCP_API_DOMAIN:
export OCP_API_DOMAIN=$(oc whoami --show-server | cut -f 2 -d ':' | cut -f 3 -d '/' | sed 's/-api././')
echo $OCP_API_DOMAIN
Obtain OpenShift configured Wildcard Domain and save in a variable OCP_WILDCARD_DOMAIN:
export OCP_WILDCARD_DOMAIN=$(oc get ingresscontroller default -n openshift-ingress-operator -o jsonpath='{.status.domain}')
echo $OCP_WILDCARD_DOMAIN
Create a directory where generated certificates will be saved:
export CERTDIR=$HOME/openshift_certificates
mkdir -p ${CERTDIR}
Register account with acme while replacing your_email_address@example.com with your email address.
$ ~/acme.sh/acme.sh --register-account -m your_email_address@example.com
Next step is generating Let’s Encrypt SSL certificates with google dns provider:
${HOME}/acme.sh/acme.sh --issue --dns dns_gcloud -d ${OCP_API_DOMAIN} -d *.${OCP_WILDCARD_DOMAIN} --debug
Let’s save the certs in the directory we created.
${HOME}/acme.sh/acme.sh --install-cert -d ${OCP_API_DOMAIN} -d *.${OCP_WILDCARD_DOMAIN} --cert-file ${CERTDIR}/cert.pem --key-file ${CERTDIR}/key.pem --fullchain-file ${CERTDIR}/fullchain.pem --ca-file ${CERTDIR}/ca.cer
Step 3: Install Let’s Encrypt Certificates to OpenShift Ingress Controller
OpenShift Ingress Controller consumes certificates stored in a secret object. The secret should be created in the openshift-ingress namespace.
Create a secret in the openshift-ingress project:
oc -n openshift-ingress create secret tls router-certs --cert=${CERTDIR}/fullchain.pem --key=${CERTDIR}/key.pem
Secret creation output:
secret/router-certs created
Thereafter we update the Custom Resource for the ingress controller located in the openshift-ingress-operator project and named default:
$ oc get ingresscontroller -n openshift-ingress-operator
NAME AGE
default 2d6h
Update the custom resource by running the command below:
oc -n openshift-ingress-operator patch ingresscontroller default --type=merge --patch='{"spec": { "defaultCertificate": { "name": "router-certs" }}}'
Command expected output:
ingresscontroller.operator.openshift.io/default patched
Router pods in the openshift-ingress should be restarted automatically in a short while:
$ oc get pods -n openshift-ingress
NAME READY STATUS RESTARTS AGE
router-default-7b7d5bb68f-4lzft 1/1 Running 0 2m11s
router-default-7b7d5bb68f-x44lb 1/1 Running 0 2m49s
We now have generated Let’s Encrypt SSL certificates applied on the Ingress router. The certificates also used by the applications exposed using the default route and Red Hat OpenShift Cluster Web Console and other services such as the Monitoring stack.
Cert PICTURE from browser
Step 4: Installing Certificates to the Red Hat OpenShift API Endpoint (Optional)
You can also apply the certificates in API Endpoint.
The OpenShift API Server also expects the certificates in a Secret. We should create the certificates secret in the openshift-config project.
$ oc get secret -n openshift-config
NAME TYPE DATA AGE
builder-dockercfg-nxjhg kubernetes.io/dockercfg 1 2d6h
builder-token-mc5fj kubernetes.io/service-account-token 4 2d6h
builder-token-wd9nc kubernetes.io/service-account-token 4 2d6h
default-dockercfg-t7h6m kubernetes.io/dockercfg 1 2d6h
default-token-4vsjs kubernetes.io/service-account-token 4 2d6h
default-token-gsmt9 kubernetes.io/service-account-token 4 2d6h
deployer-dockercfg-hmfmz kubernetes.io/dockercfg 1 2d6h
deployer-token-b9t58 kubernetes.io/service-account-token 4 2d6h
deployer-token-khbdh kubernetes.io/service-account-token 4 2d6h
etcd-client kubernetes.io/tls 2 2d6h
etcd-metric-client kubernetes.io/tls 2 2d6h
etcd-metric-signer kubernetes.io/tls 2 2d6h
etcd-signer kubernetes.io/tls 2 2d6h
initial-service-account-private-key Opaque 1 2d6h
pull-secret kubernetes.io/dockerconfigjson 1 2d6h
webhook-authentication-integrated-oauth Opaque 1 2d6h
Create a secret named api-certs
oc -n openshift-config create secret tls api-certs --cert=${CERTDIR}/fullchain.pem --key=${CERTDIR}/key.pem
Confirm that the secret is created successfully:
secret/api-certs created
Run the command below to apply the certs on API endpoint
oc patch apiserver cluster --type merge --patch="{\"spec\": {\"servingCerts\": {\"namedCertificates\": [ { \"names\": [ \"$OCP_API_DOMAIN\" ], \"servingCertificate\": {\"name\": \"api-certs\" }}]}}}"
How to renew the certificates generated
You’re not required to renew the certs manually since they will be renewed automatically every 60 days.
However, you can also force to renew a cert:
export OCP_API_DOMAIN=$(oc whoami --show-server | cut -f 2 -d ':' | cut -f 3 -d '/' | sed 's/-api././')
export OCP_WILDCARD_DOMAIN=$(oc get ingresscontroller default -n openshift-ingress-operator -o jsonpath='{.status.domain}')
~/acme.sh/acme.sh --renew -d ${OCP_API_DOMAIN} -d *.${OCP_WILDCARD_DOMAIN} --force
https://computingforgeeks.com/use-lets-encrypt-wildcard-certificates-on-openshift-ingress-routes/