Skip to main content

Command Palette

Search for a command to run...

Running a Nginx Reverse Proxy on Kubernetes

Updated
2 min read
Running a Nginx Reverse Proxy on Kubernetes
R

I have a passion for problem solving, building things and making businesses succeed. I’m madly curious by heart, so I’m very hungry for knowledge and you will always find my trying and testing out new things to stay ahead of the game.

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.

More from this blog

Ruan Bekker's Hashnode

66 posts

I have a passion for problem solving, building things and making businesses succeed. I’m madly curious by heart, so I’m very hungry for knowledge to stay ahead of the game.