如何在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
フィールドを設定しません。代わりに、externalNodes
フィールドが設定されたApisixUpstreamリソースを参照するためにupstreams
フィールドを使用します。
例えば:
# 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
で、名前はサービス名である必要があります。Service
タイプでApisixUpstreamを設定することで、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
上記の設定を適用した後、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サービスではなく、ローカルの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の機能範囲を拡張し、外部サービスへのリクエストをプロキシする方法を紹介しました。これにより、ユーザーは認証サービスやクロスクラスタサービスなどのサードパーティサービスを簡単に統合できます。