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.