目標
- KubernetesにおけるServiceについて理解する
- ラベルとLabelSelectorオブジェクトがServiceにどう関係しているかを理解する
- Serviceを使って、Kubernetesクラスタの外にアプリケーションを公開する
Kubernetes Serviceの概要
Kubernetes Podの寿命は永続的ではありません。実際、Podにはライフサイクルがあります。ワーカーのNodeが停止すると、そのNodeで実行されているPodも失われます。そうなると、ReplicaSetは、新しいPodを作成してアプリケーションを実行し続けるために、クラスタを動的に目的の状態に戻すことができます。別の例として、3つのレプリカを持つ画像処理バックエンドを考えます。それらのレプリカは交換可能です。フロントエンドシステムはバックエンドのレプリカを気にしたり、Podが失われて再作成されたとしても配慮すべきではありません。ただし、Kubernetesクラスタ内の各Podは、同じNode上のPodであっても一意のIPアドレスを持っているため、アプリケーションが機能し続けるように、Pod間の変更を自動的に調整する方法が必要です。
KubernetesのServiceは、Podの論理セットと、それらにアクセスするためのポリシーを定義する抽象概念です。Serviceによって、依存Pod間の疎結合が可能になります。Serviceは、すべてのKubernetesオブジェクトのように、YAML(推奨)またはJSONを使って定義されます。Serviceが対象とするPodのセットは通常、LabelSelectorによって決定されます(なぜ仕様にセレクタ
を含めずにServiceが必要になるのかについては下記を参照してください)。
各Podには固有のIPアドレスがありますが、それらのIPは、Serviceなしではクラスタの外部に公開されません。Serviceによって、アプリケーションはトラフィックを受信できるようになります。ServiceSpecでtype
を指定することで、Serviceをさまざまな方法で公開することができます。
- ClusterIP (既定値) - クラスタ内の内部IPでServiceを公開します。この型では、Serviceはクラスタ内からのみ到達可能になります。
- NodePort - NATを使用して、クラスタ内の選択された各Nodeの同じポートにServiceを公開します。
<NodeIP>:<NodePort>
を使用してクラスタの外部からServiceにアクセスできるようにします。これはClusterIPのスーパーセットです。 - LoadBalancer - 現在のクラウドに外部ロードバランサを作成し(サポートされている場合)、Serciceに固定の外部IPを割り当てます。これはNodePortのスーパーセットです。
- ExternalName - 仕様の
externalName
で指定した名前のCNAMEレコードを返すことによって、任意の名前を使ってServiceを公開します。プロキシは使用されません。このタイプはv1.7以上のkube-dns
を必要とします。
さまざまな種類のServiceに関する詳細情報はUsing Source IP tutorialにあります。アプリケーションとServiceの接続も参照してください。
加えて、Serviceには、仕様にselector
を定義しないというユースケースがいくつかあります。selector
を指定せずに作成したServiceについて、対応するEndpointsオブジェクトは作成されません。これによって、ユーザーは手動でServiceを特定のエンドポイントにマッピングできます。セレクタがない可能性があるもう1つの可能性は、type:ExternalName
を厳密に使用していることです。
まとめ
- Podを外部トラフィックに公開する
- 複数のPod間でトラフィックを負荷分散する
- ラベルを使う
Kubernetes Serviceは、Podの論理セットを定義し、それらのPodに対する外部トラフィックの公開、負荷分散、およびサービス検出を可能にする抽象化層です。
Serviceとラベル
Serviceは、一連のPodにトラフィックをルーティングします。Serviceは、アプリケーションに影響を与えることなく、KubernetesでPodが死んだり複製したりすることを可能にする抽象概念です。(アプリケーションのフロントエンドおよびバックエンドコンポーネントなどの)依存Pod間の検出とルーティングは、Kubernetes Serviceによって処理されます。
Serviceは、ラベルとセレクタを使用して一連のPodを照合します。これは、Kubernetes内のオブジェクトに対する論理操作を可能にするグループ化のプリミティブです。ラベルはオブジェクトに付けられたkey/valueのペアであり、さまざまな方法で使用できます。
- 開発、テスト、および本番用のオブジェクトを指定する
- バージョンタグを埋め込む
- タグを使用してオブジェクトを分類する
kubectlの
--expose
を使用して、Deploymentの作成と同時にServiceを作成できます。
ラベルは、作成時またはそれ以降にオブジェクトにアタッチでき、いつでも変更可能です。Serviceを使用してアプリケーションを公開し、いくつかのラベルを適用してみましょう。