kubernetes + ingress + cert-manager + letsencrypt = https

Deepak kumar Gunjetti
andcloud.io
Published in
2 min readMar 7, 2019

If you are hosting a service in Kubernetes, want to enable https secure access to your site from outside world and want to generate certificate, free of cost, as well as want automatic management and renewal of certificate, then below details can help you.

Here we will generate certificate for the service hosted in Kubernetes using cert-manager and letsencrypt.

Install helm client

brew install kubernetes-helm

Install tiller

Tiller is Helm’s server-side component, which helm client uses to deploy resources. Tiller is given admin privileges.

kubectl create serviceaccount tiller --namespace=kube-systemkubectl create clusterrolebinding tiller-admin \
--serviceaccount=kube-system:tiller --clusterrole=cluster-admin
helm init --service-account=tiller

Deploy cert-manager

kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.6/deploy/manifests/00-crds.yamlkubectl create namespace cert-managerkubectl label namespace cert-manager \
certmanager.k8s.io/disable-validation=true
helm repo updatehelm install \
--name cert-manager \
--namespace cert-manager \
stable/cert-manager

Verify the cert-manager installation

kubectl get pods --namespace cert-manager

Deploy a nginx web server

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --type=NodePort --port=80

Deploy nginx ingress controller

helm install stable/nginx-ingress --name=nginx-ingress

Get external IP address of loadbalancer nginx-ingress-controller

kubectl get svc

It will take some time for loadbalancer to get provisioned

Create DNS entry mapping your domain name with external ip address in your DNS provider

Create ingress resource for http access

cat << EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: basic-ingress
spec:
backend:
serviceName: nginx
servicePort: 80
EOF

Point the browser to DNS name

Wait for dns propogation, it takes 5–10 minutes, we need to get ‘welcome to nginx’ html web page.

Configure Let’s Encrypt Issuer

Edit the email address below, user@example.com to your email address to be used for ACME registration.

cat << EOF | kubectl apply -f -
apiVersion: certmanager.k8s.io/v1alpha1
kind: Issuer
metadata:
name: letsencrypt-prod
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: user@example.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod
# Enable the HTTP-01 challenge provider
http01: {}
EOF

Update ingress resource to enable tls

Edit the host below, example.example.com to your dns name.

cat << EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: basic-ingress
annotations:
certmanager.k8s.io/issuer: "letsencrypt-prod"
certmanager.k8s.io/acme-challenge-type: http01
spec:
tls:
- hosts:
- example.example.com
secretName: example-tls
rules:
- host: example.example.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
EOF

Check certificate is obtained from letsencrypt

kubectl get cert

wait for certificate status to become ready.

Point the browser to https://<dnsname>

we need to see web server available on https.

--

--