この記事ではKnativeがどのようにネットワークを構成しているか説明する。Knativeには多数のコンポーネントがあり、一見しただけではKnativeのコンポーネントがどうやって通信を行っているか理解しにくい。
しかし、あまりにも詳しい説明を書くと話がややこしくなり理解しにくくなるためこの説明ではなるべく簡単に概念を理解できるようにする。もっと詳しい実装の話を聞きたい場合はコメントやTwitterなどで気軽に連絡してほしい。
まずknativeにはScale to zeroという機能がある。これはPodsが使われていない場合は起動しているPodsの数を0個にするという機能だ。待機中で使われていないサービスのPods個数を0にすればKubernetesクラスタのリソースを無駄にすることなくサービスが維持できる。
しかしどうやってPodsが0の状態で通信しているのだろうか?
Activator
KnativeのコンポーネントのひとつにActivator
というものがある。このコンポーネントはPodsが起動していなければ起動するという機能を担っている。
Knativeの通信はまずContourやIstioなどのネットワークコンポーネントが受けとる。この記事ではContourを例にとって説明する。 ContourやIstioはどちらもEnvoyを基礎コンポーネントとして使用している。
Activatorも実際のPodsとしてKnativeが起動している。Activatorはいったんトラフィックを受け取り、対象サービスのDeploymentsのReplica数を変更する。Podsが正常に起動したら実際にPodsにトラフィックを送信する。
この時、常にトラフィックがActivatorを経由してしまうとActivatorがボトルネックになってしまう。 この問題を回避するためにActivatorはKubernetesのEndpointsを変更し、対象サービスのIPを登録する。
Endpoints
に該当サービスのIPが登録されたら、ContourやIstioがEndpointsの情報を読み取り、EnvoyのxDS というプロトコルを用いて対象サービスのIPを取得し、EnvoyのClusterを更新する。EnvoyのClusterとは簡単に言うと送信先(Destination)のことである。
EnvoyのClusterが更新されると、EnvoyはActivatorを経由せずに直接Podsにトラフィックを送信するようになり、Activatorがボトルネッックになることを避けることができる。
Appendix
EnvoyClusterの定義
Cluster: A cluster is a group of logically similar upstream hosts that Envoy connects to. Envoy discovers the members of a cluster via service discovery. It optionally determines the health of cluster members via active health checking. The cluster member that Envoy routes a request to is determined by the load balancing policy.
from: Terminology — envoy documentation