How to Deploy a Secure Nginx Website on Vultr Kubernetes Engine

Author: Hitesh Jethva

Last Updated: Wed, Jan 4, 2023
Kubernetes Security Web Servers

Deploying an Nginx website on Vultr Kubernetes Engine will help you to achieve reliability and scalability. Protecting sensitive data and securing website traffic with SSL/TLS is also necessary for all websites. However, it can be challenging to host SSL/TLS-based Nginx websites on Kubernetes.

This is the case where Traefik Proxy comes into the picture. You can use and set up Traefik Proxy as a network proxy with a cert-manager to install and manage Let's Encrypt SSL certificates. Let's Encrypt is a free certificate authority that provides a way to automate and manage SSL certificates for your website.

This guide shows you how to secure the Nginx website with cert-manager, Traefik, and Let's Encrypt SSL on Vultr Kubernetes Engine.

Prerequisites

Install the Traefik Ingress Controller with Helm

  1. Add the Helm repository for the Traefik ingress controller.

    # helm repo add traefik https://helm.traefik.io/traefik
    
  2. Update the Helm repository.

    # helm repo update
    
  3. Install Traefik on your Kubernetes cluster.

    # helm install traefik traefik/traefik
    

    Sample output.

    NAME: traefik
    
    LAST DEPLOYED: Sat Nov 26 19:56:05 2022
    
    NAMESPACE: default
    
    STATUS: deployed
    
    REVISION: 1
    
    TEST SUITE: None
    
    NOTES:
    
    Traefik Proxy v2.9.5 has been deployed successfully on default namespace !
    
  4. Verify the Traefik ingress controller service.

    # kubectl get svc
    

    Sample output.

    NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
    
    kubernetes   ClusterIP      10.96.0.1      <none>        443/TCP                      5m16s
    
    traefik      LoadBalancer   10.96.215.40   192.0.2.100   80:31391/TCP,443:30688/TCP   3m
    

Creating Nginx Deployment and Service

Now, deploy an Nginx web server using the Nginx docker image on the Kubernetes cluster.

  1. Create an nginx-deployment.yml configuration file.

    # nano nginx-deployment.yml
    

    Add the following configuration:

    kind: Deployment
    
    apiVersion: apps/v1
    
    metadata:
    
      name: nginx-web
    
      namespace: default
    
      labels:
    
        app: nginx-web
    
    spec:
    
      replicas: 1
    
      selector:
    
        matchLabels:
    
          app: nginx-web
    
      template:
    
        metadata:
    
          labels:
    
            app: nginx-web
    
        spec:
    
          containers:
    
          - name: nginx
    
            image: "nginx"
    
  2. Apply the above configuration to the Kubernetes cluster.

    # kubectl create -f nginx-deployment.yml
    

    Sample output.

    deployment.apps/nginx-web created
    
  3. Create an Nginx service to expose pods to the cluster on port 80.

    # nano nginx-service.yml
    

    Add the following configuration.

    apiVersion: v1
    
    kind: Service
    
    metadata:
    
      name: nginx-web
    
      namespace: default
    
    spec:
    
      selector:
    
        app: nginx-web
    
      ports:
    
      - name: http
    
        targetPort: 80
    
        port: 80
    
  4. Apply the configuration to the Kubernetes cluster.

    # kubectl create -f nginx-service.yml
    

    Sample output.

    service/nginx-web created
    

Creating Traefik Ingress and Exposing Nginx Website

  1. Create a Traefik Ingress deployment to expose an Nginx website to the outside world.

    # nano traefik-ingress.yml
    

    Add the following configurations:

    apiVersion: networking.k8s.io/v1
    
    kind: Ingress
    
    metadata:
    
      name: traefik-ingress
    
      namespace: default
    
      annotations:
    
        kubernetes.io/ingress.class: traefik
    
    spec:
    
      rules:
    
      - host: nginxweb.example.com
    
        http:
    
          paths:
    
          - backend:
    
              service:
    
                name: nginx-web
    
                port:
    
                  number: 80
    
            path: /
    
            pathType: Prefix
    

    Note: Replace nginxweb.example.com with a fully qualified domain name.

  2. Apply the Traefik ingress resource to the cluster.

    # kubectl create -f traefik-ingress.yml   
    

    Sample output.

    ingress.networking.k8s.io/traefik-ingress created
    
  3. Verify the running pods.

    # kubectl get pods
    

    Sample output.

    NAME                         READY   STATUS    RESTARTS   AGE
    
    nginx-web-6b756d6954-mg5v4   1/1     Running   0          60s
    
    traefik-6c95797465-7ck46     1/1     Running   0          6m9s
    
  4. Verify the Kubernetes ingress resources.

    # kubectl get ingress
    

    Sample output.

    NAME              CLASS    HOSTS                   ADDRESS   PORTS   AGE
    
    traefik-ingress   <none>   nginxweb.example.com             80      119s
    
  5. Verify the Kubernetes service to retrieve the Traefik external IP.

    # kubectl get svc
    

    Sample output.

    NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
    
    kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP                      9m50s
    
    nginx-web    ClusterIP      10.104.168.40   <none>        80/TCP                       2m16s
    
    traefik      LoadBalancer   10.96.215.40    192.0.2.100   80:31391/TCP,443:30688/TCP   7m34s
    
  6. Point Traefik LoadBalancer external IP 192.0.2.100 to your domain name nginxweb.example.com.

