# Cert-Manager ## How to set up an Nginx Ingress with Cert-Manager on E2E Kubernetes ### Introduction Kubernetes [`Ingress`](https://kubernetes.io/docs/concepts/services-networking/ingress/) is an API object that provides routing rules to manage access to the services within a Kubernetes cluster. This typically uses HTTPS and HTTP protocols to facilitate the routing. Popular Ingress Controllers include [`Nginx`](https://github.com/kubernetes/ingress-nginx/blob/main/README.md/), [`Contour`](https://projectcontour.io/getting-started/), [`HAProxy`](https://www.haproxy.com/documentation/kubernetes-ingress/overview/), and [`Traefik`](https://doc.traefik.io/traefik/providers/kubernetes-ingress/). Ingresses provide a more efficient and flexible alternative to creating multiple LoadBalancer services, each with its own dedicated load balancer. This guide will walk you through setting up the Kubernetes-maintained Nginx Ingress Controller. We'll then create Ingress resources to route traffic to backend services efficiently. Finally, to secure communication, we'll install cert-manager for managing and provisioning TLS certificates for the Ingress. For assistance on rolling out the Nginx Ingress Controller using Helm, refer to the docs [How to set up an Nginx Ingress on E2E Kubernetes and demonstrate host-based routing protocol](/docs/myaccount/kubernetes/nginx_ingress_controller/). ### Prerequisites Before you begin with this guide, you should have the following available to you: 1. Provision an E2E Kubernetes cluster with any available versions; this will serve as the platform for deploying your service workloads. Once the cluster is up and running, download the cluster configuration file (kubeconfig.yaml) from the E2E Kubernetes dashboard section and place it in the standard location: `~/.kube/config` on your local machine. 2. Ensure that the `kubectl` command-line tool is installed on your local machine and configured to connect to your cluster. You can read more about installing kubectl in the [Official documentation](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/). 3. Reserve and attach an LB IP through the k8s LB IP section to expose a service externally via an ingress. Please find the detailed steps over [here](/docs/myaccount/kubernetes/#loadbalancer) to provision LB IP. 4. A domain name and DNS A records which you can point to the E2E K8s LB IP used by the Ingress. If you are using E2E to manage your domain’s DNS records, consult the following [article](/docs/myaccount/network/dns/#setup-dns-records) for more information. ### Step 1: Creating a Sample Backend Services ```bash echo "--- apiVersion: apps/v1 kind: Deployment metadata: name: nginxhello-blue labels: app.kubernetes.io/name: nginxhello-blue app.kubernetes.io/part-of: nginxhello-blue spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: nginxhello-blue app.kubernetes.io/part-of: nginxhello-blue template: metadata: labels: app.kubernetes.io/name: nginxhello-blue app.kubernetes.io/part-of: nginxhello-blue spec: containers: - name: nginxhello-blue image: suryaprakash116/blue-container ports: - containerPort: 80 env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: COLOR value: blue --- apiVersion: v1 kind: Service metadata: name: nginxhello-blue labels: app.kubernetes.io/name: nginxhello-blue app.kubernetes.io/part-of: nginxhello-blue spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app.kubernetes.io/name: nginxhello-blue app.kubernetes.io/part-of: nginxhello-blue " | kubectl apply -f - ``` After deploying the sample backend deployments and service, you'll see the following output. ![Sample Backend Output](images/cert1.png) ## Step 2: Setting up the Nginx Ingress Controller To set up and install the Nginx Ingress Controller, kindly refer to the following [docs](/docs/myaccount/kubernetes/nginx_ingress_controller/) step 2. Once the installation has been completed, you’ll see the following output. ![Nginx Ingress Installation Output](images/cert2.png) After a few minutes, the Ingress controller service (`ingress-nginx-controller`) should acquire an external IP address. This IP will match the Load Balancer IP you previously provisioned from the [E2E Kubernetes Dashboard](https://myaccount.e2enetworks.com/products/kubernetes) LB IP section. ![Ingress Controller External IP](images/cert3.png) ## Step 3: Implementing TLS for a Backend Service using Cert-Manager ### Managing X.509 Certificates: A Pain in the Neck Manually defining, requesting, applying, renewing, and removing TLS certificates can be a tedious and error-prone process, especially when dealing with a large number of certificates. ### Introducing Cert-Manager: Your Kubernetes Certificate Hero The Kubernetes ecosystem offers a powerful open-source and community-driven solution called [Cert-Manager](https://cert-manager.io/v1.1-docs/installation/kubernetes/) (developed by Jetstack). Cert-Manager automates the entire lifecycle of TLS certificates within your Kubernetes cluster, significantly reducing manual work and associated errors. ### Benefits of Automated X.509 Certificate Management: - **Enhanced Automation:** Cert-Manager automates certificate management tasks, freeing you to focus on other critical development activities. - **Reduced Risk:** By eliminating the human element from certificate management, you minimize the risk of errors and security vulnerabilities. - **Reliable Outcomes:** Automation ensures consistency and predictability in the certificate management process, leading to more reliable results. ### Adding the Jetstack Repository Add the Jetstack repository, which contains the official Cert-Manager Helm chart, to your local Helm repository list. ```bash helm repo add jetstack https://charts.jetstack.io ``` ## Updates the Jetstack repository information in your local Helm cache. This ensures you have access to the latest version of the Cert-Manager chart. ```bash helm repo update jetstack ``` ## Actual installation of Cert-Manager ```bash helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true ``` ## To verify our installation, check the cert-manager Namespace for running pods: ![Cert-Manager Pods](images/CertManagerPods.png) This indicates that the cert-manager installation succeeded. Before issuing certificates for our domain (e.g., example.com) used throughout this guide, we need to create an Issuer. An Issuer specifies the certificate authority from which signed X.509 certificates can be obtained. In this guide, we'll leverage Let's Encrypt, a popular certificate authority that provides free, trusted TLS certificates. Let's Encrypt offers both a staging environment for testing your certificate configuration before deploying them to production and a production server for issuing verifiable TLS certificates. :::info Note During the creation of the ingress rule in the tls ingress object add annotation `cert-manager.io/issuer: acme-lets-encrypt` to automate the creation of `cert-manager` and `secrets` ::: ```bash echo "apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: host-rule-ingress annotations: cert-manager.io/issuer: acme-lets-encrypt spec: ingressClassName: nginx rules: - host: dsquarezone.online http: paths: - backend: service: name: nginxhello-blue port: number: 80 pathType: ImplementationSpecific tls: - hosts: - dsquarezone.online secretName: dsquarezone-online-tls " | kubectl apply -f - ``` To verify our certificate provisioning process is working flawlessly, let's create a test ClusterIssuer. Unlike regular Issuers which are confined to a single namespace, a ClusterIssuer has cluster-wide visibility. This allows any `Certificate `_ .resource in any namespace to leverage this ClusterIssuer for obtaining certificates. ```bash echo "apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: acme-lets-encrypt spec: acme: server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: acme-lets-encrypt email: example@gmail.com solvers: - http01: ingress: class: nginx" | kubectl apply -f - ``` This step defines and submits a Kubernetes resource called a Certificate. This resource instructs Cert-Manager to request and manage a TLS certificate for your specified domain name. ```bash echo "apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: dsquarezone-online spec: dnsNames: - dsquarezone.online ## Replace your domain name issuerRef: name: acme-lets-encrypt secretName: dsquarezone-online-tls" | kubectl apply -f - ``` Once the certificate has been successfully created, you can run a describe on it to further confirm its successful creation: ```bash kubectl describe certificate ``` You should see the following output in the Events section: ![Cert-Manager Events](images/Certevents.png) We’ll now try to access our site in a browser (e.g., https://example.com) using the HTTPS protocol to ensure it is working properly. ![HTTPS Access](images/https-access.png) ---