Ingress Example with TLS Termination

This example builds on the HTTP and gRPC ingress examples, adding TLS termination.

# TLS ingress example, requires the below two applications
# https://raw.githubusercontent.com/istio/istio/release-1.11/samples/bookinfo/platform/kube/bookinfo.yaml
# https://github.com/GoogleCloudPlatform/microservices-demo
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
  namespace: default
spec:
  ingressClassName: cilium
  rules:
  - host: hipstershop.cilium.rocks
    http:
      paths:
      - backend:
          service:
            name: productcatalogservice
            port:
              number: 3550
        path: /hipstershop.ProductCatalogService
        pathType: Prefix
      - backend:
          service:
            name: currencyservice
            port:
              number: 7000
        path: /hipstershop.CurrencyService
        pathType: Prefix
  - host: bookinfo.cilium.rocks
    http:
      paths:
      - backend:
          service:
            name: details
            port:
              number: 9080
        path: /details
        pathType: Prefix
      - backend:
          service:
            name: productpage
            port:
              number: 9080
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - bookinfo.cilium.rocks
    - hipstershop.cilium.rocks
    secretName: demo-cert

Create TLS Certificate and Private Key

For demonstration purposes we will use a TLS certificate signed by a made-up, self-signed certificate authority (CA). One easy way to do this is with minica. We want a certificate that will validate bookinfo.cilium.rocks and hipstershop.cilium.rocks, as these are the host names used in this example.

$ minica -domains '*.cilium.rocks'

On first run, minica generates a CA certificate and key (minica.pem and minica-key.pem). It also creates a directory called _.cilium.rocks containing a key and certificate file that we will use for the TLS configuration.

Create a Kubernetes secret with this demo key and certificate:

$ kubectl create secret tls demo-cert --key=_.cilium.rocks/key.pem --cert=_.cilium.rocks/cert.pem

Deploy the Ingress

The Ingress configuration for this demo provides the same routing as those demos but with the addition of TLS termination.

$ kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/HEAD/examples/kubernetes/servicemesh/tls-ingress.yaml

External IP address will be shown up in Ingress

$ kubectl get ingress
NAME          CLASS    HOSTS                                            ADDRESS        PORTS     AGE
tls-ingress   cilium   hipstershop.cilium.rocks,bookinfo.cilium.rocks   35.195.24.75   80, 443   6m5s

In this Ingress configuration, the host names hipstershop.cilium.rocks and bookinfo.cilium.rocks are specified in the path routing rules. The client needs to specify which host it wants to access. This can be achieved by editing your local /etc/hosts` file. (You will almost certainly need to be superuser to edit this file.) Add entries using the IP address assigned to the ingress service, so your file looks something like this:

$ sudo perl -ni -e 'print if !/\.cilium\.rocks$/d' /etc/hosts; sudo tee -a /etc/hosts \
  <<<"$(kubectl get ing tls-ingress -o=jsonpath='{.status.loadBalancer.ingress[0].ip}') bookinfo.cilium.rocks hipstershop.cilium.rocks"

Make HTTPS Requests

By specifying the CA’s certificate on a curl request, you can say that you trust certificates signed by that CA.

$ curl --cacert minica.pem -v https://bookinfo.cilium.rocks/details/1

If you prefer, instead of supplying the CA you can specify -k to tell the curl client not to validate the server’s certificate. Without either, you will get an error that the certificate was signed by an unknown authority.

Specifying -v on the curl request, you can see that the TLS handshake took place successfully.

Similarly you can specify the CA on a gRPC request like this:

# Download demo.proto file if you have not done before
$ curl -o demo.proto https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/protos/demo.proto
$ grpcurl -proto ./demo.proto -cacert minica.pem hipstershop.cilium.rocks:443 hipstershop.ProductCatalogService/ListProducts

Note

See the gRPC Ingress example if you don’t already have the demo.proto file downloaded.

You can also visit https://bookinfo.cilium.rocks in your browser. The browser might warn you that the certificate authority is unknown but if you proceed past this, you should see the bookstore application home page.

Note that requests will time out if you don’t specify https://.