Carpe Diem

備忘録

Kubernetesのheadless serviceを使って各PodのIPを知る

概要

gRPCを用いた負荷分散ではEnvoyを使ったL7のバランシングが最近の主流になっています。
ただEnvoyが各Podに振り分けるためにPodのIPを知る必要があります。
ECSはService Discoveryを持っていないので自前でたてるか、control planeを用意してそれをService Discoveryにする必要がありますが、Kubernetesはheadless serviceがあります。
headless serviceはServiceに対してDNSリクエストをすると、動いているPodのIPアドレス一覧を返してくれるのでこれをService Discoveryとして使うことが可能です。

今回はheadless serviceとして動かすところだけ検証しました。

環境

  • minikube v0.26.1
  • kubernetes 1.8.6

設定

Deployment

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: headless-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
        - image: "strm/helloworld-http"
          imagePullPolicy: Always
          name: hello-world-container
          ports:
            - containerPort: 80

applyして各Podが立ち上げます。

$ kubectl get pods -o wide
NAME                                  READY     STATUS    RESTARTS   AGE       IP           NODE
headless-deployment-b58876bbd-l2f8r   1/1       Running   0          26m       172.17.0.4   minikube
headless-deployment-b58876bbd-lgptv   1/1       Running   0          26m       172.17.0.5   minikube

Service

headless serviceの設定のため、clusterIP: Noneにします。

apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None
  ports:
  - name: headless
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: hello-world

ドキュメントにある通りheadless serviceではポートのマッピングが不要なので、 本来ポートの設定自体必要ありません。
ただ設定しないとエンドポイントの作成に失敗するバグもあるため、portを設定してapplyしてください。
本来不要なので、ここで設定するポートの値は適当で構いません。

github.com

一応2018/04/13に修正プルリクがマージされてます。

github.com

applyしてサービスも立ち上げます。

$ kubectl get services headless-svc -o wide
NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE       SELECTOR
headless-svc   ClusterIP   None         <none>        8080/TCP   27m       app=hello-world

確認

同じnamespaceにnslookupのあるbusyboxコンテナを立ち上げてみます。

$ kubectl run busybox --image=busybox --restart=Never --tty -i

コンソール内で先程立ち上げたserviceから引いてみると

/ # nslookup headless-svc
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      headless-svc
Address 1: 172.17.0.5 ip-172-17-0-5.ap-northeast-1.compute.internal
Address 2: 172.17.0.4 ip-172-17-0-4.ap-northeast-1.compute.internal

このようにIPが取得できます。

ソース