Siv Scripts

Solving Problems Using Code

Fri 16 October 2020

Redirecting requests in Kubernetes

Posted by Aly Sivji in Quick Hits   

This canonical URL for this blog is alysivji.github.io. I have also set up nginx to forward requests to alysivji.com and sivji.com to this blog.

This is all well and good when are you running nginx out of a VM, but what if you are using the Kubernetes NGINX Ingress Controller? Unless you are paying for NGINX Plus, you won't be able to set up URL redirects using the ingress controller.

This post walkthrough my workaround to set up URL redirects in Kubernetes.

Solution

Spin up an nginx pod with a ConfigMap that contains the settings you want.

Deployment Manifest

Our deployment will be a single pod running a containerized version of nginx with a pre-configured /etc/nginx/nginx.conf file. This file will be created via a ConfigMap.

# deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: /etc/nginx/nginx.conf
          readOnly: true
          name: nginx-conf
          subPath: nginx.conf
        - mountPath: /var/log/nginx
          name: log
        resources:
          limits:
            memory: "32Mi"
            cpu: "100m"
      volumes:
      - name: nginx-conf
        configMap:
          name: nginx-conf
          items:
            - key: nginx.conf
              path: nginx.conf
      - name: log
        emptyDir: {}

ConfigMap Manifest

We can use ConfigMaps to create files that can be accessed with our pod. Here we set up a 307 Temporary redirect.

# configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-conf
data:
  nginx.conf: |
    user nginx;
    error_log  /var/log/nginx/error.log;
    events {
      worker_connections  10240;
    }
    http {
      log_format  main
              'remote_addr:$remote_addr\t'
              'time_local:$time_local\t'
              'method:$request_method\t'
              'uri:$request_uri\t'
              'host:$host\t'
              'status:$status\t'
              'bytes_sent:$body_bytes_sent\t'
              'referer:$http_referer\t'
              'useragent:$http_user_agent\t'
              'forwardedfor:$http_x_forwarded_for\t'
              'request_time:$request_time';
      access_log    /var/log/nginx/access.log main;

      server {
          listen 80;
          server_name sivji.com www.sivji.com alysivji.com www.alysivji.com;
          return 307 https://alysivji.github.io;
      }
    }

Service Manifest

Our nginx pods will be sitting behind a Service.

# service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx

Ingress Manifest

We will create ingress routes that map domains and subdomains to the Service.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: blog-forward
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
      - sivji.com
      - www.sivji.com
      - alysivji.com
      - www.alysivji.com
      secretName: blog-forward-tls
  rules:
  - host: sivji.com
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 80
  - host: www.sivji.com
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 80
  - host: alysivji.com
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 80
  - host: www.alysivji.com
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 80

Apply Configuration

If all the manifests are in the same folder, we can apply them via kubectl:

kubectl apply -f .

 
    
 
 

Comments