背景情報
従来の物理マシンおよび仮想マシンのデプロイメントでは、さまざまなサービス間の呼び出しは、
固定のIP + ポートを通じて行うことができます。クラウドネイティブ時代が到来し、エンタープライズ
ビジネスのデプロイメントは、クラウドネイティブなコンテナ化に傾倒する傾向が強くなっています。しかし、コンテナ化された
環境では、サービスインスタンスの起動と破棄が非常に頻繁に行われます。運用保守担当者による手動メンテナンス
は、作業負荷が大きくなるだけでなく、効果的でもありません。
したがって、サービスの状態を自動的に検出し、サービスアドレスが変更されたときに新しいアドレスを動的に
バインドできるメカニズムが必要です。そこで、サービスディスカバリーのメカニズムが登場しました。
サービスディスカバリー
サービスディスカバリーのメカニズムは、2つの部分に分割できます。
- サービスレジストリ:サービスのホストとポートの情報を格納します。
コンテナが平均を計算するサービスを提供する場合、サービス名としてaverage
を
一意の識別子として使用すると、サービスレジストリにはキーと値のペア(average:192.168.1.21
)の形式で
格納されます。
- サービスディスカバリー:サービス登録段階中に保存された情報を他のユーザーが発見できるようにします。
クライアントディスカバリーモードとサーバーディスカバリーモードに分けられます。
クライアントサービスディスカバリーモード
クライアントディスカバリーモードを使用する場合、クライアントはサービスレジストリのストレージ情報を照会して、使用可能な
サービスのアドレスを取得し、ロードバランシングアルゴリズムを通じて使用可能なサービス
インスタンスを選択し、リクエストをサービスに送信します。
利点:シンプルなアーキテクチャ、柔軟な拡張、およびロードバランシング機能の実装が容易。
欠点:クライアントが重い、強い結合、一定の開発コストが発生する。

クライアントディスカバリーモード。
クライアントディスカバリーモードの実装ロジックは次のとおりです。
- 新しいサービスが開始されると、登録センターに積極的に登録され、
サービス登録センターは新しいサービスのサービス名とアドレスを保存します。 - クライアントがこのサービスを必要とする場合、サービス名を使用してサービス
レジストリに対してクエリを開始します。 - サービスレジストリは使用可能なアドレスを返し、クライアントは特定
のアルゴリズムに従って呼び出しを開始するアドレスを1つ選択します。
このプロセスでは、サービス登録に加えて、サービスディスカバリーの作業は基本的に
クライアントによって独立して完了し、レジストリとサーバーのアドレスも
クライアントに完全に可視化されます。
サーバーサービスディスカバリーモード
クライアントはロードバランサーにリクエストを送信し、ロードバランサーはクライアントの
リクエストに従ってサービスレジストリを照会し、使用可能なサービスを見つけ、リクエストを
サービスに転送します。クライアントサービスディスカバリーモードと同様に、サービスは
レジストリに登録および登録解除する必要があります。
利点:サービスのディスカバリーロジックはクライアントに対して透過的です。
欠点:ロードバランサーの追加のデプロイメントとメンテナンスが必要です。

サーバーディスカバリーモード。
サーバーディスカバリーモードの実装ロジックは次のとおりです。
- 新しいサービスが開始されると、レジストリに積極的に登録され、サービス
レジストリは新しいサービスのサービス名とアドレスを保存します。 - クライアントがサービスを必要とする場合、サービス名を使用してロード
バランサーに対してクエリを開始します。 - クライアントによって要求されたサービス名に従って、ロードバランサーはクライアントを
プロキシし、サービスレジストリに対してリクエストを開始します。 - ロードバランサーが返されたアドレスを取得した後、特定のアドレスを1つ選択します
のアルゴリズムに従って呼び出しを開始します。
CoreDNSを使用する利点
一般的なサービスディスカバリーフレームワーク(ZookeeperとConsul)と比較して、CoreDNSがサービスディスカバリーを
実装する利点は何ですか?
サービスディスカバリーの原則は、コンピューターネットワークにおける重要な
インフラストラクチャであるDNSドメインネームシステムと似ています。DNSドメインネームシステムは、
あまり変更されないドメイン名を頻繁に変更されるサーバーIPアドレスにバインドしますが、
サービスディスカバリーメカニズムはめったに変更されないドメイン名を使用します。サービス名がサービスアドレスにバインドされています。このようにして、
DNSを使用してサービスレジストリに似た機能を実現でき、DNSに保存されているドメイン名を
サービス名に変換するだけで済みます。多くのコンピューターにはDNS機能が組み込まれている
ため、元のDNSシステムの設定を変更するだけで済み、
多くの追加作業を行う必要はありません。
CoreDNSはGo
で記述されたオープンソースのDNSサーバーであり、柔軟性と拡張性があるため、マルチコンテナ環境
でのDNSサービスおよびサービスディスカバリーによく使用されます。
CoreDNSはHTTP/2 WebサーバーであるCaddyの上に構築されており、プラグインチェーン
アーキテクチャを実装し、多くのDNS関連ロジックをレイヤーごとのプラグインに抽象化します。これらはより
柔軟で拡張が容易であり、ユーザーが選択したプラグインは最終的な実行可能ファイル
にコンパイルされます。また、実行効率も非常に高くなっています。CoreDNSはCNCF(Cloud Native Computing Foundation)
に参加した最初のクラウドネイティブオープンソースプロジェクトであり、卒業も完了しており、Kubernetesのデフォルト
DNSサービスでもあります。
ミドルウェアとして、Apache APISIXはさまざまなサービスディスカバリー機能を統合しています。
以下では、Apache APISIXでCoreDNSを構成する方法を示します。
原則アーキテクチャ
- クライアントはAPISIXにリクエストを開始してサービスを呼び出します。
- APISIXは、設定されたルートに従ってアップストリームサービスノードにアクセスします(特定の設定
は以下を参照)。APISIXでは、DNSを介して取得するようにアップストリーム情報を設定できます。DNSサーバーのIP
アドレスが正しく設定されていれば、APISIXは自動的にこのアドレスにリクエストを開始し、
DNS内の対応するサービスのアドレスを取得します。 - CoreDNSは、要求されたサービス名に基づいて、使用可能なアドレスのリストを返します。
- APISIXは、使用可能なアドレスの1つと構成されたアルゴリズムを選択して呼び出しを開始します。
全体構造は次のとおりです。

