In this post I will show how I've setup my Nginx Reverse Proxy on Kubernetes and instead of mounting my configs to a persistent volume, I've opted in to create my configs as config maps.
I have a application running on my lan with the port 3579
and I want to setup a reverse proxy to do SSL termination using Traefik.
First we define our config map, named app-rp-config-cm
which will include nginx.conf
and ombi.conf
:
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-rp-config-cm
data:
nginx.conf: |
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/app.conf;
}
app.conf: |
upstream app {
server 192.168.0.240:3579;
keepalive 15;
}
server {
listen 80;
server_name _;
location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
proxy_redirect off;
}
}
Then our deployment:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-reverse-proxy
labels:
app: app-reverse-proxy
category: reverse-proxy
spec:
replicas: 1
selector:
matchLabels:
app: app-reverse-proxy
template:
metadata:
labels:
app: app-reverse-proxy
category: reverse-proxy
spec:
containers:
- name: app-reverse-proxy
image: nginx
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 50Mi
limits:
cpu: 100m
memory: 50Mi
volumeMounts:
- name: app-rp-config-cm-vol
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
readOnly: true
- name: app-rp-config-cm-vol
mountPath: /etc/nginx/conf.d/app.conf
subPath: app.conf
readOnly: true
volumes:
# https://medium.com/swlh/quick-fix-mounting-a-configmap-to-an-existing-volume-in-kubernetes-using-rancher-d01c472a10ad
- configMap:
name: app-rp-config-cm
items:
- key: nginx.conf
path: nginx.conf
- key: app.conf
path: app.conf
name: app-rp-config-cm-vol
Then our service:
---
apiVersion: v1
kind: Service
metadata:
name: app-reverse-proxy
namespace: default
spec:
ports:
- name: http
targetPort: 80
port: 80
selector:
app: app-reverse-proxy
category: reverse-proxy
And our ingress using Traefik and Letsencrypt:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-reverse-proxy
namespace: default
annotations:
kubernetes.io/ingress.class: traefik
ingress.kubernetes.io/ssl-redirect: "true"
traefik.backend.loadbalancer.stickiness: "true"
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- secretName: app-mydomain-com-tls
hosts:
- app.mydomain.com
rules:
- host: app.mydomain.com
http:
paths:
- path: /
backend:
serviceName: app-reverse-proxy
servicePort: http
You can apply then individually or concatenate them into a single file and then run:
$ kubectl apply -f my-deployment.yml
Then verify if your deployment is in its desired state:
$ kubectl get deployment -l category=reverse-proxy
NAME READY UP-TO-DATE AVAILABLE AGE
app-reverse-proxy 1/1 1 1 12m
And verify if your certificate has been issued:
$ kubectl describe certificate
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal GeneratedKey 12m cert-manager Generated a new private key
Normal Requested 12m cert-manager Created new CertificateRequest resource "app-mydomain-com-tls-90643266"
Normal Issued 12m cert-manager Certificate issued successfully
Then you should be able to access your endpoint as configured in the ingress section.