APISIX Ingressはカスタムプラグインをどのようにサポートするか

API7.ai

October 11, 2022

Products

Ingress & Ingress Controller

IngressはKubernetesのAPIオブジェクトの1つです。クラスター内のサービスへの外部アクセスを管理し、通常はHTTP/HTTPSを扱います。

クライアントはIngressルールに従って、クライアントリクエストをKubernetesクラスターのサービスまたは特定のPodにルーティングできます。

k8s_cluster.png

以下はIngressリソースの例です:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: apisix-gateway
spec:
  rules:
    - host: apisix.apache.org
      http:
        paths:
          - backend:
              service:
                name: apisix-gateway
                port:
                  number: 80
            path: /
            pathType: Exact

上記の例には以下の内容が含まれています:

  • metadata.name: Ingressリソースの名前
  • spec.rules[].host: 外部アクセスに使用されるドメイン
  • spec.rules[].http.paths[].backend: クラスター内のサービスに関する情報を記述
  • spec.rules[].http.paths[].path: クラスター内のサービスへの外部アクセスに使用されるパスを記述
  • spec.rules[].http.paths[].pathType: クラスター内のサービスへの外部アクセスを管理するためのパスタイプを記述

上記の例から、Ingressリソースの仕様は比較的シンプルであることがわかります。

IngressはKubernetes内のリソース定義であり、それ自体ではトラフィックを処理できません。そのため、Ingressリソースを有効にするためには、コントローラーを使用してこれらのIngressリソースを処理する必要があります。これがIngressコントローラーです。

Ingressコントローラーは、Kubernetesクラスター内のリソース変更を監視し、Ingressリソースルールをデータ層のプロキシルールに変換します。これにより、データ層がトラフィックを処理できるようになります。

実際の本番環境では、さまざまな種類のクライアントリクエストが存在します。例えば、Ingressリソースは認証やURIリライトなどの一般的な機能を直接記述できません。では、これらの要件をどのように満たすのでしょうか?

Ingress-NGINXは拡張機能をどのようにサポートするか?

まず、Kubernetesエコシステム内のIngress-NGINXコントローラーの例を使用して、拡張機能の使用方法を説明します。

Ingress-NGINXでは、Annotationを使用してIngressリソースに必要な拡張機能を記述できます。例えば:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: https://foo.com,https://bar.com
    nginx.ingress.kubernetes.io/cors-allow-headers: x-foo-1,x-foo-2
    nginx.ingress.kubernetes.io/cors-allow-methods: GET,POST,PUT
  name: nginx-ingress
spec:
  rules:
    - host: kubernetes.github.io
      http:
        paths:
          - path: /ingress
            pathType: Exact
            backend:
              service:
                name: nginx
                port:
                  number: 80

上記の設定により、CORSが有効になります。

IngressリソースにAnnotationを追加するのは比較的簡単ですが、Ingress-NGINXコントローラーがこれらのAnnotationを完全にサポートしている必要があります。そうでない場合、設定は有効になりません。Ingress-NGINXコントローラーの未開発の機能を使用する必要がある場合、カスタム開発を行う必要があります。

以下のセクションでは、Apache APISIX Ingressコントローラーを使用してこれらの要件を満たす方法について説明します。

APISIX Ingressでプラグインを使用する

Apache APISIX Ingressは、トラフィック処理や特定のシナリオに対する顧客のさまざまな要件を満たすためにプラグインを利用します。現在、80以上のすぐに使用できるプラグインがあり、ユーザーは新しい機能をサポートするためにカスタムプラグインを開発できます。

apisix.PNG

カスタムプラグインを開発する方法はいくつかあります:

  • ユーザーはLuaを使用してプラグインを開発でき、これらのプラグインはAPISIX内部で実行されます。
  • ユーザーは他のプログラミング言語を使用してプラグインを開発することもできます。このメカニズムは「プラグインランナー」と呼ばれ、このメカニズムで開発されたプラグインは「外部プラグイン」と呼ばれます。

プラグイン開発に関する公式ドキュメントを参照してください:

APISIX IngressでLuaを使用してプラグインを開発する3つの方法を紹介します。

純粋なCRDモード

