¿Cómo APISIX Ingress admite plugins personalizados?

API7.ai

October 11, 2022

Products

Ingress y Controlador de Ingress

Ingress es uno de los objetos API de Kubernetes. Gestiona el acceso externo a los servicios en un clúster, típicamente HTTP/HTTPS.

Los clientes pueden seguir las reglas de Ingress para enrutar las solicitudes de los clientes a los servicios del clúster de Kubernetes o a un Pod específico.

k8s_cluster.png

A continuación se muestra un ejemplo de un recurso de Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: apisix-gateway
spec:
  rules:
    - host: apisix.apache.org
      http:
        paths:
          - backend:
              service:
                name: apisix-gateway
                port:
                  number: 80
            path: /
            pathType: Exact

El ejemplo anterior contiene los siguientes elementos:

  • metadata.name: nombre del recurso de Ingress
  • spec.rules[].host: dominio utilizado para el acceso externo
  • spec.rules[].http.paths[].backend: describe la información relacionada con los servicios en un clúster
  • spec.rules[].http.paths[].path: describe las rutas utilizadas por el acceso externo a los servicios en un clúster
  • spec.rules[].http.paths[].pathType: describe el tipo de ruta para gestionar el acceso externo a los servicios en el clúster

Basándonos en el ejemplo anterior, podemos notar que la especificación del recurso de Ingress es relativamente simple.

Ingress es una definición de recurso en Kubernetes que no puede manejar tráfico por sí misma. Por lo tanto, si queremos que los recursos de Ingress sean efectivos, debemos usar un controlador para procesar estos recursos de Ingress, lo que se conoce como el controlador de Ingress.

El controlador de Ingress estaría observando constantemente cualquier cambio de recurso en el clúster de Kubernetes y convertiría las reglas de los recursos de Ingress en las reglas de proxy de la capa de datos para que la capa de datos pueda manejar el tráfico.

En un entorno de producción real, hay muchos tipos diferentes de solicitudes de clientes. Por ejemplo, los recursos de Ingress no pueden describir directamente algunas de las características más comunes como la autenticación y la reescritura de URI. Entonces, ¿cómo podemos satisfacer estos requisitos?

¿Cómo soporta Ingress-NGINX las extensiones?

Primero, usaremos un ejemplo del controlador Ingress-NGINX en el ecosistema de Kubernetes para demostrar cómo usar las extensiones.

Podemos usar Annotation para describir las extensiones necesarias en los recursos de Ingress en Ingress-NGINX. Por ejemplo:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: https://foo.com,https://bar.com
    nginx.ingress.kubernetes.io/cors-allow-headers: x-foo-1,x-foo-2
    nginx.ingress.kubernetes.io/cors-allow-methods: GET,POST,PUT
  name: nginx-ingress
spec:
  rules:
    - host: kubernetes.github.io
      http:
        paths:
          - path: /ingress
            pathType: Exact
            backend:
              service:
                name: nginx
                port:
                  number: 80

La configuración anterior habilita CORS.

Es relativamente simple agregar Annotations al recurso de Ingress; sin embargo, debemos notar que el controlador de Ingress-NGINX necesita soporte completo para estas Annotations; de lo contrario, la configuración no tendrá efecto. Si necesitamos usar algunas otras características no desarrolladas del controlador de Ingress-NGINX, necesitamos hacer algunos desarrollos personalizados.

Las siguientes secciones describen cómo usar el controlador de Ingress de Apache APISIX para cumplir con estos requisitos.

Uso de plugins en APISIX Ingress

Apache APISIX Ingress utiliza plugins para satisfacer las diversas necesidades de los clientes en el manejo del tráfico y en escenarios específicos. Actualmente, hay más de 80 plugins listos para usar, y los usuarios pueden desarrollar plugins personalizados para soportar nuevas características.

apisix.PNG

Hay muchas formas diferentes de desarrollar plugins personalizados:

  • Los usuarios pueden usar Lua para desarrollar plugins, y estos plugins pueden ejecutarse internamente en APISIX
  • Los usuarios también pueden usar otros lenguajes de programación para desarrollar plugins; este mecanismo se llama "plugin runner", y los plugins desarrollados por este mecanismo se llaman "External Plugin"

Consulte la documentación oficial sobre el desarrollo de plugins:

Introduciremos tres formas de desarrollar plugins usando Lua en APISIX Ingress.

Modo CRD Puro

