k8s の ReplicaSet のデフォルトスケジューリングについて調べた

メモです

# まとめ

+ デフォルトで別ホストに Pod を分散しようとする。また複数ゾーンの Node の場合にはゾーン分散されるように配置を試みる
+ 上記動きは `SelectorSpreadPriority` によって達成される
+ ベストエフォートの動きとなる

# 調査

## ドキュメント

複数ゾーンでの運用については以下のドキュメントがあり、言及がある。

[Running in multiple zones](https://kubernetes.io/docs/setup/best-practices/multiple-zones/#functionality)

>Kubernetes will automatically spread the pods in a replication controller or service across nodes in a single-zone cluster (to reduce the impact of failures.) With multiple-zone clusters, this spreading behavior is extended across zones (to reduce the impact of zone failures.) (This is achieved via SelectorSpreadPriority). This is a best-effort placement, and so if the zones in your cluster are heterogeneous (e.g. different numbers of nodes, different types of nodes, or different pod resource requirements), this might prevent perfectly even spreading of your pods across zones. If desired, you can use homogeneous zones (same number and types of nodes) to reduce the probability of unequal spreading.

ここでまとめに記載してある内容が書いてある

次に `SelectorSpreadPriority` について見てみる

Pod のスケジューリングは `kube-scheduler` が実施する。
そしてスケジューリングでは大きく分けて以下の２種類がある認識

[Scheduling Policies](https://kubernetes.io/docs/reference/scheduling/policies/)

+ Predicates(フィルタリング)
+ Priorities（スコアリング)

`Predicates` はフィルタリングとなり、そもそも対象 Node に配置可能か、という確認となる（例:要求されたリソースが足りいるか、必須条件として指定されたラベルがあるかなど）

上記で対象となる Node 郡に対して `Priorities` スコアリングをして、どの Node に配置するかを決める認識。

この `Priorities`  に `SelectorSpreadPriority` があるので、スコアリングに影響させる事で複数ゾーンに分散をしている、ということだと思われる。
ただし、他のスコアリング要件などもある為、ゾーン分散は確実にするものではなく、ベストエフォートで実現するという記述になっていると思われる。

## 検証してみる

実際の挙動を確認してみる

### 検証環境

```bash
$kubectl version
Client Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.6-beta.0", GitCommit:"e7f962ba86f4ce7033828210ca3556393c377bcc", GitTreeState:"clean", BuildDate:"2020-01-15T08:26:26Z", GoVersion:"go1.13.5", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.13-eks-2ba888", GitCommit:"2ba888155c7f8093a1bc06e3336333fbdb27b3da", GitTreeState:"clean", BuildDate:"2020-07-17T18:48:53Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
```

Node については合計4台で2ゾーンに分散しているものとする。

```bash
$k get nodes
NAME                                                STATUS   ROLES    AGE    VERSION
ip-192-168-34-65.ap-northeast-1.compute.internal    Ready    <none>   2d6h   v1.15.11-eks-065dce
ip-192-168-52-98.ap-northeast-1.compute.internal    Ready    <none>   2d6h   v1.15.11-eks-065dce
ip-192-168-84-65.ap-northeast-1.compute.internal    Ready    <none>   2d6h   v1.15.11-eks-065dce
ip-192-168-88-223.ap-northeast-1.compute.internal   Ready    <none>   2d6h   v1.15.11-eks-065dce
```

ゾーンの分散は以下の通り。

+ ip-192-168-34-65.ap-northeast-1.compute.internal:1-c
+ ip-192-168-52-98.ap-northeast-1.compute.internal:1-c
+ ip-192-168-84-65.ap-northeast-1.compute.internal:1-c
+ ip-192-168-88-223.ap-northeast-1.compute.interna:1-a

### 試してみる
 
`replicaset=2` でやってみる

```bash
$k run nginx --image=nginx --replicas=2

$k get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP               NODE                                                NOMINATED NODE   READINESS GATES
nginx-6db489d4b7-mmrhz   1/1     Running   0          6s    192.168.65.235   ip-192-168-88-223.ap-northeast-1.compute.internal   <none>           <none>
nginx-6db489d4b7-r9trf   1/1     Running   0          6s    192.168.48.24    ip-192-168-34-65.ap-northeast-1.compute.internal    <none>           <none>
```

`1-c` と `1-a` に分散されている。

次に `replicaset=4` にしてみる

```
$k scale deployment nginx --replicas=4

$k get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP               NODE                                                NOMINATED NODE   READINESS GATE
S
nginx-6db489d4b7-bvh6s   1/1     Running   0          24s   192.168.74.179   ip-
192-168-84-65.ap-northeast-1.compute.internal    <none>           <none>
nginx-6db489d4b7-mmrhz   1/1     Running   0          93m   192.168.65.235   ip-
192-168-88-223.ap-northeast-1.compute.internal   <none>           <none>
nginx-6db489d4b7-n96lv   1/1     Running   0          23s   192.168.58.111   ip-
192-168-34-65.ap-northeast-1.compute.internal    <none>           <none>
nginx-6db489d4b7-r9trf   1/1     Running   0          93m   192.168.48.24    ip-
192-168-34-65.ap-northeast-1.compute.internal    <none>           <none>
```

ゾーン分散しつつ、ホストもすべて別れている。
想定通りの動きとなった