Utiliser NGINX comme d'un proxy de base de données

mxglt

Maxime Guilbert

Posted on March 6, 2023

Utiliser NGINX comme d'un proxy de base de données

Dans notre quotidien, il se peut que l'on perde l'accès direct à une base de données et qu'elle ne soit qu'accessible que par les services dans le cluster Kubernetes.

Du coup, dans ce genre de situations, être capable d'utiliser un proxy peut vous permettre de résoudre ce problème de connectivité. Donc aujourd'hui, je vais vous présenter comment le faire avec Nginx.

Qu'est-ce que NGINX ?

Pour ceux qui n'auraient pas encore eu l'occasion de découvrir ce qu'est Nginx. C'est un logiciel open source pouvant servir de load balancer, de serveur web ou de proxy.


Configurer NGINX

La configuration de Nginx ressemble à ça

user  nginx;
worker_processes  auto;
error_log /dev/stdout info;
pid        /var/run/nginx.pid;
events {
  worker_connections  1024;  ## Default: 1024
}
http {
  access_log /dev/stdout combined;
  log_format logger-json escape=json '{"source": "nginx", "time": $msec, "resp_body_size": $body_bytes_sent, "host": "$http_host", "address": "$remote_addr", "request_length": $request_length, "method": "$request_method", "uri": "$request_uri", "status": $status,  "user_agent": "$http_user_agent", "resp_time": $request_time, "upstream_addr": "$upstream_addr"}';
    server {
         listen 8080 so_keepalive=on;
        location = /health {
          auth_basic off;
          return 200;
        }
    }
}
stream {
    upstream database {
        server [endpoint base de données]:[port base de données];
    }
    server {
        listen [port base de données] so_keepalive=on;
            proxy_connect_timeout 60s;
            proxy_socket_keepalive on;
            proxy_pass database;
    }
}
Enter fullscreen mode Exit fullscreen mode

Ici, il y a quelques éléments à remplacer :

  • [endpoint base de données] : L'url pour accéder à la base de données
  • [port base de données] : Le port pour accéder à la base de données

Détail de la configuration

http

La partie HTTP est pour exposer un simple endpoint /health pour s'assurer de la présence et disponibilité du service.

stream

Dans notre cas, c'est la partie qui nous intéresse le plus.

La partie upstream est pour créer un groupe de serveurs (ici on n'en a qu'un qui s'appelle database, mais ça facilite un peu la lecture).

La partie server va, elle, définir :

  • sur quelle port Nginx va écouter pour rediriger le trafic -> listen
  • où il va rediriger le trafic -> proxy_pass Ainsi que d'autres configurations comme so_keepalive=on et proxy_socket_keepalive on; qui sont importantes pour éviter que la connexion soit coupée au milieu des opérations qui sont faites sur la base de données.

Déploiement sur Kubernetes

Une fois que la configuration est prête, vous pouvez alors le déployer sur votre cluster.

Voici un template pour pouvoir créer la configmap, le deployment et le service.

apiVersion: v1
data:
  nginx.conf: "user  nginx;\r\nworker_processes  auto;\r\nerror_log /dev/stdout info;\r\npid
    \ /var/run/nginx.pid;\r\nevents {\r\n  worker_connections  1024;  ## Default:
    1024\r\n}\r\n\r\nhttp {\r\n  access_log /dev/stdout combined;\r\n  log_format
    logger-json escape=json '{\"source\": \"nginx\", \"time\": $msec, \"resp_body_size\":
    $body_bytes_sent, \"host\": \"$http_host\", \"address\": \"$remote_addr\", \"request_length\":
    $request_length, \"method\": \"$request_method\", \"uri\": \"$request_uri\", \"status\":
    $status,  \"user_agent\": \"$http_user_agent\", \"resp_time\": $request_time,
    \"upstream_addr\": \"$upstream_addr\"}';\r\n\r\n\r\n    server {\r\n         listen
    8080 so_keepalive=on;\r\n\r\n        location = /health {\r\n          auth_basic
    off;\r\n          return 200;\r\n        }\r\n    }\r\n}\r\nstream {\r\n    upstream
    postgres {\r\n        server database:port;\r\n
    \ }\r\n\r\n    server {\r\n        listen port so_keepalive=on;\r\n            proxy_connect_timeout
    60s;\r\n            proxy_socket_keepalive on;\r\n            proxy_pass postgres;\r\n
    \ }\r\n}"
kind: ConfigMap
metadata:
  name: nginx-config
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  ports:
    - port: 8080
      protocol: TCP
      targetPort: 8080
      name: http
    - port: port
      protocol: TCP
      targetPort: port
      name: database
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
      name: nginx
    spec:
      containers:
        - args:
            - nginx
            - -g
            - daemon off;
            - -c
            - /nginx/etc/config/nginx.conf
          image: nginx:1.23.3
          imagePullPolicy: IfNotPresent
          livenessProbe:
            httpGet:
              path: /health
              port: nginx
              scheme: HTTP
            initialDelaySeconds: 10
          name: nginx
          ports:
            - containerPort: 8080
              name: nginx
              protocol: TCP
            - containerPort: port
              name: database
              protocol: TCP
          readinessProbe:
            httpGet:
              path: /health
              port: nginx
              scheme: HTTP
            initialDelaySeconds: 10
          resources:
            limits:
              memory: 200Mi
            requests:
              cpu: 50m
              memory: 200Mi
          volumeMounts:
            - mountPath: /nginx/etc/config
              name: nginx-config-volume
      volumes:
        - configMap:
            name: nginx-config
          name: nginx-config-volume
Enter fullscreen mode Exit fullscreen mode

Avant de l'utiliser, assurez-vous de mettre les bonnes informations dans la configmap, ainsi que de définir le port dont vous avez besoin pour exposer votre base de données dans votre déploiement et votre service!


Utilisation

Une fois déployé sur votre cluster, vous pouvez l'exposer au travers d'un Ingress ou simplement faire un port forward du service afin de pouvoir effectuer vos manipulations depuis votre machine!


C'est tout pour cette semaine, j'espère que ça vous aidera! 🍺


Vous voulez me supporter?

Buy Me A Coffee

💖 💪 🙅 🚩
mxglt
Maxime Guilbert

Posted on March 6, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related