El controlador de APISIX Ingress soporta su propia especificación CRD, y puedes habilitar directamente plugins en las reglas de enrutamiento (ya sea un plugin interno o un plugin personalizado). Por ejemplo:

apiVersion: apisix.apache.org/v2beta3
kind: ApisixRoute
metadata:
  name: httpbin-route
spec:
  http:
    - name: rule1
      match:
        hosts:
          - apisix.apache.org
        paths:
          - /apisix-ingress
      backends:
        - serviceName: apisix-gateway
          servicePort: 80
      plugins:
        - name: cors
          enable: true
          config:
            allow_origins: http://foo.bar.org
            allow_methods: "GET,POST"
            max_age: 3600
            expose_headers: x-foo,x-baz
            allow_headers: x-from-ingress
            allow_credential: true

Los usuarios pueden usar la configuración anterior para crear reglas de enrutamiento, y el plugin cors estaría habilitado en esta ruta.

Esta forma es la más nativa en APISIX Ingress, y se integra bien con APISIX. Además, cuando los usuarios agregan nuevos plugins personalizados, APISIX Ingress no necesita ser rediseñado, por lo que los usuarios pueden usarlo directamente.

Modo CRD + Annotations de Ingress

También podemos usar CRD + Annotations de Ingress para extender las características en APISIX Ingress, por ejemplo:

apiVersion: apisix.apache.org/v2
kind: ApisixPluginConfig
metadata:
  name: cors-plugin
spec:
  plugins:
    - name: cors
      enable: true
      config:
        allow_origins: http://foo.bar.org
        allow_methods: "GET,POST"
        max_age: 3600
        expose_headers: x-foo,x-baz
        allow_headers: x-from-ingress
        allow_credential: true
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: apisix
    k8s.apisix.apache.org/plugin-config-name: cors-plugin
  name: apisix-ingress
spec:
  rules:
    - host: apisix.apache.org
      http:
        paths:
          - path: /apisix-ingress
            pathType: Exact
            backend:
              service:
                name: apisix-gateway
                port:
                  number: 80

Usando la configuración anterior, podemos crear de forma independiente una configuración de plugin llamada cors-plugin y usar k8s.apisix.apache.org/plugin-config-name: cors-plugin en el recurso de Ingress para referenciarla. El efecto real es casi el mismo que la primera configuración; ambos habilitarían el plugin cors para las rutas correspondientes.

Bajo este modo, la configuración del plugin puede considerarse como un recurso independiente, y múltiples recursos de Ingress también pueden compartirlos. De manera similar, no es necesario realizar desarrollos personalizados.

Modo Annotations de Ingress

Debido a la semántica limitada de los recursos de Ingress, generalmente usaríamos annotations para agregar información adicional a los objetos de recursos, lo que también es la forma más común de extender las capacidades de Ingress. Por ejemplo:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: apisix
    k8s.apisix.apache.org/enable-cors: "true"
    k8s.apisix.apache.org/cors-allow-origin: https://foo.com,https://bar.com
    k8s.apisix.apache.org/cors-allow-headers: x-foo-1,x-foo-2
    k8s.apisix.apache.org/cors-allow-methods: GET,POST,PUT
  name: apisix-ingress
spec:
  rules:
    - host: apisix.apache.org
      http:
        paths:
          - path: /apisix-ingress
            pathType: Exact
            backend:
              service:
                name: apisix-gateway
                port:
                  number: 80

La configuración anterior agregará información adicional relacionada con cors al recurso de Ingress. El controlador de APISIX Ingress podría entonces identificar esta información y convertirla en la configuración de la capa de datos para extender las características del recurso de Ingress.

Sin embargo, bajo este modo, debemos asegurarnos de que el controlador de APISIX Ingress ya pueda procesar estas Annotations. De lo contrario, necesitamos hacer algunos desarrollos personalizados.

Si necesitas realizar desarrollos personalizados, consulta el siguiente documento:

Conclusión

Este artículo introduce principalmente las especificaciones relacionadas con los recursos de Ingress y cómo extender las características para los recursos de Ingress. Por ejemplo, en Ingress-NGINX, generalmente solo podemos usar Annotations para extender características. Sin embargo, en Apache APISIX Ingress, tenemos tres modos de configuración para satisfacer requisitos avanzados y más escenarios. Además, los usuarios no necesitan desarrollos personalizados para plugins personalizados en la mayoría de los casos.

Tags: