API GatewayとConsulを統合する方法

Fei Han

February 25, 2022

Ecosystem

背景情報

Consulはサービスメッシュソリューションです。その中核の一つであるConsul KVは、分散型のキーバリューデータベースで、主に設定パラメータやメタデータを保存するために使用されますが、インデックス付きオブジェクトの保存も可能です。

マイクロサービスアーキテクチャモデルでは、アップストリームサービスがキャパシティ拡張やハードウェア障害などによって変更される場合、手動で設定を記述してアップストリームサービスの情報を維持する方法では、保守コストが急激に増加する可能性があります。これに対応するため、Apache APISIXはサービスディスカバリレジストリを提供し、最新のサービスインスタンス情報を動的に取得して、ユーザーの保守コストを削減します。

現在、Apache APISIXはコミュニティによって提供されたconsul_kvモジュールを使用して、Consul KVベースのサービスディスカバリレジストリをサポートしています。

動作原理

Apache APISIXは、Consul KVの分散型キーバリューストレージ機能を活用して、サービスのプロバイダーとコンシューマーを分離し、サービスディスカバリレジストリの2つのコア機能を実装します。

  1. サービス登録: サービスプロバイダーがレジストリにサービスを登録します。
  2. サービスディスカバリ: サービスコンシューマーがレジストリを通じてサービスプロバイダーのルーティング情報を見つけます。

この基盤に基づいて、Apache APISIXは既存のマイクロサービスアーキテクチャに柔軟に対応し、ユーザーのニーズにより適応できるようになります。

consul architectures

Apache APISIXでConsulを有効にする方法

この記事のテスト環境は、Dockerを使用してdocker-composeで構築されています。

  1. Apache APISIXをダウンロードします。

    # apisix-dockerのGitリポジトリをクローン
    git clone https://github.com/apache/apisix-docker.git
    
  2. Consulフォルダと設定ファイルを作成します。

    # Consulフォルダを作成
    mkdir -p ~/docker-things/consul/ && cd $_
    # 設定ファイルを作成
    touch docker-compose.yml server1.json
    
  3. docker-compose.ymlファイルを編集します。

    version: '3.8'
    
    services:
    consul-server1:
    image: consul:1.9.3
    container_name: consul-server1
    restart: always
    volumes:
      - ./server1.json:/consul/config/server1.json:ro
    networks:
      - apisix
    ports:
      - '8500:8500'
    command: 'agent -bootstrap-expect=1'
    
    networks:
    apisix:
    external: true
    name: example_apisix
    
  4. server1.jsonファイルを編集します。

    {
    node_name: consul-server1,
    server: true,
    addresses: {
    http: 0.0.0.0
    }
    }
    
  5. Apache APISIXの設定ファイルapisix_conf/config.yamlにConsul関連の設定情報を追加します。

    # config.yml
    # ...その他の設定
    discovery:
    consul_kv:
    servers:
      - http://consul-server1:8500
    prefix: upstreams
    
  6. Apache APISIXとConsulを起動します。

    # example、consulフォルダに移動し、APISIXとConsulを起動
    docker-compose up -d
    
  7. テストサービスをConsulに登録します。exampleには2つのWebサービスが含まれており、直接テストに使用できます。

    # exampleのdocker-compose.ymlを確認
    # 2つのWebサービスが確認できます
    $ cat docker-compose.yml | grep web
    # 出力
    web1:
    - ./upstream/web1.conf:/etc/nginx/nginx.conf
    web2:
    - ./upstream/web2.conf:/etc/nginx/nginx.conf
    
  8. これらのWebサービスのIPアドレスを確認します。

    $ sudo docker inspect -f='{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(sudo docker ps -aq) | grep web
    # 出力
    /example-web1-1 - 172.26.0.7
    /example-web2-1 - 172.26.0.2
    
  9. ターミナルでConsulのHTTP APIにリクエストを送信し、テストサービスを登録します。

    # 対応するIPで登録
    curl \
    -X PUT \
    -d ' {weight: 1, max_fails: 2, fail_timeout: 1}' \
    http://127.0.0.1:8500/v1/kv/upstreams/webpages/172.26.0.7:80
    
    curl \
    -X PUT \
    -d ' {weight: 1, max_fails: 2, fail_timeout: 1}' \
    http://127.0.0.1:8500/v1/kv/upstreams/webpages/172.26.0.2:80
    

    /v1/kv/の後のパスは{Prefix}/{Service Name}/{IP}:{Port}の形式に従います。

    {Prefix}はAPISIXでConsulを設定する際に記述したプレフィックスで、{Service Name}{IP}:{Port}はユーザーがアップストリームサービスに応じて決定する必要があります。

    データの形式は{"weight": , "max_fails": , "fail_timeout": }です。

  10. テストサービスが正常に登録されたか確認します。

    curl http://127.0.0.1:8500/v1/kv/upstreams/webpages?keys
    

    以下の返信メッセージは登録が成功したことを示します。

    [upstreams/webpages/172.26.0.2:80,upstreams/webpages/172.26.0.7:80]%
    

