KubernetesのHeadless Service を理解したい

# Headless Service
- 対象となる個々のPodのIPアドレスが直接帰ってくるService
- DNSラウンドロビンのイメージ
- ロードバランシングするためのIPアドレスは不要
- StatefulSetがHeadlessServiceを利用している場合、Pod名でIPアドレスを引くことができる（Kubernetesの設計的に、StatefulSet内の各Podを直接指定するのはナンセンス）

# セットアップ

## HeadlessServiceのデプロイ

```sample-headless.yaml
apiVersion: v1
kind: Service
metadata:
  name: sample-headless
spec:
  type: ClusterIP
  clusterIP: None
  ports:
  - name: "http-port"
    protocol: "TCP"
    port: 80
    targetPort: 80
  selector:
    app: sample-app
```

## デプロイ

```
kubectl apply -f sample-headless.yaml
```

## 状態確認

```
kubectl get service sample-headless
```

出力結果

```
NAME              TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
sample-headless   ClusterIP   None         <none>        80/TCP    8m9s
```

## StatefullSetのデプロイ
- ReplicaSetの亜種
- PersistentVolumeを使っている場合、Pod再起動時には同じディスクを利用して再作成される
- Pod名が変わらない

```sample-statefulset-headless.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sample-statefulset-headless
spec:
  serviceName: sample-headless
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.12
```

## デプロイ

```
kubectl apply -f sample-statefulset-headless.yaml
```

## 状態確認

```
kubectl get statefulsets sample-statefulset-headless
```

出力結果

```
NAME                          READY   AGE
sample-statefulset-headless   3/3     7m11s
```

# 動作確認

## 別PodよりHeadlessServiceを名前解決できるかを確認

```
kubectl run --image=centos:6 --restart=Never --rm -i testpod -- dig sample-headless.default.svc.cluster.local
```

出力結果
3のIPアドレスが返されていることがわかる

```
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.68.rc1.el6_10.1 <<>> sample-headless.default.svc.cluster.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33653
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;sample-headless.default.svc.cluster.local. IN A

;; ANSWER SECTION:
sample-headless.default.svc.cluster.local. 5 IN	A 10.42.0.11
sample-headless.default.svc.cluster.local. 5 IN	A 10.42.2.8
sample-headless.default.svc.cluster.local. 5 IN	A 10.42.1.8

;; Query time: 1 msec
;; SERVER: 10.43.0.10#53(10.43.0.10)
;; WHEN: Sun Oct  6 05:19:56 2019
;; MSG SIZE  rcvd: 230

pod "testpod" deleted
```

## StatefulSet内のPodを直接名前解決できることを確認

```
kubectl run --image=centos:6 --restart=Never --rm -i testpod -- dig sample-statefulset-headless-0.sample-headless.default.svc.cluster.local
```

出力結果
IPアドレスが返ってきている

```
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.68.rc1.el6_10.1 <<>> sample-statefulset-headless-0.sample-headless.default.svc.cluster.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39140
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;sample-statefulset-headless-0.sample-headless.default.svc.cluster.local. IN A

;; ANSWER SECTION:
sample-statefulset-headless-0.sample-headless.default.svc.cluster.local. 5 IN A	10.42.1.8

;; Query time: 1 msec
;; SERVER: 10.43.0.10#53(10.43.0.10)
;; WHEN: Sun Oct  6 05:22:03 2019
;; MSG SIZE  rcvd: 176

pod "testpod" deleted
```

# 参考
https://www.amazon.co.jp/Kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear-%E9%9D%92%E5%B1%B1/dp/4295004804/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2KQ802O485GTG&keywords=kubernetes%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89&qid=1570339459&sprefix=kubernet%2Caps%2C256&sr=8-1