Balanceo de carga de servicios de Kubernetes con NGINX Plus

NGINX | 17 de noviembre de 2015

Kubernetes es un sistema de código abierto desarrollado por Google para ejecutar y gestionar en un clúster aplicaciones basadas en microservicios en contenedores. Quienes utilizan Kubernetes suelen necesitar que los servicios que crean en Kubernetes sean accesibles desde fuera de su clúster de Kubernetes.

Aunque Kubernetes ofrece soluciones integradas para exponer servicios, descritas más adelante en Exposición de servicios de Kubernetes mediante soluciones integradas, dichas soluciones se limitan al balanceo de carga de capa 4 o al balanceo de carga HTTP mediante round-robin.

Este artículo muestra cómo utilizar NGINX Plus como una solución avanzada de equilibrio de carga de capa 7 para exponer servicios de Kubernetes a Internet, tanto si ejecuta Kubernetes en la nube como en su propia infraestructura.

Suponemos que tiene conocimientos básicos de Kubernetes (pods, servicios, controladores de replicación y etiquetas), así como un clúster de Kubernetes en funcionamiento. Para obtener más información sobre Kubernetes, consulte la guía oficial del usuario de Kubernetes.

Exposición de servicios de Kubernetes con soluciones integradas

Kubernetes ofrece varias opciones para exponer servicios. Dos de ellas, NodePort y LoadBalancer, corresponden a un tipo específico de servicio. Una tercera opción, la API Ingress, pasó a estar disponible en fase beta en la versión 1.1 de Kubernetes.

NodePort

Al especificar el tipo de servicio como NodePort el servicio queda disponible en el mismo puerto de cada nodo de Kubernetes. Para exponer el servicio a Internet, debe exponer uno o varios nodos en ese puerto. Para garantizar una alta disponibilidad, puede exponer varios nodos y utilizar el equilibrio de carga basado en DNS para distribuir el tráfico entre ellos, o bien colocar los nodos detrás del equilibrador de carga que prefiera.

Cuando el tráfico entrante llega a un nodo a través del puerto, se distribuye entre los pods del servicio. El balanceo de carga que realiza el proxy de red de Kubernetes (kube-proxy) que se ejecuta en cada nodo se limita al balanceo de carga TCP/UDP.

Balanceador de carga

Al especificar el tipo de servicio como LoadBalancer, se asigna un balanceador de carga en la nube que distribuye el tráfico entrante entre los pods del servicio.

La solución LoadBalancer solo es compatible con determinados proveedores de servicios en la nube y con Google Container Engine, y no está disponible si ejecuta Kubernetes en su propia infraestructura. Además, Kubernetes solo permite configurar el balanceo de carga TCP mediante round-robin, aunque el balanceador de carga en la nube disponga de funciones avanzadas, como la persistencia de sesión o el enrutamiento de solicitudes.

API de Ingress

Crear un recurso Ingress permite exponer servicios en Internet mediante URL personalizadas (por ejemplo, el servicio A en la URL /foo y el servicio B en la URL /bar) y varios nombres de host virtuales (por ejemplo, foo.example.com para un grupo de servicios y bar.example.com para otro grupo). Un controlador de Ingress procesa un recurso Ingress y configura un balanceador de carga externo.

Un controlador de Ingress no forma parte de una implementación estándar de Kubernetes: debe elegir el controlador que mejor se adapte a sus necesidades o implementar uno usted mismo y añadirlo a su clúster de Kubernetes. Se espera que pronto aparezcan muchas implementaciones de controladores, pero, por ahora, la única disponible es el controlador para el balanceador de carga HTTP de Google Compute Engine, que solo funciona si ejecuta Kubernetes en Google Compute Engine o Google Container Engine. La API de Ingress solo admite el balanceo de carga HTTP mediante round-robin, aunque el balanceador de carga real admita funciones avanzadas.

En el momento de redactar este documento, tanto la API de Ingress como el controlador del balanceador de carga HTTP de Google Compute Engine se encuentran en fase beta.

Actualización – NGINX Ingress Controller para NGINX y NGINX Plus ya está disponible en nuestro repositorio de GitHub. Para obtener más información sobre el producto, consulte NGINX Ingress Controller.