ルートを作成し、Consulを有効にする

Apache APISIXが提供するAdmin APIを使用して、Consulをルートに追加します。

X-API-KEYupstream.service_nameは、追加する前に決定する必要があります。

  • X-API-KEY: Admin APIのアクセストークンで、この例ではデフォルトのedd1c9f034335f136f87ad84b625c8f1を使用します。
  • upstream.service_name: アップストリームサービスの名前で、ルートにバインドされるレジストリ内のサービスを指定します。Consulを使用する場合、テストサービスの登録に使用したURLに設定し、末尾の{IP}:{Port}部分を削除する必要があります。また、Apache APISIXが提供するMemory Dump APIを使用してサービスのURLを取得し、アップストリームサービスが正常に発見されているか確認することもできます。
$ curl http://127.0.0.1:9092/v1/discovery/consul_kv/dump | jq
# 出力
{
  "services": {
    # このキーが必要なURL
    "http://consul-server1:8500/v1/kv/upstreams/webpages/": [
      {
        "port": 80,
        "host": "172.26.0.7",
        "weight": 1
      },
      {
        "port": 80,
        "host": "172.26.0.2",
        "weight": 1
      }
    ]
  },
  "config": {
    # ...設定
  }
}

ルートを追加

ここでは、URL /consul/*のリクエストをhttp://consul-server1:8500/v1/kv/upstreams/webpages/にルーティングします。また、discovery_typeconsul_kvに設定して、対応するモジュールを起動する必要があります。

curl http://127.0.0.1:9080/apisix/admin/routes -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X POST -d '
{
    "uri": "/consul/*",
    "upstream": {
        "service_name": "http://consul-server1:8500/v1/kv/upstreams/webpages/",
        "type": "roundrobin",
        "discovery_type": "consul_kv"
    }
}'

テストと結果の検証

リクエスト結果は、Apache APISIXの新しいルートがConsulを通じて正しいサービスアドレスを見つけ、ロードバランシングポリシーに基づいて両方のノードにリクエストを送信できることを示しています。

# 最初のリクエスト
curl -s http://127.0.0.1:9080/consul/
# 出力
hello web1%

# 2番目のリクエスト
curl -s http://127.0.0.1:9080/consul/
# 出力
hello web2%

# 注: 両方のリクエストがweb1またはweb2と同じ結果を返すこともあります。
#      これはロードバランシングの性質によるもので、より多くのリクエストを試すことができます。

まとめ

この記事の前半では、Apache APISIXがConsulと連携してConsul KVベースのサービスディスカバリレジストリを実装し、サービス情報の管理と保守の問題を解決する方法について説明しました。後半では、DockerでConsulとApache APISIXを使用する方法に焦点を当てました。もちろん、実際のシナリオでのアプリケーションは、ビジネスシナリオと既存のシステムアーキテクチャに応じて分析する必要があります。

Apache APISIXでのConsulレジストリの使用に関する詳細な説明は、公式ドキュメントを参照してください。

Apache APISIXは現在、追加のプラグインをサポートして追加のサービスの統合をサポートする作業を行っています。興味がある場合は、GitHub Discussionでディスカッションを開始するか、メーリングリストを通じてコミュニケーションを取ることができます。

Tags: