TLS for Kubernetes Ingress

TL;DR

Activating TLS on a Kubernetes Ingress resource.

Ingress resources are used in Kubernetes to expose stuff outside of the cluster. This stuff must be, in particular, HTTP/HTTPS stuff.

If you’re interested into enabling TLS for exposing the service, it can be done with a few configurations and it will not take long.

What you need

As it will be acting as a server, you will need:

  • the server certificate (server.crt in the following);
  • for good measure, the whole CA certificates chain up to the root CA certificate. In the following we will assume that the server certificate was generated by an intermediate CA whose certificate is in int-ca.crt and was generated by a root CA, whose certificate is in root-ca.crt;
  • the server key (server.key in the following).

We will assume everything above is available in PEM format.

Join all certificates together

Merge all certificates together, from the server one up to the root CA certificate, putting all intermediate CA certificates in the middle in the right order between the two extremes (i.e. from server to root CA).

Example:

cat server.crt int-ca.crt root-ca.crt > certificates-chain.pem

Put stuff in a TLS Secret

Certificates and the secret key have to be put inside a Kubernetes’s Secret, in particular associated to keys tls.crt and tlx.key. You can use an Opaque secret, but it’s just easier and more self-documenting to use type kubernetes.io/tls (which, by the way, also does some minimal validation that those keys are present).

There’s even a command for creating such a secret, so why not? Let’s just remember to use the certificates-chain.pem file we generated in the last section:

kubectl create secret tls -n my-namespace my-ingress-tls \
  --cert=certificates-chain.pem \
  --key=server.key

Configure the Ingress’s TLS

Last, we need to tell Kubernetes that the Ingress resource needs to be protected via TLS, by adding a tls section in the spec like this:

kind: Ingress
metadata:
  namespace: my-namespace
  ...
spec:
  tls:
  - hosts:
      - secure.example.com
    secretName: my-ingress-tls
  rules:
  - host: secure.example.com
    ...

A couple of things to watch for:

  • make sure that the namespace of the Ingress corresponds to the one for the Secret (or, well, the other way around!);
  • make sure that the hosts’s Fully Qualified Domain Names (secure.example.com in our example above) corresponds and are the same as they appear inside the server certificate. You can check this with this command:
openssl x509 -text -noout -in server.crt | grep Subject

We’re done!

Yes, we’re really done at this point! Apply the changes to the the Ingress, and you should have TLS enabled!


Comments? Octodon, , GitHub, Reddit, or drop me a line!