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?
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!