Configuring cert-manager for Traefik Ingress

cert-manager is a certificate management controller for Kubernetes that allows you to download, renew and use Let's Encrypt or other SSL certificates.

Run the kubectl command to install cert-manager using the cert-manager's release file on the Kubernetes cluster.

# kubectl apply --validate=false -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml

Sample output.

service/cert-manager created

service/cert-manager-webhook created

deployment.apps/cert-manager-cainjector created

deployment.apps/cert-manager created

deployment.apps/cert-manager-webhook created

mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created

validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created

Configuring and Creating Traefik Ingress Let's Encrypt TLS Certificate

  1. First, create the ClusterIssuer for the Kubernetes cluster to issue certificates from Let's Encrypt.

    # nano  letsencrypt-issuer.yml
    

    Add the following configurations.

    apiVersion: cert-manager.io/v1
    
    kind: ClusterIssuer
    
    metadata:
    
      name: letsencrypt-prod
    
      namespace: default
    
    spec:
    
      acme:
    
        # The ACME server URL
    
        server: https://acme-v02.api.letsencrypt.org/directory
    
        # Email address used for ACME registration
    
        email: hitjethva@gmail.com
    
        # Name of a secret used to store the ACME account private key
    
        privateKeySecretRef:
    
          name: letsencrypt-prod
    
        # Enable the HTTP-01 challenge provider
    
        solvers:
    
        - http01:
    
            ingress:
    
              class: traefik
    
  2. Deploy the above configuration to the Kubernetes cluster.

    # kubectl apply -f letsencrypt-issuer.yml
    

    Sample output.

    clusterissuer.cert-manager.io/letsencrypt-prod created
    
  3. Create the Traefik Ingress Let's Encrypt TLS certificate for your Nginx website.

    # nano letsencrypt-certificate.yml
    

    Add the following configurations.

    apiVersion: cert-manager.io/v1
    
    kind: Certificate
    
    metadata:
    
      name: nginxweb.example.com
    
      namespace: default
    
    spec:
    
      secretName: nginxweb.example.com-tls
    
      issuerRef:
    
        name: letsencrypt-prod
    
        kind: ClusterIssuer
    
      commonName: nginxweb.example.com
    
      dnsNames:
    
      - nginxweb.example.com
    
  4. Apply the above configuration to the cluster.

    # kubectl apply -f letsencrypt-certificate.yml
    

    This will create a Traefik Ingress Let's Encrypt TLS certificate for the domain nginxweb.example.com.

    certificate.cert-manager.io/nginxweb.example.com created
    
  5. Verify the created certificate.

    # kubectl get certificates nginxweb.example.com 
    

    Sample output.

    NAME                    READY   SECRET                      AGE
    
    nginxweb.example.com   True    nginxweb.example.com-tls   55s
    

Define Let's Encrypt Certificate in Traefik Ingress Resource

After creating Traefik Ingress Let's Encrypt SSL, define the certificate in traefik-ingress.yml.

Edit the traefik-ingress.yml using the nano editor.

# KUBE_EDITOR= "nano" kubectl edit ingress traefik-ingress

Change the file with the following configuration.

apiVersion: networking.k8s.io/v1

kind: Ingress

metadata:

  annotations:

    cert-manager.io/cluster-issuer: letsencrypt-prod

    kubernetes.io/ingress.class: traefik

  creationTimestamp: "2022-11-26T14:32:09Z"

  generation: 1

  name: traefik-ingress

  namespace: default

  resourceVersion: "2125"

  uid: 942404bd-6031-4a31-9f89-eccbc66b80f6

spec:

  rules:

  - host: nginxweb.example.com

    http:

      paths:

      - backend:

          service:

            name: nginx-web

            port:

              number: 80

        path: /

        pathType: Prefix

  tls:

  - hosts:

    - nginxweb.example.com

    secretName: nginxweb.example.com-tls



status:

  loadBalancer: {}

Verify HTTPS

Your Nginx website is now deployed on the Kubernetes cluster with Let's Encrypt SSL. You can now verify it by visiting the URL https://nginxweb.example.com in your web browser. You can also verify the Nginx website using curl.

# curl -L https://nginxweb.example.com

Conclusion

You have deployed an Nginx website with cert-manager, Traefik, and Let's Encrypt SSL on Vultr Kubernetes Engine. You can also deploy and serve many websites on the same cluster using different Ingress resources. For more information, visit the Traefik Proxy documentation page.

Want to contribute?

You could earn up to $600 by adding new articles.