Apache APISIX Ingress Controller에서 외부 서비스 프록시하는 방법
Yeqi Peng
January 13, 2023
이 튜토리얼에서는 ApisixUpstream 리소스에서 외부 서비스를 구성하는 방법을 소개합니다.
이 기능은 서비스가 타사 서비스나 다른 K8s 클러스터의 서비스에 의존할 때 유용합니다. 또한 참조된 서비스 이름이 업데이트될 때 많은 수의 ApisixRoute를 수정하지 않고도 공유된 ExternalName 서비스로 ApisixRoute를 관리할 수 있는 방법을 제공합니다.
사전 요구 사항
- 사용 가능한 Kubernetes 클러스터
- 사용 가능한 APISIX 및 APISIX Ingress Controller 설치
APISIX가 apisix
네임스페이스에 설치되어 있다고 가정합니다.
소개
APISIX Ingress는 K8s ExternalName 서비스와 직접 도메인 모두에 대해 외부 서비스를 백엔드로 구성하는 것을 지원합니다.
이 경우 ApisixRoute 리소스에서 backends
필드를 구성하지 않습니다. 대신 upstreams
필드를 사용하여 externalNodes
필드가 구성된 ApisixUpstream 리소스를 참조합니다.
예를 들어:
# 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
이 구성은 인그레스 컨트롤러에게 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
여야 하며 이름은 서비스 이름이어야 합니다. Service
타입으로 ApisixUpstream을 구성하면 인그레스 컨트롤러가 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
위 구성을 적용한 후 APISIX를 통해 httpbin.org
에 직접 접근할 수 있습니다.
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 서비스에 의해 처리되었음을 나타냅니다.
외부 이름 서비스 업스트림
test
네임스페이스에 간단한 httpbin 앱을 배포하여 나중에 생성할 외부 이름 서비스의 백엔드로 사용하겠습니다.
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
그런 다음 apisix
네임스페이스에 ExternalName 서비스를 생성하기 위해 다음 구성을 사용합니다.
apiVersion: v1
kind: Service
metadata:
name: ext-httpbin
spec:
type: ExternalName
externalName: httpbin.test.svc
이제 ExternalName 서비스 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의 기능적 경계를 확장하여 외부 서비스로 요청을 프록시하는 방법을 살펴보았습니다. 이를 통해 사용자는 인증 서비스나 클러스터 간 서비스와 같은 타사 서비스를 쉽게 통합할 수 있습니다.