Aunque las soluciones mencionadas anteriormente son fáciles de configurar y funcionan sin necesidad de ajustes adicionales, no ofrecen ninguna funcionalidad avanzada, especialmente en lo que respecta al equilibrio de carga de capa 7.

Exposición de servicios de Kubernetes con NGINX Plus

[Editor – Esta sección se ha actualizado para hacer referencia a la API de NGINX Plus, que sustituye y deja obsoleto el módulo independiente de configuración dinámica mencionado originalmente aquí.]

Para integrar NGINX Plus con Kubernetes, debemos asegurarnos de que la configuración de NGINX Plus se mantenga sincronizada con Kubernetes y refleje los cambios en los servicios de Kubernetes, como la adición o eliminación de pods. Con NGINX Open Source, se modifica manualmente el archivo de configuración de NGINX y se vuelve a cargar la configuración. Con NGINX Plus, hay dos formas de actualizar la configuración de forma dinámica:

  • Con las API – Este método utiliza la API de NGINX Plus para añadir y eliminar entradas de los pods de Kubernetes en la configuración de NGINX Plus, y la API de Kubernetes para obtener las direcciones IP de los pods. Este método requiere que escribamos algo de código, por lo que no lo trataremos en profundidad aquí. Para obtener más información, vea el seminario web de Kelsey Hightower, «Llevando Kubernetes al perímetro con NGINX Plus», en el que explora las API y crea una aplicación que las utiliza.
  • Mediante la resolución periódica de nombres DNS – Este método solo requiere configurar correctamente NGINX Plus una vez, tal como se describe en la siguiente sección.

Uso de la reconfiguración basada en DNS

Suponemos que ya dispone de un clúster de Kubernetes en funcionamiento y de un host con la utilidad kubectl disponible para administrar el clúster. Para obtener instrucciones, consulte la guía de introducción a Kubernetes correspondiente a su tipo de clúster. También debe haber creado una imagen de Docker de NGINX Plus. Encontrará las instrucciones en Implementación de NGINX y NGINX Plus con Docker en nuestro blog.

A continuación, se resume lo que haremos:

  1. Configure un pod de NGINX Plus para exponer y equilibrar la carga del servicio que vamos a crear en el paso 2.
  2. Cree una aplicación web sencilla que actúe como nuestro servicio.
  3. Aumente y reduzca la escala del servicio y observe cómo NGINX Plus se reconfigura automáticamente.

Notas: Probamos la solución descrita en este blog con Kubernetes 1.0.6 ejecutándose en Google Compute Engine y en un entorno local de Vagrant, que es el que utilizamos a continuación.

En los comandos, los valores que pueden variar según la configuración de Kubernetes aparecen en cursiva.

Configuración del pod de NGINX Plus

Vamos a instalar NGINX Plus en un pod de Kubernetes, en un nodo que expondremos a Internet. Nuestro pod lo crea un controlador de replicación, que también estamos configurando. El archivo de configuración de NGINX Plus específico para Kubernetes se encuentra en una carpeta compartida entre el pod de NGINX Plus y el nodo, lo que facilita su mantenimiento.

Elegir un nodo para alojar el pod de NGINX Plus

Para designar el nodo en el que se ejecuta el pod de NGINX Plus, añadimos una etiqueta a dicho nodo. Para obtener la lista de todos los nodos, ejecutamos:

$ kubectl get nodesNAME         LABELS                              STATUS
10.245.1.3   Kubernetes.io/hostname=10.245.1.3   Ready
10.245.1.4   Kubernetes.io/hostname=10.245.1.4   Ready
10.245.1.5   Kubernetes.io/hostname=10.245.1.5   Ready

Elegimos el primer nodo y le añadimos una etiqueta ejecutando:

$ kubectl label node 10.245.1.3 role=nginxplus

Configuración del controlador de replicación para el pod de NGINX Plus