原則アーキテクチャ。
使用方法
前提条件
この記事は、次の環境に基づいています。
-
OS:Centos 7.9。
-
Apache APISIX 2.12.1、参照:Apache APISIXの構築方法。
-
CoreDNS 1.9.0、参照:CoreDNSインストールガイド。
-
Node.js、参照:Node.jsインストール。
手順
- Node.jsの
Koa
フレームワークを使用して、ポート3005
で簡単なテストサービスを開始します。
このサービスにアクセスすると、文字列Hello World
が返されます。後でCoreDNSを介してこの
サービスのアドレスを取得します。
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3005);
- CoreDNSを構成します。
CoreDNSはデフォルトでポート53
でリッスンし、同じディレクトリ内のCorefile
構成ファイルを
読み取ります。初期状態では、同じディレクトリにCorefile
ファイルがないため、
構成を作成して完了する必要があります。
Corefile
は主にプラグインを構成することで機能を実装するため、3つのプラグインを構成する必要があります。
hosts
:このパラメーターを使用して、サービス名とIPアドレスをバインドできます。fallthrough
は、現在のプラグインが正常なデータを返せない場合、リクエストを転送して
処理(存在する場合)できることを意味します。forward
:リクエストを指定されたアドレス(通常は権威DNS
サーバーアドレス)にプロキシすることを指示します。log
:デバッグのためにログ情報をコンソールインターフェイスに出力するためのパラメーターを構成しないでください。
.:1053 { # Listen on port 1053
hosts {
10.10.10.10 hello
# Bind the service name "coredns" to the IP address
fallthrough
}
forward . 114.114.114.114:53
log
}
- Apache APISIXを構成します。
conf/config.yaml
ファイルに関連する構成を追加し、Apache APISIXをリロードします。
# config.yml
# ...other config
discovery:
dns:
servers:
- "127.0.0.1:1053" # Use the real address of the DNS server,
# here is the 1053 port of the local machine.
- Apache APISIXでルーティング情報を構成します。
次に、Admin API
をリクエストして、関連するルーティング情報を構成します。
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/core/*",
"upstream": {
"service_name": "hello:3005",
# Name the service as coredns, consistent with
# the configuration of the hosts plugin in CoreDNS
"type": "roundrobin",
"discovery_type": "dns" # Set service discovery type to DNS
}
}'
- 検証します。
a. ローカルマシンで認証します。
curl 127.0.0.1:9080/core/hello -i
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 11
Connection: keep-alive
Date: Wed, 16 Feb 2022 08:44:08 GMT
Server: APISIX/2.12.1
Hello World
b. 他のホストで検証します。
curl 10.10.10.10:9080/core/hello -i
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 11
Connection: keep-alive
Date: Wed, 16 Feb 2022 08:43:32 GMT
Server: APISIX/2.12.0
Hello World
上記の結果からわかるように、サービスは正常に実行されています。
- シミュレートされたコンテナのIPアドレスは、コンテナがさまざまな理由で
サービスを提供できないために変更されます。
別のサーバーでも同じサービスをセットアップする必要があります。これもポート3005
で実行されますが、
IPアドレスが変更され、返される文字列がHello, Apache APISIX
に変更されます。
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello, Apache APISIX';
});
app.listen(3005);
Corefile
構成を変更し、Core DNSを再起動します。他の構成は
変更しないでください。構成例は次のとおりです。
.:1053 { # Listen on port 1053
hosts {
10.10.10.10 hello
# Bind the service name "coredns" to the IP address
fallthrough
}
forward . 114.114.114.114:53
log
}
DNSにはキャッシュメカニズムがあります。
dig
コマンドを使用して新しい
ドメイン名の解決をリクエストすると、返されたDNS record
に番号フィールドが表示されます。これは、TTL
フィールドであり、通常は3600
、つまり1時間です。TTL
期間内にドメイン名に送信されたリクエストは、
DNSサーバーにアドレスを解決することを要求しなくなり、
ローカルキャッシュ内のドメイン名に対応するアドレスを直接取得します。
検証により、リクエストが新しいアドレスにリダイレクトされていることがわかります。以下のように
検証します。
curl 127.0.0.1:9080/core/hello -i
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 11
Connection: keep-alive
Date: Wed, 16 Feb 2022 08:44:08 GMT
Server: APISIX/2.12.0
Hello, Apache APISIX
概要
この記事では、主にサービスディスカバリーの種類と、Apache
APISIXでCoreDNSを使用する方法を紹介します。ビジネスニーズに応じて、
Apache APISIXとCoreDNSを使用できます。