Cómo hacer proxy de servicios externos en Apache APISIX Ingress Controller
Yeqi Peng
January 13, 2023
En este tutorial, presentaremos cómo configurar servicios externos en recursos de ApisixUpstream.
Esto es útil cuando tu servicio depende de un servicio de terceros o de un servicio de otro clúster de K8s. También proporciona una forma de gestionar tu ApisixRoute con servicios ExternalName compartidos, sin necesidad de modificar un gran número de ApisixRoutes cuando se actualiza el nombre del servicio referenciado.
Requisitos previos
- Un clúster de Kubernetes disponible
- Una instalación disponible de APISIX y APISIX Ingress Controller
Asumimos que tu APISIX está instalado en el espacio de nombres apisix
.
Introducción
APISIX Ingress admite la configuración de servicios externos como backends, tanto para servicios ExternalName de K8s como para dominios directos.
En este caso, no configuramos el campo backends
en el recurso ApisixRoute. En su lugar, usaremos el campo upstreams
para referenciar un recurso ApisixUpstream con el campo externalNodes
configurado.
Por ejemplo:
# httpbin-route.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: rule1
match:
hosts:
- local.httpbin.org
paths:
- /*
# backends: # No usaremos el campo `backends`
# - serviceName: httpbin
# servicePort: 80
upstreams:
- name: httpbin-upstream
Esta configuración le indica al controlador de ingress que no resuelva los hosts de upstream a través de los servicios de K8s, sino que use la configuración definida en el ApisixUpstream referenciado.
El ApisixUpstream referenciado DEBE tener el campo externalNodes
configurado. Por ejemplo:
# httpbin-upstream.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: httpbin-upstream
spec:
externalNodes:
- type: Domain
name: httpbin.org
En este ejemplo de yaml, configuramos httpbin.org
como el backend. El tipo Domain
indica que se trata de un servicio de terceros, y aquí se admite cualquier nombre de dominio.
Si deseas usar un servicio de nombre externo en el clúster de K8s, el tipo debe ser Service
y el nombre debe ser el nombre del servicio. Al configurar ApisixUpstream con el tipo Service
, el controlador de ingress rastreará automáticamente el contenido del servicio ExternalName y sus cambios.
Upstream de Dominio Externo
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: httpbin-route
spec:
http:
- name: rule1
match:
hosts:
- local.httpbin.org
paths:
- /*
upstreams:
- name: httpbin-upstream
---
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: httpbin-upstream
spec:
externalNodes:
- type: Domain
name: httpbin.org
Después de aplicar la configuración anterior, podemos intentar acceder a httpbin.org
directamente a través de APISIX.
kubectl exec -it -n apisix APISIX_POD_NAME -- curl -i -H "Host: local.httpbin.org" http://127.0.0.1:9080/get
Si todo funciona correctamente, verás un resultado como este:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 321
Connection: keep-alive
Date: Thu, 15 Dec 2022 10:47:30 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.0.0
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "local.httpbin.org",
"User-Agent": "curl/7.29.0",
"X-Amzn-Trace-Id": "Root=xxxxx",
"X-Forwarded-Host": "local.httpbin.org"
},
"origin": "127.0.0.1, xxxxxxxxx",
"url": "http://local.httpbin.org/get"
}
El encabezado Server: APISIX/3.0.0
indica que la solicitud ha sido enviada desde APISIX. Y la respuesta contiene X-Amzn-Trace-Id
, lo que indica que la solicitud fue manejada por el servicio httpbin en línea.
Upstream de Servicio de Nombre Externo
Implementemos una aplicación simple de httpbin en el espacio de nombres test
como backend para el servicio de nombre externo que crearemos más adelante.
kubectl create ns test
kubectl -n test run httpbin --image-pull-policy IfNotPresent --image=kennethreitz/httpbin --port 80
kubectl -n test expose pod/httpbin --port 80
Luego, usa la siguiente configuración para crear un servicio ExternalName en el espacio de nombres apisix
.
apiVersion: v1
kind: Service
metadata:
name: ext-httpbin
spec:
type: ExternalName
externalName: httpbin.test.svc
Ahora podemos crear un ApisixRoute y un ApisixUpstream para el servicio ExternalName.
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: ext-route
spec:
http:
- name: rule1
match:
hosts:
- ext.httpbin.org
paths:
- /*
upstreams:
- name: ext-upstream
---
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
name: ext-upstream
spec:
externalNodes:
- type: Service
name: ext-httpbin
Una vez que las configuraciones estén sincronizadas, intenta acceder con el siguiente comando.
El único argumento que cambia es el encabezado que pasamos.
kubectl exec -it -n apisix APISIX_POD_NAME -- curl -i -H "Host: ext.httpbin.org" http://127.0.0.1:9080/get
La salida debería ser similar a:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 234
Connection: keep-alive
Date: Thu, 15 Dec 2022 10:54:21 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.0.0
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "ext.httpbin.org",
"User-Agent": "curl/7.29.0",
"X-Forwarded-Host": "ext.httpbin.org"
},
"origin": "127.0.0.1",
"url": "http://ext.httpbin.org/get"
}
Podemos ver que la respuesta es similar a la anterior, pero algunos campos no existen. Esto se debe a que la solicitud se envió a nuestro servicio local de httpbin en lugar del servicio en línea.
Dominio en Servicio de Nombre Externo
El servicio de nombre externo también puede contener cualquier nombre de dominio fuera del clúster de K8s.
Actualicemos la configuración del servicio externo que aplicamos en la sección anterior.
apiVersion: v1
kind: Service
metadata:
name: ext-httpbin
spec:
type: ExternalName
externalName: httpbin.org
Intenta acceder nuevamente, y la salida debería contener múltiples origin
y un encabezado X-Amzn-Trace-Id
, lo que significa que estamos accediendo al servicio en línea de httpbin.org
.
Conclusión
En este tutorial, extendemos los límites funcionales del controlador de ingress de APISIX al redirigir solicitudes a servicios externos. Esto permite a los usuarios integrar fácilmente servicios de terceros, como servicios de autenticación o servicios entre clústeres.
Para obtener más información sobre la puerta de enlace de API, visita nuestros blogs o contáctanos.