No creamos un pod de NGINX Plus directamente, sino a través de un controlador de replicación. Configuramos el controlador de replicación para el pod de NGINX Plus en un archivo de declaración de Kubernetes llamado «nginxplus-rc.yaml».

  • Establecemos el número de réplicas en uno, lo que significa que Kubernetes garantiza que siempre haya un pod de NGINX Plus en ejecución: si el pod falla, se sustituye por uno nuevo.
  • En el campo nodeSelector especificamos que el pod de NGINX Plus se cree en un nodo con la etiqueta role: nginxplus.
  • Nuestro contenedor NGINX Plus expone dos puertos, el 80 y el 8080, y configuramos una asignación entre estos y los puertos 80 y 8080 del nodo.
  • Nuestro contenedor de NGINX Plus también comparte la carpeta /etc/nginx/conf.d que se encuentra en el nodo. Como se explica más adelante en Configuración de NGINX Plus, compartir la carpeta nos permite reconfigurar NGINX Plus sin tener que volver a crear la imagen del contenedor.
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginxplus-rc
spec:
  replicas: 1
  selector:
    app: nginxplus
  template:
    metadata:
      labels:
        app: nginxplus
    spec:
      nodeSelector:
        role: nginxplus
      containers:
      - name: nginxplus
        imagePullPolicy: IfNotPresent
        image: nginxplus
        ports:
          - name: http
            containerPort: 80
            hostPort: 80
          - name: http-alt
            containerPort: 8080
            hostPort: 8080
        volumeMounts:
          - mountPath: "/etc/nginx/conf.d"
            name: etc-nginx-confd
      volumes:
        - hostPath:
            path: "/etc/nginx/conf.d"
          name: etc-nginx-confd

Hacer que la imagen de Docker de NGINX Plus esté disponible en el nodo

Como hemos indicado anteriormente, ya hemos creado una imagen de Docker de NGINX Plus. Ahora vamos a hacer que esté disponible en el nodo. Para simplificar, no utilizamos un repositorio privado de Docker, sino que cargamos manualmente la imagen en el nodo.

En el host donde creamos la imagen de Docker, ejecutamos el siguiente comando para guardar la imagen en un archivo:

$ docker save -o nginxplus.tar nginxplus

Transferimos nginxplus.tar al nodo y ejecutamos el siguiente comando en él para cargar la imagen desde el archivo:

$ docker load -i nginxplus.tar

Configuración de NGINX Plus

En la carpeta /etc/nginx del contenedor de NGINX Plus, conservamos el archivo de configuración principal predeterminado nginx.conf que se incluye con los paquetes de NGINX Plus. La directiva include del archivo predeterminado carga otros archivos de configuración de la carpeta /etc/nginx/conf.d. Tal como se especifica en el archivo de declaración del controlador de replicación de NGINX Plus (nginxplus-rc.yaml), compartimos la carpeta /etc/nginx/conf.d del nodo de NGINX Plus con el contenedor. Esto nos permite modificar los archivos de configuración almacenados en la carpeta (en el nodo) sin tener que volver a compilar la imagen de Docker de NGINX Plus, algo que tendríamos que hacer si creáramos la carpeta directamente en el contenedor. Colocamos nuestro archivo de configuración específico de Kubernetes (backend.conf) en la carpeta compartida.

Primero, vamos a crear la carpeta /etc/nginx/conf.d en el nodo.

$ sudo mkdir -p /etc/nginx/conf.d

