Serviceとは
KubernetesのPodは、ephemeral(短命)という特徴を持っています。ざっくり言うと「よく再起動されることがある」、ということです。Podが再起動されたとき、k8sクラスタ内でPodに割り振られたIPアドレスも、その割当て範囲の中で変動してしまいます。
また、複数のPodそれぞれがIPアドレスを持つことになるので、愚直にIPアドレスを指定して通信する必要があります。
・・でも、面倒くさいですよね(/ω\)
ということは、複数のPod,NodeのIPアドレスをクライアントが意識せずに単一のエンドポイントで通信する方法が必要になります。
https://qiita.com/kouares/items/94a073baed9dffe86ea0
上記の事象に対する解決策としてPod,Nodeの存在を抽象化し、Podとの通信に単一のエンドポイントを提供するのがServiceの主な役割になります。
実際に、keycloakのhelmテンプレートとして定義されたServiceを覗いてみます。
{{- $service := .Values.keycloak.service -}}apiVersion: v1kind: Servicemetadata: name: {{ template "keycloak.fullname" . }}-http{{- with $service.annotations }} annotations:{{ toYaml . | indent 4 }}{{- end }} labels: app: {{ template "keycloak.name" . }} chart: {{ template "keycloak.chart" . }} release: "{{ .Release.Name }}" heritage: "{{ .Release.Service }}"{{- with $service.labels }}{{ toYaml . | indent 4 }}{{- end }}spec: type: {{ $service.type }} ports: - name: httpport: {{ $service.port }}targetPort: http {{- if and (eq "NodePort" $service.type) $service.nodePort }}nodePort: {{ $service.nodePort }} {{- end }}protocol: TCP selector: app: {{ template "keycloak.name" . }} release: "{{ .Release.Name }}"
3行目、kindには”Service”を定義し、spec.ports以下にポートの設定が記入されています。このService定義では、k8sのクラスタIP(クラスタ内からのみアクセス可能な仮想IP)がServiceに割り当てられ、spec.selector.appで指定したラベルがつけられたPodを通信先に、nodePortへ来た通信をPod(targetPort)のhttpポート(80番)へ転送します。