Istio Upgradeに関するメモ書き (IstioOperator使用時)

2021年1月頃に色々と試行錯誤したときの記録。なお当時最新版は1.8.2。現在1.9.2/1.8.4が出ている。インストールはOperator使用、かつcontrol-plane/ingressgatewayは別のIstioOperator CRで管理している前提。

# メモ書き

- Canary Upgradeは[1.8.x以降でないと使えない](https://github.com/istio/istio/issues/28964#issuecomment-732287567)
    - 1.8.xまではin-place upgradeを使う。ちなみにin-place upgradeで1.7.x <-> 1.8.xの行き来は極めてスムーズに実施出来たという記録あり
    - 1.7.6 -> 1.8.1のCanaryを何度か試した記録によると「たまたまうまくいく」こともあったが、これは本当にたまたまにうまくいっただけであり **絶対にやるべきでない。** そもそも公式で1.8.x以降しかCanaryは出来ないと言っている
        - 補足：IstioOperator(リソース)の変更をどっちのistio-operator(Pod)が先に拾うか、によって結末が変わる。本来はistio-operatorがここでIstioOperatorのrevisionを見て「あっこれは自分が処理するべきじゃないやつだ」とスキップするべきところを1.7.x以前はスキップしないことが原因
- 1.8.x(revision無し) -> 1.8.x(revisionあり)のCanaryは問題なく実行出来る
    - よって、1.7.x以前からのアップグレードパスは以下のようにするのが良いと思われる
        - 1.6.x(revision無し) --[in-place]--> 1.7.x(revision無し)
        - 1.7.x(revision無し) --[in-place]--> 1.8.x(revision無し)
        - 1.8.x(revision無し) --[Canary]--> 1.8.x(revisionあり)
            - この時、実際のバージョンは揃えたほうが良いと思われる。例えば1.8.2(revision無し) -> 1.8.2(revisionあり)など。
- 1.8.x(revisionあり) -> 1.8.x(revisionあり)のCanaryはスムーズに出来ないので注意が必要(1.8.1 <-> 1.8.2での実績にもとづく)
    - revisonあり→あり、の場合の問題点は、元のバージョンのcontrol-planeのIstioOperator CRの削除がうまくいかない、ということ。具体的にどううまくいかないかというと、kubectl deleteが永遠に終わらない。原因は(古いrevisionで生成された)全てのリソースがクリーンナップされる前に(古いrevisionの)IstioOperatorが消されてしまうからっぽい
    - 1.8.1 -> 1.8.2 (canary) の場合の最後の処理
        - `kubectl delete istiooperator/control-plane-1-8-1`
            - フリーズする
        - `kubectl edit istiooperator/control-plane-1-8-1`
            - `revision: 1-8-2` に書き換える → フリーズしたdeleteが終了してCRが消える
        - `istioctl operator remove --force --revision 1-8-1`
            - `clusterrolebinding` が残るので、消す
        - (念の為) `kubectl rollout restart deploy/istio-operator-1-8-2 -n istio-operator`
    - そもそもIstioOperator CRを消したときにistio-operator自体が消えてしまうのは挙動として想定されているのだろうか？公式のdocでもIstioOperator CRを消した後にistioctlを使ってOperatorを消す手順になっているので、これは1.8.xにおけるバグのような気がしないでもない
- **Canaryで1.8.x(revisoinあり) -> 1.8.x(revision無し)にする方法は未だ確率していない(試していない)**
- istiodがログを吐き出しまくっている件 -> revisionedだと問題になる。[公式に注意書きがいつの間にか追加されていた。](https://istio.io/latest/docs/setup/upgrade/canary/)
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28237/307113d7-b31b-1acb-06f8-97e53229c592.png)
    - [Revision Upgrades Break Validation Webhook #28880
](https://github.com/istio/istio/issues/28880)
    - [Istio v1.8.1: How to enable validatingwebhook’s failurePolicy to fail?](https://discuss.istio.io/t/istio-v1-8-1-how-to-enable-validatingwebhooks-failurepolicy-to-fail/9451/3)
        - こちらの直し方(patchでWebhookが見に行く先のURLをrevision付きに変えてしまう)のほうが良さそう

# 1.8.2(revisionあり) -> 1.9.2(revisionあり) Canary Upgrade実施時のメモ

- Validation Webhookの件をpatchで対応したら、control-planeのIstioOperator CRの初回Reconcileでエラー -> `kubectl get iop -A` で表示されるHEALTHがERRORになってしまう。単ににわたま問題なのでistiodのPodがReadyになったら `kubectl rollout restart deploy/istio-operator-1-9-2 -n istio-operator` してやれば良い。
    - 出てたエラーログ

```
istio-operator-1-9-2-8c594dcdb-59v8l istio-operator - Processing resources for Istiod.
istio-operator-1-9-2-8c594dcdb-59v8l istio-operator ✘ Istiod encountered an error: failed to update resource with server-side apply for obj EnvoyFilter/istio-system/metadata-exchange-1.8-1-9-2: Internal error occurred: failed calling webh
ook "validation.istio.io": Post https://istiod-1-9-2.istio-system.svc:443/validate?timeout=30s: service "istiod-1-9-2" not found
istio-operator-1-9-2-8c594dcdb-59v8l istio-operator failed to update resource with server-side apply for obj EnvoyFilter/istio-system/metadata-exchange-1.9-1-9-2: Internal error occurred: failed calling webhook "validation.istio.io": Post
 https://istiod-1-9-2.istio-system.svc:443/validate?timeout=30s: service "istiod-1-9-2" not found
istio-operator-1-9-2-8c594dcdb-59v8l istio-operator failed to update resource with server-side apply for obj EnvoyFilter/istio-system/stats-filter-1.8-1-9-2: Internal error occurred: failed calling webhook "validation.istio.io": Post http
s://istiod-1-9-2.istio-system.svc:443/validate?timeout=30s: service "istiod-1-9-2" not found
istio-operator-1-9-2-8c594dcdb-59v8l istio-operator failed to update resource with server-side apply for obj EnvoyFilter/istio-system/stats-filter-1.9-1-9-2: Internal error occurred: failed calling webhook "validation.istio.io": Post http
s://istiod-1-9-2.istio-system.svc:443/validate?timeout=30s: service "istiod-1-9-2" not found
istio-operator-1-9-2-8c594dcdb-59v8l istio-operator failed to update resource with server-side apply for obj EnvoyFilter/istio-system/tcp-metadata-exchange-1.8-1-9-2: Internal error occurred: failed calling webhook "validation.istio.io":
Post https://istiod-1-9-2.istio-system.svc:443/validate?timeout=30s: service "istiod-1-9-2" not found
istio-operator-1-9-2-8c594dcdb-59v8l istio-operator failed to update resource with server-side apply for obj EnvoyFilter/istio-system/tcp-metadata-exchange-1.9-1-9-2: Internal error occurred: failed calling webhook "validation.istio.io":
Post https://istiod-1-9-2.istio-system.svc:443/validate?timeout=30s: service "istiod-1-9-2" not found
istio-operator-1-9-2-8c594dcdb-59v8l istio-operator failed to update resource with server-side apply for obj EnvoyFilter/istio-system/tcp-stats-filter-1.8-1-9-2: Internal error occurred: failed calling webhook "validation.istio.io": Post
https://istiod-1-9-2.istio-system.svc:443/validate?timeout=30s: service "istiod-1-9-2" not found
```

- 『1.8.x(revisionあり) -> 1.8.x(revisionあり)のCanaryはスムーズに出来ない』再現
    - Upgrade元が1.8.xなので、今回のケースでもヒットするかなと思っていたら予想的中
    - 落ち着いて以下を実施する
        - `kubectl edit istiooperator/control-plane-1-8-2 -n istio-system`
            - `revision: 1-9-2` に変更して保存
            - ログ(後述)が出て1.9.2のOperatorが削除を完了してくれる
        - `istioctl operator remove --dry-run --force --revision 1-8-2`
            - ClusterRoleBinding::istio-operator-1-8-2 だけ残っている(想定通り)
            - `--dry-run` 外して実行するのを忘れずに…

1-9-2なOperatorがcontrol-plane-1-8-2のrevisionを書き換えた後に消してくれるところ。最後がReconcilingになってて大丈夫か？と一瞬思うけど、対象のIstioOperator CRは消えているので問題ないだろう。

```
istio-operator-1-9-2-79cc669495-cmp85 istio-operator 2021-03-28T07:32:28.918336Z        info    installer       Reconciling IstioOperator
istio-operator-1-9-2-79cc669495-cmp85 istio-operator 2021-03-28T07:32:28.920843Z        info    installer       Deleting IstioOperator control-plane-1-8-2
istio-operator-1-9-2-79cc669495-cmp85 istio-operator 2021-03-28T07:32:29.009810Z        info    installer       API server conflict during finalizer removal, retrying.
istio-operator-1-9-2-79cc669495-cmp85 istio-operator 2021-03-28T07:32:29.030843Z        info    installer       Reconciling IstioOperator
```

1-8-2なOperatorが自分を消すのに失敗するあたりのログ。

```
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator 2021-03-28T07:23:01.098049Z        info    installer       Watching a change for istio resource: /istio-sidecar-injector-1-8-2
istio-operator-1-9-2-79cc669495-cmp85 istio-operator 2021-03-28T07:23:01.102986Z        info    installer       Watching a change for istio resource: /istio-sidecar-injector-1-8-2
istio-operator-1-9-2-79cc669495-cmp85 istio-operator 2021-03-28T07:23:01.103052Z        info    installer       Reconciling IstioOperator
istio-operator-1-9-2-79cc669495-cmp85 istio-operator 2021-03-28T07:23:01.106663Z        info    installer       Ignoring IstioOperator CR control-plane-1-8-2 with revision 1-8-2, since operator revision is 1-9-2.
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator   Removed ClusterRole::istio-operator-1-8-2.
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator 2021-03-28T07:23:01.123426Z        info      Removed ClusterRole::istio-operator-1-8-2.
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator   Removed ClusterRoleBinding::istio-operator-1-8-2.
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator 2021-03-28T07:23:01.126782Z        info      Removed ClusterRoleBinding::istio-operator-1-8-2.
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator 2021-03-28T07:23:01.329177Z        error   klog    error retrieving resource lock istio-operator/istio-operator-lock-1-8-2: configmaps "istio-operator-lock-1-8-2" is forbidden: User "system:serviceaccount:istio-operator:istio-operator-1-8-2" cannot get resource "configmaps" in API group "" in the namespace "istio-operator": RBAC: clusterrole.rbac.authorization.k8s.io "istio-operator-1-8-2" not found[]
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator 2021-03-28T07:23:02.130306Z        info    installer       Reconciling IstioOperator
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator 2021-03-28T07:23:02.132196Z        info    installer       Deleting IstioOperator control-plane-1-8-2
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator 2021-03-28T07:23:03.153164Z        info    installer       Reconciling IstioOperator
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator 2021-03-28T07:23:03.154462Z        info    installer       Deleting IstioOperator control-plane-1-8-2
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator 2021-03-28T07:23:03.165553Z        info    Closing ControlZ
istio-operator-1-8-2-6787b6bb4d-9mcg7 istio-operator 2021-03-28T07:23:03.165610Z        info    ControlZ terminated: accept tcp 127.0.0.1:9876: use of closed network connection
```

今改めて見て気がついだのだが、

`error retrieving resource lock istio-operator/istio-operator-lock-1-8-2: configmaps "istio-operator-lock-1-8-2" is forbidden: User "system:serviceaccount:istio-operator:istio-operator-1-8-2" cannot get resource "configmaps" in API group "" in the namespace "istio-operator": RBAC: clusterrole.rbac.authorization.k8s.io "istio-operator-1-8-2" not found[]`

完全にこれが原因ではないか。そのちょっと上で `Removed ClusterRole::istio-operator-1-8-2.` しているし。