A continuación, creamos allí el archivo backend.conf e incluimos estas directivas:

  • resolver – Define el servidor DNS que NGINX Plus utiliza para volver a resolver periódicamente el nombre de dominio que usamos para identificar nuestros servidores ascendentes (en la directiva server dentro del bloque upstream, que se explica en el siguiente punto). Identificamos este servidor DNS mediante su nombre de dominio, kube-dns.kube-system.svc.cluster.local. El parámetro valid indica a NGINX Plus que envíe la solicitud de nueva resolución cada cinco segundos. (Tenga en cuenta que el proceso de resolución de esta directiva difiere del de los servidores ascendentes: este nombre de dominio solo se resuelve cuando NGINX se inicia o se recarga, y NGINX Plus utiliza el servidor o los servidores DNS del sistema definidos en el archivo /etc/resolv.conf para resolverlo).
  • upstream – Crea un grupo de servidores upstream denominado backend que contiene los servidores que proporcionan el servicio de Kubernetes que estamos exponiendo. En lugar de enumerar los servidores individualmente, los identificamos mediante un nombre de host completo en una única directiva server. El parámetro resolve indica a NGINX Plus que vuelva a resolver el nombre de host en tiempo de ejecución, de acuerdo con la configuración especificada mediante la directiva resolver. Dado que tanto el DNS de Kubernetes como NGINX Plus (R10 y versiones posteriores) admiten registros de servicio DNS (SRV), NGINX Plus puede obtener mediante DNS los números de puerto de los servidores upstream. Incluimos el parámetro service para que NGINX Plus solicite registros SRV, especificando el nombre (_http) y el protocolo (_tcp) de los puertos expuestos por nuestro servicio. Declaramos esos valores en el archivo webapp-svc.yaml, que se explica más adelante en Creación del controlador de replicación para el servicio. Para obtener más información sobre la detección de servicios mediante DNS, consulte Uso de DNS para la detección de servicios con NGINX y NGINX Plus en nuestro blog.
  • server (dos veces): define dos servidores virtuales:
    • El primer servidor escucha en el puerto 80 y distribuye las solicitudes entrantes de /webapp (nuestro servicio) entre los pods que ejecutan instancias del servicio. También configuramos comprobaciones de estado activas.
    • El segundo servidor escucha en el puerto 8080. Aquí configuramos la supervisión de la actividad en tiempo real de NGINX Plus. Más adelante, la utilizaremos para comprobar que NGINX Plus se haya reconfigurado correctamente. [Editor: La configuración de este segundo servidor se ha actualizado para utilizar la API de NGINX Plus, que sustituye al módulo de estado independiente utilizado originalmente y hace que quede obsoleto.]
resolver kube-dns.kube-system.svc.cluster.local valid=5s;

upstream backend {
    zone upstream-backend 64k;
    server webapp-svc.default.svc.cluster.local service=_http._tcp resolve;
}

server {
    listen 80;
    status_zone backend-servers;

    location /webapp {
        proxy_pass http://backend;
        health_check;
    }
}

server {
    listen 8080;
    root /usr/share/nginx/html;

    location = /dashboard.html { }

    location = / {
        return 302 /dashboard.html;
    }

    location /api {
        api write=on;
    }
}

Creación del controlador de replicación

Ahora ya podemos crear el controlador de replicación ejecutando este comando:

$ kubectl create -f nginxplus-rc.yaml

Para comprobar que se ha creado el pod de NGINX Plus, ejecutamos:

$ kubectl get pods
NAME                 READY     STATUS    RESTARTS   AGE
nginxplus-rc-0ts5t   1/1       Running   0          17s

Estamos ejecutando Kubernetes en un entorno local de Vagrant, por lo que sabemos que la dirección IP externa de nuestro nodo es 10.245.1.3 y utilizaremos esa dirección durante el resto de este ejemplo. Si está ejecutando Kubernetes en un proveedor de servicios en la nube, puede obtener la dirección IP externa de su nodo ejecutando:

$ kubectl get nodes node-name -o json | grep -i externalIP -A 1                "type": "ExternalIP",
                "address": XXX.XXX.XXX.XXX

Si utiliza un entorno en la nube, no olvide configurar una regla de firewall para permitir que el nodo de NGINX Plus acepte el tráfico entrante. Consulte la documentación de su proveedor de servicios en la nube.

