OpenShiftのRouterをzone単位に散らす

# マルチゾーンに散らしたい
---

せっかくマルチゾーンのクラスターなのだから、Podはマルチゾーンに散らしたいものですよね。
ユーザー側で作成したPodはいくらでも散らせますが、OpenShiftデフォルトでデプロイされているPodを散らすには小技が必要です。Operatorで管理されているので、Operatorが知らないうちにコトを済ませる必要があったりするのです。(本末転倒感がありますが)

# Router Podを散らすぞ

ユーザー側で作成したPodをマルチゾーンに散らしたのに、その手前に存在するRouter Podが片方のゾーンに寄ってしまっている…なんてことがあります。

```bash
$oc get po -owide -n openshift-ingress
NAME                              READY   STATUS    RESTARTS   AGE   IP               NODE          NOMINATED NODE   READINESS GATES
router-default-6bf85d74d8-klps5   1/1     Running   0          10d   172.17.150.225   10.244.4.41   <none>           <none>
router-default-6bf85d74d8-qtbjt   1/1     Running   0          10d   172.17.174.124   10.244.4.39   <none>           <none>
```

topologySpreadConstraintsを利用して散らしたいものです。
しかし、RouterはOperatorで管理しているので、Deploymentの定義を修正してももとに戻されてしまいます。
この場合、Operatorを一旦停止し、その間にDeploymentを修正することでOperatorに勝手に定義を戻されずに修正が可能です。

## さっそく

```bash
$oc -n openshift-ingress-operator get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
ingress-operator   1/1     1            1           32d
```

このDeploymentのレプリカ数を0にします。

```bash
~ $oc -n openshift-ingress-operator scale deploy/ingress-operator --replicas=0
deployment.apps/ingress-operator scaled
~ $
~ $oc -n openshift-ingress-operator get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
ingress-operator   0/0     0            0           32d
```

この状態で、RouterのDeploymentを修正します。

```bash
$ oc -n openshift-ingress edit deploy/router-default
```

spec.containerと同列に以下を追記してみます。

```yaml
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: failure-domain.beta.kubernetes.io/zone
        whenUnsatisfiable: ScheduleAnyway
```


試しに、Router Podをスケールアウトしてみます。
ちゃんとゾーンに散らかっていることが分かります。

```bash
$oc -n openshift-ingress scale deploy router-default --replicas=4
deployment.apps/router-default scaled

$oc -n openshift-ingress get po -owide
NAME                              READY   STATUS    RESTARTS   AGE     IP              NODE           NOMINATED NODE   READINESS GATES
router-default-69bdf79f44-58qhh   1/1     Running   0          111s    172.17.57.75    10.244.128.4   <none>           <none>
router-default-69bdf79f44-99qqx   1/1     Running   0          7m59s   172.17.54.199   10.244.64.20   <none>           <none>
router-default-69bdf79f44-gmrvk   1/1     Running   0          7m59s   172.17.10.52    10.244.128.8   <none>           <none>
router-default-69bdf79f44-qwf2n   1/1     Running   0          111s    172.17.11.207   10.244.0.5     <none>           <none>
```

ところで、さきほど停止した`ingress-operator` は自動的に再起動します。

```bash
$oc -n openshift-ingress-operator get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
ingress-operator   1/1     1            1           32d
```

さきほど設定した散らし設定は生きています。

```bash
$oc -n openshift-ingress get deploy router-default -oyaml | grep -A5 topologySpreadConstraints
            f:topologySpreadConstraints:
              .: {}
              k:{"topologyKey":"failure-domain.beta.kubernetes.io/zone","whenUnsatisfiable":"ScheduleAnyway"}:
                .: {}
                f:maxSkew: {}
                f:topologyKey: {}
---
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: failure-domain.beta.kubernetes.io/zone
        whenUnsatisfiable: ScheduleAnyway
      volumes:
      - name: default-certificate
      
```

以上でございます。