Como Proxiar Serviços Externos no Apache APISIX Ingress Controller
Yeqi Peng
January 13, 2023
Neste tutorial, vamos apresentar como configurar serviços externos em recursos ApisixUpstream.
Isso é útil quando o seu serviço depende de um serviço de terceiros ou de um serviço de outro cluster K8s. Também fornece uma maneira de gerenciar seu ApisixRoute com serviços ExternalName compartilhados, sem a necessidade de modificar um grande número de ApisixRoutes quando o nome do serviço referenciado é atualizado.
Pré-requisitos
- Um cluster Kubernetes disponível
- Uma instalação disponível do APISIX e do APISIX Ingress Controller
Assumimos que o seu APISIX está instalado no namespace apisix
.
Introdução
O APISIX Ingress suporta a configuração de serviços externos como backends, tanto para serviços ExternalName do K8s quanto para domínios diretos.
Neste caso, não configuramos o campo backends
no recurso ApisixRoute. Em vez disso, usaremos o campo upstreams
para referenciar um recurso ApisixUpstream com o campo externalNodes
configurado.
Por exemplo:
# 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: # Não usaremos o campo `backends` # - serviceName: httpbin # servicePort: 80 upstreams: - name: httpbin-upstream
Esta configuração informa ao controlador de ingress para não resolver os hosts upstream através dos serviços K8s, mas sim usar a configuração definida no ApisixUpstream referenciado.
O ApisixUpstream referenciado DEVE ter o campo externalNodes
configurado. Por exemplo:
# httpbin-upstream.yaml apiVersion: apisix.apache.org/v2 kind: ApisixUpstream metadata: name: httpbin-upstream spec: externalNodes: - type: Domain name: httpbin.org
Neste exemplo de yaml, configuramos httpbin.org
como o backend. O tipo Domain
indica que este é um serviço de terceiros, e qualquer nome de domínio é suportado aqui.
Se você quiser usar um serviço de nome externo no cluster K8s, o tipo deve ser Service
e o nome deve ser o nome do serviço. Ao configurar o ApisixUpstream com o tipo Service
, o controlador de ingress rastreará automaticamente o conteúdo do serviço ExternalName e suas alterações.
Upstream de Domínio 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
Após aplicar a configuração acima, podemos tentar acessar httpbin.org
diretamente através do APISIX.
kubectl exec -it -n apisix APISIX_POD_NAME -- curl -i -H "Host: local.httpbin.org" http://127.0.0.1:9080/get
Se tudo funcionar, você verá o resultado assim:
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" }
O cabeçalho Server: APISIX/3.0.0
indica que a solicitação foi enviada pelo APISIX. E a resposta contém X-Amzn-Trace-Id
, indicando que a solicitação foi tratada pelo serviço httpbin online.
Upstream de Serviço de Nome Externo
Vamos implantar um aplicativo httpbin simples no namespace test
como o backend para o serviço de nome externo que criaremos posteriormente.
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
Em seguida, use a seguinte configuração para criar um serviço ExternalName no namespace apisix
.
apiVersion: v1 kind: Service metadata: name: ext-httpbin spec: type: ExternalName externalName: httpbin.test.svc
Agora podemos criar um ApisixRoute e ApisixUpstream para o serviço 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
Assim que as configurações forem sincronizadas, tente acessá-la com o seguinte comando.
O único argumento que muda é o cabeçalho que passamos.
kubectl exec -it -n apisix APISIX_POD_NAME -- curl -i -H "Host: ext.httpbin.org" http://127.0.0.1:9080/get
A saída deve ser semelhante 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 a resposta é semelhante à anterior, mas alguns campos não existem. Isso ocorre porque a solicitação foi enviada para o nosso serviço httpbin local, e não para o online.
Domínio em Serviço de Nome Externo
O serviço de nome externo também pode conter qualquer nome de domínio fora do cluster K8s.
Vamos atualizar a configuração do serviço externo que aplicamos na seção anterior.
apiVersion: v1 kind: Service metadata: name: ext-httpbin spec: type: ExternalName externalName: httpbin.org
Tente acessá-lo novamente, e a saída deve conter múltiplos origin
e um cabeçalho X-Amzn-Trace-Id
, o que significa que estamos acessando o serviço online httpbin.org
.
Conclusão
Neste tutorial, estendemos os limites funcionais do APISIX Ingress Controller ao encaminhar solicitações para serviços externos. Isso permite que os usuários integrem facilmente serviços de terceiros, como serviços de autenticação ou serviços entre clusters.
Para mais informações sobre gateway de API, visite nossos blogs ou entre em contato conosco.