広告

kubernetes – Headless Service

infrastructure as code

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が同じであること

それでは、イメージ図です。
Headless
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の名前解決はできません。

ここまで読んでいただいて、お疲れ様でした。

コメント

タイトルとURLをコピーしました