前提
- 本記事執筆時の各ツールのバージョン
kubernetes v1.16.5
docker 19.03.12 - 書いている人は k8s をこれから使ってみようとしている人。
悩み
- StatefulSet を使う際に Headless Service が出てきて、機能は理解したが必要性がすぐにピンとこなかった。
結論
- StatefulSet のようにステートフルなもので、状態を持っている Pod に対して直接接続したい。(プライマリ / レプリカ構成の DB、とか)
- k8s の実装とは別の、外部のサービスディスカバリを利用したい。(gRPC だから envoy 挟みたい、とか)
- pod へのルーティングを自分でコントロールしたい。(均等に割り振りたいけど偏っちゃう、とか)
他にもあるとは思いますが、調べて出てきた具体的な用途はこんな感じでした。
Headless Service の機能
通常のService
はデフォルトでは単一のClusterIP
が振られます。これは文字通りクラスター内でのIPで、ここを窓口にして裏側の Pod へはいい感じにロードバランシングやプロキシしてくれます。
しかし.spec.clusterIP
の値をNone
にすることで、サービス自体のIPは設定されない Headless Service となります。
サービス名で引いた時、セレクターを設定しているかどうかで DNS の挙動がかわるのですが、結論で書いてあるような用途はセレクター有りで使うのかなと思います。
- セレクター有りの場合
裏側にある Pod の IP を全部返してきます。ちなみにこの場合にサービス名でつなごうとすると DNS ラウンドロビンとおんなじ感じでつながります。 - セレクター無しの場合
公式の説明では、以下です。- ExternalNameタイプのServiceに対するCNAMEレコード
- 他の全てのServiceタイプを含む、Service名を共有している全てのEndpointsレコード
ExternalName
を yaml に書くとExternalIP
として設定されるのは理解しましたが、後者についてはまだよくわかってません。
ということで
DNS やルーティングについての知識がないので理解ができていない部分もありますが、Headless Service の背景はわかりました。