Setting up development kubernetes cluster with Docker For Mac and SSL

8/11/2019

I'm setting up a kubernetes cluster for development with Docker for Mac. I have a few private grpc microservices and a couple Rails public REST APIs that use SSL. I want my dev environment to be as close to production as possible so I'd prefer to not need a special Dockerfile for building for dev. Can someone give me a set-by-step approach for getting SSL working with my two REST services, including how to trust the self-signed certificates so the two services can talk to each other? I'm not very familiar with SSL or TLS.

I got the HTTPS servers working with the browser using a self-signed certificate generated with:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./app1.localhost.key -out ./app1.localhost.crt -subj "/CN=app1.localhost"

and then

kubectl create secret tls app1-tls --key ./app1.localhost.key --cert ./app1.localhost.crt

Then I have nginx-ingress running and an Ingress configured like

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app1
spec:
  rules:
  - host: app1.localhost
    http:
    paths:
    - path: /
      backend:
        serviceName: app1
        servicePort: 443
  tls:
  - hosts:
    - app1.localhost
      secretName: app1-tls

I've updated my host file to map the domains to localhost.

This is working in the browser by accepting the cert in Chrome through the advanced link in the "Your connection is not private" page. However, because the certificate is not trusted in general, the services can't talk to each other. I get a RestClient::SSLCertificateNotVerified error when attempting to make a request from one to the other.

A lot of the stuff online I've found refer to the client certificate and server certificate, but I'm not sure how to generate the two certs (above I get a .crt and a .key file, is that for the client or server?). And I'm not sure how to trust them.

-- harumphfrog
docker-for-mac
https
kubernetes
nginx-ingress
ssl

1 Answer

8/12/2019

how to trust the self-signed certificates so the two services can talk to each other?

It depends on your HTTP client, for ruby it looks like:

File.open( "client_certificate.pem", 'rb' ) { |f| cert = f.read }
File.open( "client_key.pem", 'rb' ) { |f| key = f.read }
http_session.cert = OpenSSL::X509::Certificate.new(cert)
http_session.key = OpenSSL::PKey::RSA.new(key, nil)

Ingress TLS is just for server, and use self-signed certificate is a bad idea.

If you want your two services talk to each other with TLS, and don't want to config the CA/Cert/Key manually (or call it Certificate Distribution), I recommend istio, it support transparent TLS proxy between two pods.

-- menya
Source: StackOverflow