Monday, October 19, 2020

Updating SSL certificates in Kubernetes on Oracle Cloud

When you secure your servers and APIs, you need SSL certificates. Since they don't last for ever, you will have to update them every year, or every other year.

In OKE (Kubernetes on Oracle Cloud), there are two slightly different ways of doing this, depending on the kind of component you are using. Unfortunately, the Oracle documentation does not describe how to update SSL certificates in Kubernetes. 

Update an Ingress controller 

An ingress that is used for SSL termination looks something like this: 

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: my-ing
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
      tls:
      - secretName: my-ssl-secret-name
      rules:
      - http:
          paths:
          - backend:
              serviceName: my-backend-svc
              servicePort: 8088
The Oracle documentation has a clear description of how to setup an ingress controller with TLS. Basically you create an ingress controller and a TLS secret and apply an ingress.yaml.  Note that when you check the load balancer in the OCI console that is associated with the ingress, there is no SSL certificate listed there, this is completely handled from within the Kubernetes cluster.

There is no mention of how to update the certificate but that is actually very simple: you can update the values in the existing Kubernetes secret (for example using the dashboard or a script) and the ingress controller will pick up the new certificate automatically. 

Update a service of type Load Balancer

A service of type load balancer yaml looks something like this: 

kind: Service
apiVersion: v1
metadata:
  name: my-frontend-service
  annotations:
    service.beta.kubernetes.io/oci-load-balancer-ssl-ports: "443"
    service.beta.kubernetes.io/oci-load-balancer-tls-secret: my-ssl-secret-name
spec: selector:
Again, the Oracle documentation has a clear description of how to setup a service with a load balancer.  It describes a similar procedure: you create a service and secret in Kubernetes and apply this. However, because the kind of deployment is a service which specifies a load balancer, the certificate is picked up by the OCI Load Balancer and copied there.

Again there is no mention of how to update the certificate. When you change the value of the certificate in the secret in Kubernetes, the change is not picked up by the OCI Load Balancer. There are a lot of warnings in the documentation not to change it in OCI directly, so that is not an option.  The procedure to update the certificate is:
  1. Create a new secret with a new certificate and private key
  2. Update the service yaml to point to the new secret
  3. Apply the updated service yaml (don't create the service, just apply the updated yaml on the existing service) using kubectl apply -f [name of your yaml]
  4. Delete the previous secret.
To streamline the procedure, we have decided to create a new secret for both the ingress controller and the service so we don't end up with multiple secrets containing the same wildcard certificate and to make sure we can use one procedure for both types of components.

I hope the documentation will be updated by Oracle to include an instruction for updating SSL certificates. In the mean time I hope this post helps you when you need to update your SSL certificates. 

Happy coding! 😀