Service概要
- Service
- ClusterIP:k8s内部ロードバランサー
- ExternalIP(ClusterIPに属する):指定のNodeのIPを使って、外部と通信可能なClusterIP
- NodePort:任意NodeのIPを使って、外部からk8s内部への通信を可能にするリソース
- LoadBalancer:外部ロードバランサー + NodePort + ClusterIP
- Headless(None)(ClusterIPに属する):主にStatefulSetのためのClusterIP
- ExternalName:k8sのCNAME変換用リソース
- None-Selector(ClusterIPに属する):Endpointsをカスタマイズ可能なClusterIP
Headless Service(None)
manifestのリソース指定:
kind: Service
spec.type: ClusterIP
spec.clusterIP: None
HeadlessもClusterIPの一種です。単刀直入でいいますと、このServiceはロードバランシングのためのものではありません。
あくまで、ディスカバリー用のリソースです。
仕組みとしては、Headlessの条件にあったPodのIPをアクセスごとに、一個ずつ帰ってきます。
要するに、DNS RoundRobin(DNS RR)* の形式で実現しています。
※DNS RoundRobin(DNS RR):DNSに、同じレコードで複数のIPを登録し、アクセスごとに、違うIPへ転送する方式です。
k8sでは、ClusterIPの名前を解決できますが、Podの名前解決(DNS)は基本出来ないです。
ただ、一個例外があります。それはStatefulSetとHeadlessを併用する場合です。
なぜこれが必要かというと、StatefulSetは固定な名前を持っていて、名前解決できた方がいいからです。
StatefulSetとHeadless関連して使う条件は一つのみ:
- Headlessの
metadata.name
とStatefulSetのspec.serviceName
が同じであること
それでは、イメージ図です。
k8s内部で、StatefulSetのPodに対して、直接Pod名でアクセス(名前解決)が可能になります。
特徴:
- DNS RoundRobin(DNS RR) の形式のロードバランシング
- DNS RoundRobin(DNS RR)は負荷分散に向きませんので、メイン用途ではない。
- StatefulSetとHeadlessを併用すると、StatefulSetのPodの名前解決が可能になる
- FQDN:
<Pod名>.<Service名>.<Namespace名>.svc.cluster.local
- その他はClusterIPと同じ
StatefulSetとHeadlessの併用 manifest例
# まずは、Headless作成
apiVersion: v1
kind: Service
metadata:
name: nginx # この設置値はStatefulSetのspec.ServiceNameと同じにする必要がある
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None # これを指定することで、Headlessになれます。
selector:
app: nginx
---
# 次は、StatefulSet作成
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx # .spec.template.metadata.labelsにマッチする必要がある
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx # .spec.selector.matchLabelsにマッチする必要がある
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "my-storage-class"
resources:
requests:
storage: 1Gi
最後に
Headless ServiceはStatefulSetと併用することがほとんどです。
この機能を使用することによって、StatefulSet配下のPodも名前解決ができるようになります。
※k8sでは、基本Podの名前解決はできません。
ここまで読んでいただいて、お疲れ様でした。
コメント