複雑化しやすいマイクロサービス間の連携の解決について気になっているところでlinkerdについて知ったので少し調べてみました。
ただ、思ったより日本語の情報は無いですね。。。
大規模なサービス連携でなければ、Consulなどでのサービスディスカバリ単体があれば十分であることが多くて、導入までに至らないからでしょうか。
もとのドキュメントもしっかりしており、GitHub等を見る限りでも必要な機能も揃っている印象で日本語情報なしでもある程度は簡単にできるのでは?とは感じました。
linkerdやConsulなどのサービスディスカバリやルーティングの支援ツールが複数出てきており、これらを導入するほうが早いか、大規模化・複雑化しないことを前提に取り入れずに進めるかは判断の別れるところになりそうです。
linkerdとは
linkerdは分散型のアプリケーション間の連携を支援するオープンソースのツールです。
2017年1月にCloud Native Computing Foundation傘下になったことで注目を浴びているようです。
linkerdはおもにルーティング機能を提供し、マイクロサービス化されることにより複雑化するルーティングを抽象化されたレイヤーを提供することで解決します。
linkerdの機能
linkerdはアプリケーションからの抽象化されたリクエストを受け付けることができます。
この時点で、アプリケーションはリクエスト先となるアプリケーションの実際の場所を知る必要がありません。
また、linkerdはリクエストを受けてリクエスト先となるアプリケーションをサービスディスカバリを通じてその場所を解決し、ロードバランシングを受け渡しをしてくれます。
これにより、分散型のシステムにおける複雑化しやすい通信部分にレイヤを設けることができ、シンプルに保つことができるようになります。
引用: https://linkerd.io/overview/what-is-linkerd/
リクエストをどのようにサービス名に変換するかを決定するプラグイン可能なモジュールや、サービスディスカバリとしてConsulやZookeeper、Kubernetesなどを利用することもでき、様々な方法でシステムに合わせた形での利用をすることができます。
linkerdのルーティングの概要
linkerdは、identification、binding、resolution、load balancingの4ステップでリクエストを変換し、最終的なホストを決定して渡します。
引用: https://linkerd.io/advanced/routing/
Identification
linkerdはリクエストを受け取ると、まずIdentification(識別)を行います。
Identificationはリクエストに対してサービス名となる「名前」を割り当てます。
サービス名にはクラスタ、ゾーン、環境、ホストのような情報は含んでいません。アプリケーションがこれらの情報をきにする必要はないためです。
また、このIdentificationによるリクエストから名前への変換はIdentifierと呼ばれるプラグイン可能なモジュールによって行われます。
Identifierには標準でHTTPリクエストをはじめ、多くのものが用意されています。
Linkerd Configuration Reference
また、TCP通信に対するモジュールも公開されています。
例えば GET http://example/hello
のようなHTTPリクエストは Identifier io.l5d.header.token
によってホストヘッダーを元に、 /svc/example
というサービス名が割り当てられます。
binding
Identificationによってサービス名に変換されたリクエストは、次にbindingによってクラスタ、ゾーン、環境などの詳細を含むクライアント名へと変換されます。
このとき、bindingではdtabs(delegation tablesの略)を利用して変換が行われます。
dtabsはサービス名からクライアント名へのルーティングルールを持ちます。
例えば、次のようなdtabsがあった場合
/env => /#/io.l5d.serversets/discovery /svc => /env/prod
先ほどの例にあった、 /svc/example
は
/svc/exmaple /env/prod/example /#io.l5d.serversets/discovery/prod/example
のようにクライアント名 /#io.l5d.serversets/discovery/prod/example
に変換されます。
ちなみにクライアント名は /#
か /$
で始まります。
resolution
resolutionでは、クライアント名を物理的なエンドポイント(IPアドレス + ポート)に解決します。
このタイミングでバックエンドのサービスディスカバリを用いて、このエンドポイントの解決を行います。
load balancing
linkerdでは、接続レイヤーではなくリクエストのレイヤーで、要求に対する遅延情報を元にロードバランシングアルゴリズムを用いて、低速なノードへの負荷を軽減させています。
linkerdを始めるには
linkerdを始める場合、まずはドキュメントを読むと良さそうです。
https://linkerd.io/documentation/linkerd.io
またGitHubにexampleのリポジトリがあるため、こちらを実行してみるとどのように動くのか確認することができます。
現実のシステムで利用するには、バックエンドのサービスディスカバリの選定なども重要になるだろうと思います。
linkerdのような新しく抽象的なレイヤを導入するようなツールも利用することで複雑化・大規模化するアプリケーションを上手に開発・運用できるようにしていきたいですね。