Comment proxifier des services externes dans APISIX Ingress Controller

Yeqi Peng

January 13, 2023

Products

Dans ce tutoriel, nous allons expliquer comment configurer des services externes dans les ressources ApisixUpstream.

Cela est utile lorsque votre service dépend d'un service tiers ou d'un service provenant d'un autre cluster K8s. Cela fournit également un moyen de gérer votre ApisixRoute avec des services ExternalName partagés, sans avoir à modifier un grand nombre d'ApisixRoutes lorsque le nom du service référencé est mis à jour.

Prérequis

  • un cluster Kubernetes disponible
  • une installation disponible d'APISIX et du contrôleur d'entrée APISIX

Nous supposons que votre APISIX est installé dans l'espace de noms apisix.

Introduction

APISIX Ingress prend en charge la configuration de services externes en tant que backends, à la fois pour les services ExternalName de K8s et les domaines directs.

Dans ce cas, nous ne configurons pas le champ backends dans la ressource ApisixRoute. Au lieu de cela, nous utiliserons le champ upstreams pour référencer une ressource ApisixUpstream avec le champ externalNodes configuré.

Par exemple :

# 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:  # Nous n'utiliserons pas le champ `backends`
    #    - serviceName: httpbin
    #      servicePort: 80
    upstreams:
    - name: httpbin-upstream

Cette configuration indique au contrôleur d'entrée de ne pas résoudre les hôtes en amont via les services K8s, mais d'utiliser la configuration définie dans la ressource ApisixUpstream référencée.

La ressource ApisixUpstream référencée DOIT avoir le champ externalNodes configuré. Par exemple :

# httpbin-upstream.yaml
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
  name: httpbin-upstream
spec:
  externalNodes:
  - type: Domain
    name: httpbin.org

Dans cet exemple yaml, nous avons configuré httpbin.org comme backend. Le type Domain indique qu'il s'agit d'un service tiers, et tout nom de domaine est pris en charge ici.

Si vous souhaitez utiliser un service de nom externe dans le cluster K8s, le type doit être Service et le nom doit être le nom du service. En configurant ApisixUpstream avec le type Service, le contrôleur d'entrée suivra automatiquement le contenu du service ExternalName et ses modifications.

Upstream de domaine externe

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

Après avoir appliqué la configuration ci-dessus, nous pouvons essayer d'accéder à httpbin.org directement via APISIX.

kubectl exec -it -n apisix APISIX_POD_NAME -- curl -i -H "Host: local.httpbin.org" http://127.0.0.1:9080/get

Si tout fonctionne, vous verrez un résultat comme celui-ci :

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"
}

L'en-tête Server: APISIX/3.0.0 indique que la requête a été envoyée depuis APISIX. Et la réponse contient X-Amzn-Trace-Id indiquant que la requête a été traitée par le service httpbin en ligne.

Upstream de service de nom externe

Déployons une application httpbin simple dans l'espace de noms test comme backend pour le service de nom externe que nous créerons plus tard.

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

Ensuite, utilisez la configuration suivante pour créer un service ExternalName dans l'espace de noms apisix.

apiVersion: v1
kind: Service
metadata:
  name: ext-httpbin
spec:
  type: ExternalName
  externalName: httpbin.test.svc

Maintenant, nous pouvons créer une ApisixRoute et une ApisixUpstream pour le service 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

Une fois les configurations synchronisées, essayez d'y accéder avec la commande suivante.

Le seul argument qui change est l'en-tête que nous passons.

kubectl exec -it -n apisix APISIX_POD_NAME -- curl -i -H "Host: ext.httpbin.org" http://127.0.0.1:9080/get

Le résultat devrait être similaire à :

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"
}

Nous pouvons voir que la réponse est similaire à la précédente, mais certains champs sont absents. C'est parce que la requête a été envoyée à notre service httpbin local plutôt qu'au service en ligne.

Domaine dans un service de nom externe

Le service de nom externe peut également contenir n'importe quel nom de domaine en dehors du cluster K8s.

Mettons à jour la configuration du service externe que nous avons appliquée dans la section précédente.

apiVersion: v1
kind: Service
metadata:
  name: ext-httpbin
spec:
  type: ExternalName
  externalName: httpbin.org

Essayez d'y accéder à nouveau, et le résultat devrait contenir plusieurs origin et un en-tête X-Amzn-Trace-Id, ce qui signifie que nous accédons au service httpbin.org en ligne.

Conclusion

Dans ce tutoriel, nous avons étendu les limites fonctionnelles du contrôleur d'entrée APISIX en redirigeant les requêtes vers des services externes. Cela permet aux utilisateurs d'intégrer facilement des services tiers, tels que des services d'authentification ou des services inter-clusters.

Pour plus d'informations sur les passerelles API, veuillez visiter nos blogs ou nous contacter.

Tags: