概要
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してください。
本来不要なので、ここで設定するポートの値は適当で構いません。
一応2018/04/13に修正プルリクがマージされてます。
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が取得できます。