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