Monday, July 23, 2018

Secure apps on IBM Cloud Kubernetes Service with Let's Encrypt wildcard certificates

In my recent post I explained how I enable SSL for Cloud Foundry apps on IBM Cloud with my own custom domain. Today, I focus on securing apps running in Docker containers in the Kubernetes service on IBM Cloud.The good news is that I only had to follow what is written in the documentation and in my previous blog post. Here are the details.



Prepare cluster and DNS

First, to secure apps on a Kubernetes cluster, you need to have a cluster provisioned on IBM Cloud and the app deployed. Once done, I can retrieve the cluster information including the Ingress Subdomain for that cluster:

ibmcloud cs cluster-get henriks-cluster

...
Master Location:        Frankfurt  
Ingress Subdomain:      henriks-cluster.eu-de.containers.appdomain.cloud  
Ingress Secret:         thesecretishere  
Workers:                2  
Worker Zones:           fra02  
...


I need that information to create a CNAME record that points the subdomain to the Ingress Subdomain. Thus, all DNS requests for that subdomain are resolved by the nameserver of IBM Cloud Kubernetes Service.

Get the certificate in place

Next, I obtained a new Let's Encrypt wildcard certificate by repeating the steps outlined in my previous post on that topic. Assuming that I am already connected to the K8S cluster, I could create a TLS secret by providing the certificate and private key in PEM format:


kubectl create secret tls henriks-k8s-cluster-secret --cert=/home/hloeser/certs/cs.example.com/cert1.pem --key=/home/hloeser/certs/cs.example.com/privkey1.pem

Thereafter, I created YAML file with the Ingress configuration. Here is the content which is similar to what is documented in the IBM Cloud docs:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-for-henriks-domain
spec:
  tls:
  - secretName: henriks-k8s-cluster-secret
    hosts:
    - hl.cs.example.com
    - hldjango.cs.example.com
  rules:
  - host: hl.cs.example.com

    http:
      paths:
      - path: /
        backend:
          serviceName: hldjango-service
          servicePort: 3000
  - host: hldjango.cs.example.com

    http:
      paths:
      - path: /
        backend:
          serviceName: hldjango-service
          servicePort: 3000


The secret, which we created above, is referenced and used for two hosts, "hl" and "hldjango". Thereafter, the two hosts are defined. For the sake of simplicity, both use the same Django starter app ("hldjango-service". What is left is to apply the configuration to the cluster. "ingress-cs-example-tls.yml" is the configuration file.

kubectl apply -f ingress-cs-example-tls.yml

Thereafter, my Python Django app is accessible via https://hl.cs.example.com and https://hldjango.cs.example.com, each time presenting a valid certificate.

If you have feedback, suggestions, or questions about this post, please reach out to me on Twitter (@data_henrik) or LinkedIn.