Install NGINX Ingress Controller on Kubernetes + Let's Encrypt Cert Issuer
Dak Washbrook
Posted on November 14, 2020
This article is a perspective rewrite of the given sources that allowed me to get from point A to point B from my perspective.
Requirements:
- A Kubernetes Cluster
- Helm (https://helm.sh/docs/using_helm/)
I recommend DigitalOcean for a very affordable Kubernetes Cluster.
Click here to sign-up for Digital Ocean: https://m.do.co/c/79bf9fee3de8.
Amazon has its own Managed k8s service as well: https://aws.amazon.com/eks/.
Google (the creators of Kubernetes) has its own, very convenient and highly managed, k8s service. https://cloud.google.com/kubernetes-engine/.
Apply the latest version of the NGINX Ingress Controller
Check https://github.com/kubernetes/ingress-nginx/releases for the newest version number.
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml
Output:
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.extensions/nginx-ingress-controller created
Install the Cloud Generic Load Balancer for the Ingress
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml -n ingress-nginx
Output:
service/ingress-nginx created
// If you want all nodes to pass the health check:
$ kubectl patch svc ingress-nginx -n ingress-nginx -p '{"spec":{"externalTrafficPolicy":"Cluster"}}'
You can check on the service with:
$ kubectl get svc --namespace=ingress-nginx
Installing cert-manager + lets-encrypt
Apply the CRDs (Custom Resource Definitions)
$ kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml
Output:
customresourcedefinition.apiextensions.k8s.io/certificates.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/challenges.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/clusterissuers.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/issuers.certmanager.k8s.io created
customresourcedefinition.apiextensions.k8s.io/orders.certmanager.k8s.io created
Set a label on kube-system
namespace to enable advanced resource validation with a webhook.
$ kubectl label namespace kube-system certmanager.k8s.io/disable-validation="true"
Output:
namespace/kube-system labeled
If you do not have Helm installed on your client and k8s cluster. Before the next step, I had to install the Helm client (https://helm.sh/docs/using_helm/) and run the following command:
$ helm init
Output:
$HELM_HOME has been configured at /Users/<User>/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
To prevent this, run `helm init` with the --tiller-tls-verify flag.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Then I had to give tiller a ServiceAccount
and link everything up via roles.
$ kubectl create serviceaccount --namespace kube-system tiller
Output:
serviceaccount/tiller created
$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
Output:
clusterrolebinding.rbac.authorization.k8s.io/tiller-cluster-rule created
$ kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
Output:
deployment.extensions/tiller-deploy patched
Add jetstack
to your Helm repositories.
$ helm repo add jetstack https://charts.jetstack.io
Output:
"jetstack" has been added to your repositories
Install the cert-manager helm chart.
$ helm install --name cert-manager --namespace kube-system jetstack/cert-manager --version v0.8.0
Output:
NAME: cert-manager
LAST DEPLOYED: Tue Jun 25 08:39:05 2019
NAMESPACE: kube-system
STATUS: DEPLOYED
RESOURCES:
==> v1/ClusterRole
NAME AGE
cert-manager-edit 3s
cert-manager-view 3s
cert-manager-webhook:webhook-requester 3s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
cert-manager-5d669ffbd8-glqgv 0/1 ContainerCreating 0 3s
cert-manager-cainjector-79b7fc64f-bwn7t 0/1 ContainerCreating 0 3s
cert-manager-webhook-6484955794-p2jgn 0/1 ContainerCreating 0 3s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cert-manager-webhook ClusterIP ${CLUSTER_IP} <none> 443/TCP 3s
==> v1/ServiceAccount
NAME SECRETS AGE
cert-manager 1 3s
cert-manager-cainjector 1 3s
cert-manager-webhook 1 3s
==> v1alpha1/Certificate
NAME AGE
cert-manager-webhook-ca 3s
cert-manager-webhook-webhook-tls 2s
==> v1alpha1/Issuer
NAME AGE
cert-manager-webhook-ca 2s
cert-manager-webhook-selfsign 2s
==> v1beta1/APIService
NAME AGE
v1beta1.admission.certmanager.k8s.io 3s
==> v1beta1/ClusterRole
NAME AGE
cert-manager 3s
cert-manager-cainjector 3s
==> v1beta1/ClusterRoleBinding
NAME AGE
cert-manager 3s
cert-manager-cainjector 3s
cert-manager-webhook:auth-delegator 3s
==> v1beta1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
cert-manager 0/1 1 0 3s
cert-manager-cainjector 0/1 1 0 3s
cert-manager-webhook 0/1 1 0 3s
==> v1beta1/RoleBinding
NAME AGE
cert-manager-webhook:webhook-authentication-reader 3s
==> v1beta1/ValidatingWebhookConfiguration
NAME AGE
cert-manager-webhook 2s
NOTES:
cert-manager has been deployed successfully!
In order to begin issuing certificates, you will need to set up a ClusterIssuer
or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer).
More information on the different types of issuers and how to configure them
can be found in our documentation:
https://docs.cert-manager.io/en/latest/reference/issuers.html
For information on how to configure cert-manager to automatically provision
Certificates for Ingress resources, take a look at the `ingress-shim`
documentation:
https://docs.cert-manager.io/en/latest/reference/ingress-shim.html
Create a file called issuer.yaml
:
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: ${YOUR_EMAIL_ADDRESS}
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt
# Enable the HTTP-01 challenge provider
http01: {}
Replace ${YOUR_EMAIL_ADDRESS}
with your e-mail address.
Create the issuer with the following command:
$ kubectl create -f issuer.yaml
Output:
clusterissuer.certmanager.k8s.io/letsencrypt created
See this example Ingress
resource using the issuer:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: echo-ingress
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- echo1.example.com
- echo2.example.com
secretName: letsencrypt
rules:
- host: echo1.example.com
http:
paths:
- backend:
serviceName: echo1
servicePort: 80
- host: echo2.example.com
http:
paths:
- backend:
serviceName: echo2
servicePort: 80
Create as many Ingress
resources as you would like. The best practice, in my opinion, is having 1 per domain, just for organizational reasons.
If you have any questions or comments please feel free to comment below!
Thanks!
Sources:
Posted on November 14, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 14, 2020