概要
サービスディスカバリを初めてみたのでそのメモ
サービスディスカバリとは
サービスディスカバリ(Service Discovery、サービス検出[1])はサービスのインスタンスがもつネットワーク上の位置を決定することである[2]。
とても簡単に言えばプログラムがサーバを発見する際にドメイン名なんかを識別名としてIPアドレスを特定していく技術のこと。(実態間参照とかいうらしい)。サーバの数も位置も動的にスケールインアウトするようなクラウドネイティブな世界ではIPアドレスリストなんかを持つことが不可能なためよく聞く言葉となっている。
ちなみにKubernetesでは、サービスディスカバリの機能をServiceが提供している。Aレコードでやるやり方以外にも
なんかがある。Aレコードでやるやり方はDNSラウンドロビン的な感じで1レコードの回答に複数値を入れると行ったやり方。これが一番わかりやすい。サンプルとしては以下のようにtargetのIPアドレスを問い合わせると3IPが帰ってきてプログラムからはこのIP3つを使ってアクセスしていくというやり方。
dig @127.0.0.1 target ;; ANSWER SECTION: target. 0 IN A 192.168.1.1 target. 0 IN A 192.168.1.2 target. 0 IN A 192.168.1.3
これで嬉しいのはprometheusみたいなpull型の監視ツール。例えば監視対象をtargetと指定しサービスディスカバリを使用するように設定しておけばサーバがスケールアウトしたとしてもprometheus的には何も変えずに自動的にインスタンスを検出してくれる仕組み。jenkinsやらCircleCIなんかでもデプロイ先をドメインにしておけばデプロイ対象が増えてもレコードの修正のみで済む。すごい便利。
Aレコードだけでいいじゃん!って思うがマイクロサービスの登場によってこれだけで済むかというと最近はそんなこともないらしい。大変。。
従来のAレコードで解決してくやり方で直面する問題。
1つ目がDNSラウンドロビンでも同じことが起きる死活監視問題。Aレコードでやるサービスディスカバリはその特性上仮にサーバが死んだとしても問い合わせを行うプログラムからは判別することが難しい。 (もちろん問い合わせ->処理の前にチェックを挟めば問題なし)
2つ目はAレコードでは得られる情報がIPのみ問題。1IP1サービスであれば何も問題は無いが8080と8081で別のサービスをあげたい場合に問題が起きる。
1つ目の解決策としては自動的に登録の削除ができるようなツールを使う。この辺はetcdとかがトレンドになるのだろうか。正直さっぱり分からない。死活監視あたりの資料はちゃんと読もうと思う。
本番環境でのKubernetesの監視 | Sysdig Monitor | Sysdigブログ | コンテナ・Kubernetes環境向けセキュリティ・モニタリング プラットフォーム
2つ目の解決策はSRVレコードを使う。
SRVレコードとは、DNSで定義されるそのドメインについての情報の種類の一つで、そのドメインで提供されているサービスの詳細な情報を記述するためのもの。
引用元: SRVレコードとは - IT用語辞典 e-Words
例えばプログラムがパラメータでDNS SRVレコードへ問い合わせることでIPアドレスとportを返してくれる仕組みを実装することで解決する。また以下のようなメリットがある。
- 負荷分散サービスの提供
- 冗長性の確保
- サービスポート番号の通知
またSRVのフォーマットを見ればわかるがweigthと行った値を持たせることでノードごとに通信の割合も定義が可能となっている。サービスエンドポイントを検出するのにとても便利。(マイクロサービス・アーキテクチャみたいなインフラの動的展開なんかをサポートするにはSRVが使われることが多いのかな)
_Service._Proto.Name TTL Class SRV Priority Weight Port Target
ちなみにNginxでSRVレコードを使えるかと思いきやその機能自体は有料版らしい。昨今のモダンなマイクロサービスでは当たり前に必須の機能なだけに残念な気もするがその辺はどのくらいの企業が使ってるんだろうか。やってることはupstreamを動的に検出する際にportまで検出可能となってる模様。Nginx -> k8sみたいな構成も取れるしで便利そう。
http - Can Nginx resolves upstream server name given as SRV DNS records? - Stack Overflow
(久々にplusのページ見たけど面白そうな機能がたくさんあることに気づいた)
まとめ
サービスディスカバリ = プログラムがサーバを検出する方法。って意味で良さそう。
色々調べていて思ったのがサービスディスカバリ自体は目新しい言葉でも機能でも無さそう。普段使ってるドメイン参照してのリクエストやら自宅で運用してるサーバたちのドメインはサービスディスカバリに通じていた。気がする。