普段何となく使っているレベルからもう 1 ミリだけ詳しくなる Kubernetes の Service とは何ぞや

この記事はFixer Advent Calendar 7 日目の記事です。

また、なむゆの個人ブログにもマルチポストする予定です。

はじめに

Kubernetes にアプリケーションを配置するときに使用するリソースの一つに Service があります。
仕事で普段既に構成されたマニフェストを利用していると、その役割としてやっていることを忘れがちになっていたので思い出しがてら記事にしてみます。

サービスディスカバリ とは

Kubernetes の Service について説明する前に Kubernetes 上に展開したアプリケーションに対してどうやってアドレスを特定して接続を行うかを説明する必要があります。
Kubernetes 上に展開されるアプリケーションは Pod 内のコンテナとして存在しています。
そして、その Pod はそれぞれ Kubernetes クラスターのネットワーク内で指定された個別のプライベート IP アドレスを持ちます。
なので、最低限そのプライベートアドレスを知っていれば、Kubernetes クラスター内部からはアクセスが可能です。
しかし、その IP アドレスは Pod が再移動するたびに毎回変更されてしまうので、もしプライベート IP アドレスを用いて Kubernetes クラスター内で通信しようとすると接続先の Pod 再起動の度に接続先 IP アドレスの設定が必要になるので現実的ではありません。
そこで、DNS のような仕組みを作って同じ名前のアドレスにアクセスすると自動で目的の Pod にアクセスでき、しかも Pod 再起動の度に自動でアクセス先のプライベート IP アドレスを再設定してくれる仕組みがあればええやんという発想が出てきます。
この発想を「サービスディスカバリ」といいます。
直訳するとサービスを発見すること、もうちょっと意訳すると接続先のアプリケーションのアドレスを発見することになります。
そしてそれを実現するための仕組みの一つが、CoreDNS です。
これは、Kubernetes の中に仕込まれている仕組みの一つで、Kubernetes でのサービスディスカバリのデフォルトの実装となっています。
Kubernetes をインストールして起動すると、自動的に CoreDNS の pod がいくつか立ち上がり、後述の Service で規定した条件に従ってアドレスと Pod の IP アドレスの結び付けを行ってくれます。

Service ってなんぞや

そんな CoreDNS に対して、「このアドレスにやってきた通信はこっちの IP に流して!」と指示する役割を持つのが Service になります。
Service を作成するときには、そのリソースの名前と、通信の流し先の Pod の選択条件を記述します。
リソースの名前とネームスペース名から通信を受け付けるアドレスが決まります。
通信の流し先の Pod の選択条件は Service リソースの Selector として記述します。
Service で規定したアドレスにやってきた通信は、Selector の条件を満たす Pod からランダムに一つ選んで流されます。
そうです、Selector では通信の流し先の Pod の選択条件を規定するので、その条件に合う Pod は一つとは限りません。
複数の Pod が条件に当てはまればその条件に当てはまる Pod にほぼ平等に通信を分配するので、同じ Pod を複数用意しておけばその間でロードバランシングのようなこともできます。
その他、標準的な方法ではないのですが、Service では Kubernetes クラスター内からリクエストだけでなくクラスター外部からやってきたリクエストを Node のポート番号を指定して受け入れることもできます。
とはいえ、この方法だけだとインターネットからアクセスする際のアドレスは kubernetes クラスターに属するそれぞれの node のパブリック IP アドレス+ポート番号になってしまうので、アプリケーションを外部公開する際には素直に「Ingress」という別の仕組みを使うのが吉です。

おわりに

今回は思い出しがてらに Kubernetes の基本的な構成要素の Service についてその役割ややっていることについて説明しました。
知っている人にとっては当たり前のこと鳴きもしますが、復習がてらドキュメントを読み直してみるのも役に立つかと思います。

参考