Как проксировать внешние сервисы в Apache APISIX Ingress Controller

Yeqi Peng

January 13, 2023

Products

В этом руководстве мы расскажем, как настроить внешние сервисы в ресурсах ApisixUpstream.

Это полезно, когда ваш сервис зависит от стороннего сервиса или сервиса из другого кластера K8s. Это также предоставляет способ управления вашим ApisixRoute с использованием общих сервисов ExternalName, без необходимости изменять большое количество ApisixRoutes при обновлении имени ссылочного сервиса.

Предварительные требования

  • доступный кластер Kubernetes
  • установленные APISIX и APISIX Ingress Controller

Мы предполагаем, что ваш APISIX установлен в пространстве имен apisix.

Введение

APISIX Ingress поддерживает настройку внешних сервисов в качестве бэкендов, как для сервисов K8s ExternalName, так и для прямых доменов.

В этом случае мы не настраиваем поле backends в ресурсе ApisixRoute. Вместо этого мы будем использовать поле upstreams для ссылки на ресурс ApisixUpstream с настроенным полем externalNodes.

Например:

# 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: # Мы не будем использовать поле `backends` # - serviceName: httpbin # servicePort: 80 upstreams: - name: httpbin-upstream

Эта конфигурация указывает контроллеру ingress не разрешать узлы бэкенда через сервисы K8s, а использовать конфигурацию, определенную в ссылочном ApisixUpstream.

Ссылочный ApisixUpstream ДОЛЖЕН иметь настроенное поле externalNodes. Например:

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

В этом примере yaml мы настроили httpbin.org в качестве бэкенда. Тип Domain указывает, что это сторонний сервис, и здесь поддерживается любое доменное имя.

Если вы хотите использовать сервис с внешним именем в кластере K8s, тип должен быть Service, а имя должно быть именем сервиса. Настроив ApisixUpstream с типом Service, контроллер ingress будет автоматически отслеживать содержимое сервиса ExternalName и его изменения.

Внешний доменный бэкенд

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

После применения вышеуказанной конфигурации мы можем попробовать получить доступ к httpbin.org напрямую через APISIX.

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

Если все работает, вы увидите результат, подобный этому:

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

Заголовок Server: APISIX/3.0.0 указывает, что запрос был отправлен через APISIX. А ответ содержит X-Amzn-Trace-Id, что указывает на то, что запрос был обработан онлайн-сервисом httpbin.

Внешний сервис с именем в качестве бэкенда

Давайте развернем простое приложение httpbin в пространстве имен test в качестве бэкенда для сервиса с внешним именем, который мы создадим позже.

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

Затем используйте следующую конфигурацию для создания сервиса ExternalName в пространстве имен apisix.

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

Теперь мы можем создать ApisixRoute и ApisixUpstream для сервиса с внешним именем.

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

После синхронизации конфигураций попробуйте получить доступ с помощью следующей команды.

Единственный аргумент, который изменяется, — это заголовок, который мы передаем.

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

Результат должен быть следующим:

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

Мы видим, что ответ похож на предыдущий, но некоторые поля отсутствуют. Это связано с тем, что запрос был отправлен на наш локальный сервис httpbin, а не на онлайн-сервис.

Домен во внешнем сервисе с именем

Сервис с внешним именем также может содержать любое доменное имя за пределами кластера K8s.

Давайте обновим конфигурацию внешнего сервиса, которую мы применили в предыдущем разделе.

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

Попробуйте снова получить доступ, и в выводе должно быть несколько origin и заголовок X-Amzn-Trace-Id, что означает, что мы обращаемся к онлайн-сервису httpbin.org.

Заключение

В этом руководстве мы расширили функциональные границы APISIX Ingress Controller, проксируя запросы на внешние сервисы. Это позволяет пользователям легко интегрировать сторонние сервисы, такие как сервисы аутентификации или кросс-кластерные сервисы.

Для получения дополнительной информации о API-шлюзах, пожалуйста, посетите наши блоги или свяжитесь с нами.

Tags: