In this post (and future posts) we will continue to look into questions our clients have asked about using Docker Enterprise that have prompted us to do some further research and/or investigation. Here we are going to look into the options for enabling secure communications with our applications running under Kubernetes container orchestration on a Docker Enterprise cluster.
LoadBalancer type of a service in Kubernetes is available if you are using one of the major public clouds, AWS, Azure or GCP, via their respective cloud provider implementations. An
Ingress resource is available on any Kubernetes cluster including both on-premises and in the cloud. Both
Ingress provide the capability to terminate SSL traffic. In this post will show how this is accomplished with an AWS
Create a Deployment
Let’s start by creating a deployment with two replicas of a pod with one container using the
nginx:1.15 image from Docker Hub. By default, an NGINX container listens on TCP port 80 (HTTP).
kind: Deployment apiVersion: apps/v1 metadata: name: kens-deployment spec: selector: matchLabels: app: kens-app replicas: 2 template: metadata: labels: app: kens-app spec: containers: - name: nginx image: nginx:1.15 ports: - containerPort: 80
To create the NGINX deployment, we just need to apply the above manifest.
ken$ kubectl apply -f kens-deployment.yml deployment.apps/kens-deployment created ken$ kubectl get all NAME READY STATUS RESTARTS AGE pod/kens-deployment-7ff87d5f69-5s22g 1/1 Running 0 6s pod/kens-deployment-7ff87d5f69-qlbzd 1/1 Running 0 6s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/kens-deployment 2 2 2 2 7s NAME DESIRED CURRENT READY AGE replicaset.apps/kens-deployment-7ff87d5f69 2 2 2 7s
Get a Certificate
SSL requires a certificate. Since we are using AWS, the certificate we use for this load balancer must exist in the AWS Certificate Manager. You can either request a certificate from AWS or you can import one from your preferred certificate authority (CA). In either case, you will need access to your DNS provider to validate the domain name(s) you use in the certificate. In this case we’ll import a wildcard certificate for *.lab.capstonec.net issued by GoDaddy. Make sure to request or import the certificate in the region your Docker Enterprise cluster resides. You will need the ARN for this certificate (see below) for the annotations metadata for the service you create. (For a list of all the AWS LoadBalancer annotations, see Cloud Providers – AWS in the Kubernetes documentation.)
Create an HTTPS Service
Next we will create a service that accepts HTTPS (TCP port 443) traffic on an AWS load balancer (ELB) and routes it using HTTP (TCP port 80) to a pod with a label of type
app and a value of
We are now ready to create the manifest for the NGINX service. We want our end users to access our NGINX deployment via HTTP and HTTPS so we need the load balancer to accept traffic on TCP ports 80 and 443. Our NGINX deployment accepts HTTP so we will need to terminate SSL at the load balancer and forward all of the backend traffic as HTTP to our pods.
kind: Service apiVersion: v1 metadata: name: kens-service annotations: service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-east-1:123456789012:certificate/0be2e3b9-bc43-4159-8369-d2de55d8ac43" service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" spec: type: LoadBalancer selector: app: kens-app ports: - name: http protocol: TCP port: 80 targetPort: 80 - name: https protocol: TCP port: 443 targetPort: 80
To create our NGINX service, we just need to apply the manifest above. And, we will see our service along with the IP address of the service within the cluster and the DNS name (A record) of the public interface of the AWS ELB created.
ken$ kubectl apply -f kens-service.yml service/kens-service created ken$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kens-service LoadBalancer 10.96.234.74 a88dc79a7338a11e9bd4c0242ac11000-243518521.us-east-1.elb.amazonaws.com 80:33432/TCP,443:34074/TCP 3s
Add a DNS Entry
We want to access this service at https://ken-nginx.lab.capstonec.net so we will need to add a CNAME record to DNS that points to the DNS name supplied by AWS for the load balancer created. In order to keep your browser happy, the DNS name you use has to match the certificate you used. In this example, the wildcard certificate we used is for *.lab.capstonec.net which matches our DNS entry, ken-nginx.lab.capstonec.net.
Access Our HTTPS Service
Once we add the DNS entry, we can use our browser to access https://ken-nginx.lab.capstonec.net. You will notice the browser has made a secure connection and we’re getting to the default webpage of an NGINX container.
Issues with LoadBalancer
There are a couple of issues with this method. First, it’s only available on several public cloud providers today. It’s not available on-premises. Second, the annotations used for each cloud provider are different. As a result, this method is not portable between providers or between providers and on-premises. This also requires one load balancer per service which can become expensive from both a cost and a management perspective if you have a lot of services.
In this post we’ve looked at implementing SSL termination for an HTTP/HTTPS application using an AWS
LoadBalancer. Next time we will do the same thing with an Azure
LoadBalancer. And we’ll follow that with an
Do you need help with containers, cloud and/or DevOps? Capstone IT is here to help. We bring years of enterprise IT experience to help you with your digital transformations.