Using nginx-ingress controller with Kubernetes: The complete guide

Updated: January 20, 2024 By: Guest Contributor Post a comment

Introduction

Modern web applications often rely on a container orchestration system like Kubernetes to manage and scale their environments efficiently. Kubernetes, while powerful, does not natively handle external traffic routing to services within the cluster. This is where the nginx-ingress controller comes into play. In this complete guide, we’ll explore how to seamlessly integrate an nginx-ingress controller with Kubernetes and manage incoming HTTP(s) traffic.

Prerequisites

  • A Kubernetes cluster with kubectl configured
  • Basic knowledge of Kubernetes resource types, especially Services and Deployments
  • Familiarity with nginx, or common web server/proxy concepts

Installation

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml

Verify the installation using:

kubectl get pods --namespace=ingress-nginx

First Steps with nginx-ingress

After installing the nginx-ingress controller, the first step is to route traffic to a simple web application:

Creating a Test Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: nginx:latest
        ports:
        - containerPort: 80

Exposing the Deployment with a Service

apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  selector:
    app: webapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP

Defining the Ingress Resource

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: webapp-service
            port:
              number: 80

Now let’s check if the ingress is set up correctly:

kubectl get ingress

Advanced Configuration

With the basics covered, we can dive into more advanced use cases, like setting up TLS, path-based routing, and implementing advanced load balancing rules.

Securing Ingress with TLS

To secure our ingress traffic, we can modify our Ingress resource to use TLS:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - example.com
    secretName: example-tls
  rules:
    - host: example.com
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: webapp-service
              port:
                number: 80

Note: The secret example-tls should already exist in your Kubernetes cluster and contain the TLS certificate and private key.

Path Based Routing

If you have multiple services and need to route traffic based on the URL path, the nginx-ingress controller can easily facilitate this:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-ingress
spec:
  rules:
  - http:
      paths:
      - path: /service1
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 80
      - path: /service2
        pathType: Prefix
        backend:
          service:
            name: service2
            port:
              number: 80

Monitoring and Troubleshooting

Monitoring is crucial for any ingress implementation:

kubectl logs -n ingress-nginx <nginx-ingress-controller-pod>

Troubleshooting tips include:

  • Checking the status of ingress controller pods
  • Using kubectl describe to inspect resources
  • Viewing nginx-ingress controller logs for HTTP errors

Optimizations and Performance Tuning

Annotations in your Ingress resource can tune performance:

nginx.ingress.kubernetes.io/proxy-body-size: "64m"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "15"
nginx.ingress.kubernetes.io/proxy-read-timeout: "20"

Altering these parameters in-line with your application needs can optimize your load balancing behavior and resource utilization.

Using Custom Nginx Configuration

For complex routing or custom behavior, you may need to introduce custom nginx configuration:

nginx.ingress.kubernetes.io/configuration-snippet: |
  more_set_headers "X-Robots-Tag: noindex, nofollow";

This allows you to inject nginx server directives into your Ingress controller without altering global configmaps.

Conclusion

In this guide, we’ve covered everything from setting up a basic nginx-ingress to fine-tuning performance and applying custom configuration. Embracing nginx-ingress within your Kubernetes clusters will ensure you have a solid gateway managing your service traffic effectively.