APISIX Ingressコントローラーは、独自に設計されたCRD仕様をサポートしており、ルーティングルールで直接プラグインを有効にできます(内部プラグインまたはカスタムプラグイン)。例えば:

apiVersion: apisix.apache.org/v2beta3
kind: ApisixRoute
metadata:
  name: httpbin-route
spec:
  http:
    - name: rule1
      match:
        hosts:
          - apisix.apache.org
        paths:
          - /apisix-ingress
      backends:
        - serviceName: apisix-gateway
          servicePort: 80
      plugins:
        - name: cors
          enable: true
          config:
            allow_origins: http://foo.bar.org
            allow_methods: "GET,POST"
            max_age: 3600
            expose_headers: x-foo,x-baz
            allow_headers: x-from-ingress
            allow_credential: true

ユーザーは上記の設定を使用してルーティングルールを作成でき、このルートでCORSプラグインが有効になります。

この方法はAPISIX Ingressで最もネイティブにサポートされており、APISIXとうまく連携します。また、ユーザーが新しいカスタムプラグインを追加する場合、APISIX Ingressを再開発する必要がないため、ユーザーは直接使用できます。

CRD + Ingress Annotationsモード

CRD + Ingress Annotationsを使用してAPISIX Ingressの機能を拡張することもできます。例えば:

apiVersion: apisix.apache.org/v2
kind: ApisixPluginConfig
metadata:
  name: cors-plugin
spec:
  plugins:
    - name: cors
      enable: true
      config:
        allow_origins: http://foo.bar.org
        allow_methods: "GET,POST"
        max_age: 3600
        expose_headers: x-foo,x-baz
        allow_headers: x-from-ingress
        allow_credential: true
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: apisix
    k8s.apisix.apache.org/plugin-config-name: cors-plugin
  name: apisix-ingress
spec:
  rules:
    - host: apisix.apache.org
      http:
        paths:
          - path: /apisix-ingress
            pathType: Exact
            backend:
              service:
                name: apisix-gateway
                port:
                  number: 80

上記の設定を使用して、cors-pluginというプラグイン設定を独立して作成し、Ingressリソースのk8s.apisix.apache.org/plugin-config-name: cors-pluginを使用してそれを参照できます。実際の効果は最初の設定とほぼ同じで、対応するルートでCORSプラグインが有効になります。

このモードでは、プラグイン設定は独立したリソースと見なすことができ、複数のIngressリソースで共有することもできます。同様に、カスタム開発は必要ありません。

Ingress Annotationsモード

Ingressリソースのセマンティクスが限られているため、通常はannotationsを使用してリソースオブジェクトに追加情報を追加します。これはIngressの機能を拡張する最も一般的な方法です。例えば:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: apisix
    k8s.apisix.apache.org/enable-cors: "true"
    k8s.apisix.apache.org/cors-allow-origin: https://foo.com,https://bar.com
    k8s.apisix.apache.org/cors-allow-headers: x-foo-1,x-foo-2
    k8s.apisix.apache.org/cors-allow-methods: GET,POST,PUT
  name: apisix-ingress
spec:
  rules:
    - host: apisix.apache.org
      http:
        paths:
          - path: /apisix-ingress
            pathType: Exact
            backend:
              service:
                name: apisix-gateway
                port:
                  number: 80

上記の設定により、IngressリソースにCORS関連の追加情報が追加されます。APISIX Ingressコントローラーはこの情報を識別し、データ層の設定に変換してIngressリソースの機能を拡張します。

ただし、このモードでは、APISIX IngressコントローラーがすでにこれらのAnnotationを処理できることを確認する必要があります。そうでない場合、カスタム開発を行う必要があります。

カスタム開発を行う必要がある場合は、以下のドキュメントを参照してください:

結論

この記事では、主にIngressリソースに関連する仕様と、Ingressリソースの機能を拡張する方法について紹介しました。例えば、Ingress-NGINXでは通常、Annotationを使用して機能を拡張するしかありません。しかし、Apache APISIX Ingressでは、高度な要件やより多くのシナリオを満たすために3つの設定モードがあります。さらに、ほとんどの場合、ユーザーはカスタムプラグインに対してカスタム開発を行う必要はありません。

Tags: