What's the way to expose a Kubernetes deployment to the world using HTTPS on AWS?

9/20/2017

Suppose I have a deployment named app running on my Kubernetes cluster (which is running on AWS) which is defined as such:

apiVersion: apps/v1beta1 # for versions before 1.6.0 use extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

(source: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment)

I want to expose these pods to world using an AWS ELB. Additionally, it is required (and generally advisable) to serve this service over HTTPS. As a matter of convenience, I would like to leverage AWS's Certificate Manager (ACM) to get free, evergreen certificates, instead of buying and managing the certificates myself.

If I try to expose the pods by creating a service using this command: kubectl expose deployment nginx-deployment --type=LoadBalancer --port=80 --target-port=80 --name=nginx-svc

An ELB is created, but it is a TCP load balancer, completely unaware of HTTP and I am unable to set an ACM certificate to it.

How can I create the service so Kubernetes will create an HTTP load balancer and set my certificate to it?

-- Rotem Tamir
amazon-web-services
https
kubernetes

1 Answer

9/20/2017

Even though not very well documented it is indeed possible to do this. You can see on GitHub the source code of the module which is responsible for it here: https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/providers/aws/aws.go#L125

In order to utilize this feature create a YAML nginx-svc.yaml file like so:

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-west-1:<account number>:certificate/<certificate id>
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
spec:
  type: LoadBalancer
  ports:
  - port: 443
    targetPort: 80
  selector:
    app: nginx

and use kubectl to create it: kubectl create -f nginx-svc.yaml

wait a few minutes and you'll be good to go!

-- Rotem Tamir
Source: StackOverflow