DEV Community

Dak Washbrook
Dak Washbrook

Posted on • Edited on • Originally published at asilearn.org

2 2

Install NGINX Ingress Controller on Kubernetes + Let's Encrypt Cert Issuer

This article is a perspective rewrite of the given sources that allowed me to get from point A to point B from my perspective.

Alt Text

Requirements:

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"}}'
Enter fullscreen mode Exit fullscreen mode

You can check on the service with:

$ kubectl get svc --namespace=ingress-nginx
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

Output:

namespace/kube-system labeled
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Then I had to give tiller a ServiceAccount and link everything up via roles.

$ kubectl create serviceaccount --namespace kube-system tiller
Enter fullscreen mode Exit fullscreen mode

Output:

serviceaccount/tiller created
$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
Enter fullscreen mode Exit fullscreen mode

Output:

clusterrolebinding.rbac.authorization.k8s.io/tiller-cluster-rule created
$ kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
Enter fullscreen mode Exit fullscreen mode

Output:

deployment.extensions/tiller-deploy patched
Enter fullscreen mode Exit fullscreen mode

Add jetstack to your Helm repositories.

$ helm repo add jetstack https://charts.jetstack.io
Enter fullscreen mode Exit fullscreen mode

Output:

"jetstack" has been added to your repositories
Enter fullscreen mode Exit fullscreen mode

Install the cert-manager helm chart.

$ helm install --name cert-manager --namespace kube-system jetstack/cert-manager --version v0.8.0
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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: {}
Enter fullscreen mode Exit fullscreen mode

Replace ${YOUR_EMAIL_ADDRESS} with your e-mail address.

Create the issuer with the following command:

$ kubectl create -f issuer.yaml
Enter fullscreen mode Exit fullscreen mode

Output:

clusterissuer.certmanager.k8s.io/letsencrypt created
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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:

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more