Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kubernetes NGINX Ingress Controller not picking up TLS Certificates

I setup a new kubernetes cluster on GKE using the nginx-ingress controller. TLS is not working, it's using the fake certificates.

There is a lot of configuration detail so I made a repo - https://github.com/jobevers/test_ssl_ingress

In short the steps were

  • create a new cluster without GKE's load balancer
  • create a tls secret with my key and cert
  • create an nginx-ingress deployment / pod
  • create an ingress controller

The nginx-ingress config comes from https://zihao.me/post/cheap-out-google-container-engine-load-balancer/ (and looks very similar to a lot of the examples in the ingress-nginx repo).

My ingress.yaml is nearly identical to the example one

When I run curl, I get

$ curl -kv https://35.196.134.52
[...]
*    common name: Kubernetes Ingress Controller Fake Certificate (does not match '35.196.134.52')
[...]
*    issuer: O=Acme Co,CN=Kubernetes Ingress Controller Fake Certificate
[...]

which shows that I'm still using the default certificates.

How am I supposed to get it using mine?


Ingress definition

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ssl-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
    - secretName: tls-secret
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: demo-echo-service
          servicePort: 80

Creating the secret:

kubectl create secret tls tls-secret --key tls/privkey.pem --cert tls/fullchain.pem

Debugging further, the certificate is being found and exist on the server:

$ kubectl -n kube-system exec -it $(kubectl -n kube-system get pods | grep ingress | head -1 | cut -f 1 -d " ") -- ls -1 /ingress-controller/ssl/
default-fake-certificate-full-chain.pem
default-fake-certificate.pem
default-tls-secret-full-chain.pem
default-tls-secret.pem

And, from the log, I see

kubectl -n kube-system log -f $(kubectl -n kube-system get pods | grep ingress | head -1 | cut -f 1 -d " ")
[...]
I1013 17:21:45.423998       6 queue.go:111] syncing default/test-ssl-ingress
I1013 17:21:45.424009       6 backend_ssl.go:40] starting syncing of secret default/tls-secret
I1013 17:21:45.424135       6 ssl.go:60] Creating temp file /ingress-controller/ssl/default-tls-secret.pem236555242 for Keypair: default-tls-secret.pem
I1013 17:21:45.424946       6 ssl.go:118] parsing ssl certificate extensions
I1013 17:21:45.743635       6 backend_ssl.go:102] found 'tls.crt' and 'tls.key', configuring default/tls-secret as a TLS Secret (CN: [...])
[...]

But, looking at the nginx.conf, its still using the fake certs:

$ kubectl -n kube-system exec -it $(kubectl -n kube-system get pods | grep ingress | head -1 | cut -f 1 -d " ") -- cat /etc/nginx/nginx.conf | grep ssl_cert
        ssl_certificate                         /ingress-controller/ssl/default-fake-certificate.pem;
        ssl_certificate_key                     /ingress-controller/ssl/default-fake-certificate.pem;
like image 753
jobevers Avatar asked Oct 13 '17 17:10

jobevers


People also ask

How do you set a default TLS certificate for the Kubernetes nginx ingress controller?

you need to specify the default secret with the parameter --default-ssl-ceritifcate in the ingress controller, and then just remove the "secretName" option in the yalm, and it should use the default certificate.

What is TLS termination in Kubernetes?

Terminating at an external load balancer A common strategy for TLS/SSL termination and Kubernetes is to use an external load balancer such as an AWS Elastic Load Balancer or Google Cloud Load Balancer. This approach offloads the computation and management of TLS/SSL to another system.


1 Answers

Turns out that the ingress definition needs to look like:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ssl-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
    - hosts:
      - app.example.com
      secretName: tls-secret
  rules:
    - host: app.example.com
      http:
        paths:
        - path: /
          backend:
            serviceName: demo-echo-service
            servicePort: 80

The host entry under rules needs to match one of the hosts entries under tls.

like image 54
jobevers Avatar answered Oct 01 '22 04:10

jobevers