Podemos comprobar que nuestro pod de NGINX Plus está en funcionamiento consultando el panel de monitorización de actividad en tiempo real de NGINX Plus, disponible en el puerto 8080 de la dirección IP externa del nodo (en nuestro caso, http://10.245.1.3:8080/dashboard.html). Sin embargo, si lo consultamos en este momento, no veremos ningún servidor para nuestro servicio, ya que todavía no lo hemos creado.

El panel de monitorización de la actividad en tiempo real de NGINX Plus antes de crear los servicios de Kubernetes

Creación de un servicio sencillo de Kubernetes

Ahora es el momento de crear un servicio de Kubernetes. Nuestro servicio consta de dos servidores web, cada uno de los cuales ofrece una página web con información sobre el contenedor en el que se ejecuta.

Creación del controlador de replicación para el servicio

Primero creamos un controlador de replicación para que Kubernetes garantice que el número especificado de réplicas del servidor web (pods) esté siempre en ejecución en el clúster. Este es el archivo de declaración (webapp-rc.yaml):

apiVersion: v1kind: ReplicationController
metadata:
  name: webapp-rc
spec:
  replicas: 2
  selector:
    app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: hello
        image: nginxdemos/hello 
        ports:
        - containerPort: 80

Nuestro controlador consta de dos servidores web. Declaramos un controlador formado por pods con un único contenedor que expone el puerto 80. La imagen nginxdemos/hello se descargará de Docker Hub.

Para crear el controlador de replicación, ejecutamos el siguiente comando:

$ kubectl create -f webapp-rc.yaml

Para comprobar que nuestros pods se han creado, podemos ejecutar el siguiente comando. Usamos el selector de etiquetas app=webapp para obtener únicamente los pods creados por el controlador de replicación en el paso anterior:

$ kubectl get pods -l app=webapp
NAME             READY     STATUS    RESTARTS   AGE
webapp-rc-544f1   1/1       Running   0          2m
webapp-rc-uk6pm   1/1       Running   0          2m

Creación del servicio

A continuación, creamos un servicio para los pods creados por nuestro controlador de replicación. Declaramos el servicio mediante el siguiente archivo (webapp-service.yaml):

apiVersion: v1kind: Service
metadata:
  name: webapp-svc
spec:
  clusterIP: None
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: webapp

Aquí declaramos un servicio sin encabezado especial estableciendo el campo ClusterIP en None. Con este tipo de servicio, no se asigna ninguna dirección IP del clúster y el servicio no está disponible a través de kube-proxy. Una consulta DNS al DNS de Kubernetes devuelve varios registros A (las direcciones IP de nuestros pods).

También declaramos el puerto que NGINX Plus utilizará para conectarse a los pods. Además de especificar los números de puerto y puerto de destino, indicamos el nombre (http) y el protocolo (TCP). Utilizamos esos valores en el archivo de configuración de NGINX Plus, donde indicamos a NGINX Plus que obtenga los números de puerto de los pods mediante DNS utilizando registros SRV.

Al establecer el campo selector en app: webapp, declaramos qué pods pertenecen al servicio, concretamente los pods creados por nuestro controlador de replicación de NGINX (definido en webapp-rc.yaml).

Ejecutamos el siguiente comando, que crea el servicio:

$ kubectl create -f webapp-service.yaml

Ahora, si actualizamos la página del panel de control y hacemos clic en la pestaña «Upstreams» de la esquina superior derecha, veremos los dos servidores que hemos añadido.

El panel de monitorización de la actividad en tiempo real de NGINX Plus después de crear los servicios de Kubernetes

También podemos comprobar que NGINX Plus distribuye el tráfico entre los pods del servicio. Si es así, cuando accedemos a http://10.245.1.3/webapp/ desde un navegador, la página nos muestra información sobre el contenedor en el que se ejecuta el servidor web, como el nombre de host y la dirección IP.

Si actualizamos esta página varias veces y consultamos el panel de estado, veremos cómo se distribuyen las solicitudes entre los dos servidores upstream.

Escalar el servicio de Kubernetes

[Editor: Esta sección se ha actualizado para utilizar la API de NGINX Plus, que sustituye al módulo de estado independiente utilizado originalmente y lo marca como obsoleto.]

Ahora añadamos dos pods más a nuestro servicio y asegurémonos de que la configuración de NGINX Plus vuelva a actualizarse automáticamente. Ejecutamos este comando para cambiar el número de pods a cuatro escalando el controlador de replicación:

$ kubectl scale rc webapp-rc --replicas=4
scaled

Para comprobar que NGINX Plus se ha reconfigurado, podríamos volver a consultar el panel, pero esta vez utilizaremos la API de NGINX Plus. Ejecutamos el siguiente comando, donde 10.245.1.3 es la dirección IP externa de nuestro nodo NGINX Plus y 3 es la versión de la API de NGINX Plus. Para dar un formato legible a la salida JSON, la canalizamos a jq.

$ curl -s 10.245.1.3:8080/api/3/http/upstreams/backend/servers | jq{
  "peers": [
    {
      "id": 1,
      "server": "10.0.0.1:80",
      "backup": false,
      "weight": 1,
      "state": "unhealthy",
      "active": 0,
      "requests": 1,
      "responses": {
        "1xx": 0,
        "2xx": 0,
        "3xx": 0,
        "4xx": 0,
        "5xx": 0,
        "total": 0
      },
      "sent": 0,
      "received": 0,
      "fails": 0,
      "unavail": 0,
      "health_checks": {
        "checks": 1,
        "fails": 1,
        "unhealthy": 1,
        "last_passed": false
      },
      "downtime": 33965,
      "downstart": 1445378182275,
      "selected": 1445378131000
    },
    {
      "id": 2,
      "server": "10.246.1.6:80",
      ...
    },
    {
      "id": 3,
      "server": "10.246.3.2:80",
       ...
    {
      "id": 4,
      "server": "10.0.0.2:80",
      ...
    }
  ],
  "keepalive": 0
}

La matriz peers de la salida JSON tiene exactamente cuatro elementos, uno por cada servidor web.

Ahora reduzcamos el número de pods de cuatro a uno y volvamos a comprobar el estado de NGINX Plus:

$ kubectl scale rc webapp-rc --replicas=1scaled

$ curl -s 10.245.1.3:8080/api/3/http/upstreams/backend/servers | jq

Ahora la matriz peers de la salida JSON contiene un solo elemento (la salida es la misma que la del par con el ID 1 en el comando de ejemplo anterior).

Ahora que tenemos NGINX Plus en funcionamiento, podemos empezar a aprovechar sus funciones avanzadas, como la persistencia de sesión, la terminación SSL/TLS, el enrutamiento de solicitudes, la monitorización avanzada y muchas más.

Resumen

Las opciones de reconfiguración dinámica disponibles en NGINX Plus permiten integrarlo fácilmente con Kubernetes, ya sea mediante programación a través de una API o íntegramente mediante DNS. El uso de NGINX Plus para exponer servicios de Kubernetes a Internet ofrece muchas funciones de las que carecen las soluciones de balanceo de carga integradas actualmente en Kubernetes.

Para descubrir cómo funciona NGINX Plus con Kubernetes, comience hoy mismo su prueba gratuita de 30 días o póngase en contacto con nosotros para hablar sobre su caso de uso.


Compartir

Artículos relacionados del blog

Únete a F5 NGINX en AppWorld 2024
NGINX | 04/01/2024

Únete a F5 NGINX en AppWorld 2024

Descubre las numerosas razones para asistir al evento insignia de F5, que incluirá un emocionante anuncio sobre la cartera de productos NGINX.

Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source
NGINX | 26/09/2023

Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source

La función de diccionario compartido permite configurar NGINX sin necesidad de reiniciarlo al renovar los certificados SSL/TLS.

Exposición de APIs en Kubernetes
NGINX | 10/03/2022

Exposición de APIs en Kubernetes

La unidad 2 de Microservices March 2022 se centra en cómo exponer tus API en Kubernetes. Aquí tienes enlaces a los recursos que necesitas: la retransmisión en directo del 14 de marzo, artículos de blog y otros recursos de preparación, y el laboratorio práctico «Protege las API de Kubernetes mediante la limitación de solicitudes».

NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto
NGINX | 23/08/2021

NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto

Hoy, en NGINX Sprint 2.0, anunciamos cómo respaldaremos nuestra visión del futuro de las aplicaciones modernas con una mayor presencia en la comunidad de código abierto, incluida la participación en el proyecto comunitario Kubernetes, nuevos proyectos de software de código abierto y la arquitectura de referencia para aplicaciones modernas.

Presentamos NGINX Plus R22
NGINX | 09/06/2020

Presentamos NGINX Plus R22

NGINX Plus R22 incorpora nuevas funcionalidades, como la compatibilidad con OCSP para verificar la revocación de certificados en TLS mutuo, el uso de varios proveedores de identidad OIDC en una configuración, el seguimiento en tiempo real de la limitación de solicitudes y conexiones en el panel de NGINX Plus y mejoras en NGINX JavaScript.

Presentamos NGINX Plus R17
NGINX | 11/12/2018

Presentamos NGINX Plus R17

NGINX Plus R17 incorpora compatibilidad con la limitación de velocidad en dos fases y con TLS 1.3, la versión más reciente del protocolo Transport Layer Security. La configuración de OpenID Connect es más sencilla y NGINX ModSecurity WAF es el doble de rápido que antes. También se ha actualizado el módulo JavaScript de NGINX.