Generally, I have an application that is hosted on a TomEE that has a http and https listener. I want to call https over the ELB and route the request as a https request to the TomEE.
What already works is that the ELB is receiving an https call from a public request and route it with http to the Pods. This is achieved with some annotations in the Service manifest:
apiVersion: v1
kind: Service
metadata:
name: my-app-elb
labels:
elb: my-app-elb
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws...<MY_CERT>
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
spec:
ports:
- name: https
port: 443
targetPort: app-ssl-port
protocol: TCP
selector:
app: my-app
type: LoadBalancer
Now the communication between the Service and the Pods should be done with https too.
How can this be achieved? Are there also some annotations for this or is there another way?
Unfortunately, the kubernetes Docs are very limited at this topic.
Edit: Like Symmetric suggested, the following annotation can be used:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol=https
But this seems to be only the half way. Because the Service now uses https to communicate with the Pods. But how does the Service know about the certificate/key to use for the handshake?
The certificate for the TomEE differs to the one specified in the Service manifest. So basically, there are two certificates used. One AWS certificate for the communication with the Service and one for the Pods.
The certificate of the Pods can be stored in a Secret object of kubernetes. But how the Service get a reference to this?
As an alternative approach, you could disable SSL termination on your ELB, and have all your decryption done in your pod. I use this approach in GCP. It's technically more secure, since you're not trusting the cloud provider with your unencrypted data at the LB.
It is also a fairly platform-agnostic approach, and should work if you have to migrate to bare metal or another cloud provider.
I use https://github.com/PalmStoneGames/kube-cert-manager/ to create a Secret for my certs, using Letsencrypt. This uses the DNS challenge method, so you'd give the cert-manager service access to your DNS.
It looks like this is the annotation that you need:
service.beta.kubernetes.io/aws-load-balancer-backend-protocol
From the source code, here's a description of the annotation:
// ServiceAnnotationLoadBalancerBEProtocol is the annotation used on the service
// to specify the protocol spoken by the backend (pod) behind a listener.
// If `http` (default) or `https`, an HTTPS listener that terminates the
// connection and parses headers is created.
// If set to `ssl` or `tcp`, a "raw" SSL listener is used.
// If set to `http` and `aws-load-balancer-ssl-cert` is not used then
// a HTTP listener is used.