I have an application on GKE that I wish to be available via HTTPS only, so I have gotten a signed certificate to secure the application using TLS.
I have checked out a lot of tutorials on how I can do this, but they all refer to using Ingress and automatically requesting the certificate using, LetsEncrypt and KubeLego. But I wish to continue using the external load balancers (the compute engine instances that google has provided me) but I just want my application to be accessible via https.
How do I apply my server.crt and server.key files to enable https.Do I apply it to the Load balancers or to the kubernetes cluster.
Ingress is probably your best bet when it comes to exposing your application over HTTPS. The Ingress resource specifies a backend service, so you will to continue exposing your application as a Kubernetes service, just with type set to ClusterIP
. This will produce a service that is "internal" to your cluster, and will be externally accessible through the Ingress once you set it up.
Now, specifically in Google Kubernetes Engine (GKE), any ingress resources defined in your cluster will be served by a Google Cloud Load Balancer, so I don't think you have to worry about deploying your own Ingress Controller (e.g. Nginx Ingress Controller).
In terms of TLS, you can use your own certificate if you have one. The certificate must be uploaded to the cluster through a Kubernetes Secret. Once that secret is defined, you can reference that secret in your Ingress definition. (https://kubernetes.io/docs/concepts/services-networking/ingress/#tls)
You can create the secret using the following command:
kubectl create secret tls my-app-certs --key /tmp/tls.key --cert /tmp/tls.crt
Once you have your secret, you can reference it in your ingress resource:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-app-ingress
spec:
tls:
- secretName: my-app-certs
backend:
serviceName: s1
servicePort: 80
Once you have created your ingress resource, GKE will configure the load balancer and give you a publicly accessible IP that you can get using:
kubectl get ingress my-app-ingress
The following is a good tutorial that walks you through Ingress on GKE:
https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer
Ingress is the easiest way. You do not need to use LetsEncrypt, you can specify your own certificate.
Ingress controller is just an NGINX proxy. If you don't want to use an ingress (why?) you'll have to create this proxy service yourself. Which will essentially be the ingress for this one service.
The solution:
Fetch your certificates during runtime, lots of people use LetsEncrypt because of how easy it is but you can store your certificates in an actually secure storage such as your cloud platform's Key Management Store, or run your own Hashicorp Vault (I recommend Hashicorp Vault, it's very good!) and then retrieve your secrets securely at runtime.
You noted that every tutorial or guide recommended to fetch them dynamically.
but they all refer to using Ingress and automatically requesting the certificate using, LetsEncrypt and KubeLego.
The reasoning for this is as follows:
https://kubernetes.io/docs/concepts/configuration/secret/#risks
Risks
In the API server secret data is stored as plaintext in etcd; therefore:
Administrators should limit access to etcd to admin users
Secret data in the API server is at rest on the disk that etcd uses; admins may want to wipe/shred disks used by etcd when no longer in use
A user who can create a pod that uses a secret can also see the value of that secret. Even if apiserver policy does not allow that user to read the secret object, the user could run a pod which exposes the secret.
If multiple replicas of etcd are run, then the secrets will be shared between them. By default, etcd does not secure peer-to-peer communication with SSL/TLS, though this can be configured.
Currently, anyone with root on any node can read any secret from the apiserver, by impersonating the kubelet. It is a planned feature to only send secrets to nodes that actually require them, to restrict the impact of a root exploit on a single node.
Therefore everyone is correctly recommending that you DO NOT USE K8s SECRETS for storing your valuable certificates as it is NOT FIT for the job.