❓HOWTO: cert-manager with ingress-nginx on GKE
A few months ago, I described how to deploy Ghost on Google Cloud's Kubernetes Engine (GKE), using GCP's managed SSL offering. But that setup had some limitations, both with the managed SSL certificates as well as GCP's default ingress (which is an L7 solution).
At the time, I had assumed that managing SSL certificates any other way on Kubernetes would be too complicated. Turns out, it's actually pretty straight-forward to do this without relying on a managed offering. Besides, it's cheaper and provides more features (e.g. automatic HTTP to HTTPS redirects, HSTS support and more). Read on to find out how.
First, create your cluster. I wanted to get Kubernetes 1.6+ so I went with the rapid
release channel, but that's obviously not recommended for production workloads. I also enabled automatic upgrades and configured the default node pool with E2 instances. Finally, I also enabled auto-scaling.
Next, install helm. Part of the reason I started with a new cluster with the latest k8s was that I wanted to test drive the new helm 3 – among other things, they completely got rid of tiller, making the installation and deployment significantly simpler! For Mac, a simple brew install helm
should do the trick, otherwise check the installation guide.
Cert Manager
For certificate management, we'll use the excellent cert-manager. Installation should be as simple as:
Finally, setup both staging and production issuers (I opted for the simpler ClusterIssuer
configuration) as described here. Basically, your issuer file should look something like this:
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: your-email@example.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource used to store the account's private key.
name: letsencrypt-staging
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
Ingress NGINX
For ingress, I went with ingress-nginx. With Helm, installation was trivial:
Note that unlike the GCE Ingress (which is L7), this is an L4 Ingress. And therefore, you will need to allocate a regional static IP address (as opposed to a global reservation for L7).
Now go ahead and deploy your sites. Your ingress configuration should look something like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: floatingsun.net
http:
paths:
- backend:
serviceName: floatingsun-net
servicePort: 80
tls:
- hosts:
- floatingsun.net
secretName: floatingsun-net
Each new entry in the TLS section will trigger cert-manager to issue a certificate, and store the secret in the secretName
key. Cert-Manager will take care of renewing the certificates etc. For each new domain you want a certificate for, just add the corresponding entries under the rules and tls sections.
And that's it! If you found the post useful, please like / share.