本記事は ZOZO Advent Calendar 2022 vol.3 の14日目の記事です。
昨日は @Otofuke さんの BigQuery移行で学んだクエリコスト削減Tips でした。
本記事では、Istio Operator を活用した 1.13.X → 1.14.X のアップグレードで盛大にハマってしまったポイントを紹介し、Istio Operator でのインストール・アップグレードは早急にやめて、istioctl や Helm を使った管理を推奨する話をしたいと思います。
TL;DR
本記事の主旨は以下になります。
- Istio Operator で 1.13.X → 1.14.X にアップグレードすると、Gateway Pod が正常に起動しない
-
spec.components.*
の設定を更新した Istio Operator の manifest を apply しても設定が更新されない - Istio Operator をやめよう
Istio の構成管理としては、Kustomize を用いて、Istio Operator manifest の環境ごとの差分を overlay する手法を好んで利用していたのですが、
Istio Operator は現在もサポートされてはいるものの新しい機能は追加されない方針となりました。
現在は istioctl や Helm でのインストールが強く推奨されています。
Use of the operator for new Istio installations is discouraged in favor of the Istioctl and Helm installation methods. While the operator will continue to be supported, new feature requests will not be prioritized.
引用元: https://istio.io/latest/docs/setup/install/operator/
Istio Operator を利用している方はインストール・アップグレード方法を早急に切り替えていきましょう。
ここからは、実際に Istio Operator を使ったアップグレードで、盛大にハマった具体例を紹介します。
Istio Operator で 1.13.X → 1.14.X にアップグレードすると Gateway Pod が正常に起動しない
Istio Operator におけるアップグレードは大きく以下のようなステップになります。
[1] Istio Operator manifest 更新による Control Plane と Gateway の更新
[2] Data Plane の deploymentリソース を rollout restart することによる istio-proxy (sidecar) の更新
図で示すと以下のようになります。
[1] では Istio Operator がアップグレードされると、Operator が Control Plane (istiod) と Gateway Pod をアップグレードします。
[2] の Data Plane のアップグレードは、istiod が istio-proxy (sidecar) を inject するタイミングで更新可能ですので、 rollout restart などで sidecar injection をトリガーする必要があります。
Istio Operator による 1.13.X → 1.14.X アップグレードにおいては、 [1] のタイミングで 新しい revision の Gateway Pod の起動ログで以下のようなメッセージが繰り返し出力され、Running Status にならないという問題に遭遇しました。
2022-10-12T05:31:16.683725Z warn Failed to create directory for ./var/run/secrets/workload-spiffe-uds/socket: mkdir var/run/secrets/workload-spiffe-uds: read-only file system
2022-10-12T05:31:16.683797Z error sds Failed to set up UDS path: failed to listen on unix socket "./var/run/secrets/workload-spiffe-uds/socket": listen unix ./var/run/secrets/workload-spiffe-uds/socket: bind: no such file or directory
2022-10-12T05:31:16.683813Z info sds SDS server for workload certificates started, listening on "./var/run/secrets/workload-spiffe-uds/socket"
2022-10-12T05:31:16.683832Z info xdsproxy Initializing with upstream address "istiod.istio-system.svc:15012" and cluster "Kubernetes"
2022-10-12T05:31:16.683912Z info sds Starting SDS grpc server
2022-10-12T05:31:16.683974Z warn Failed to create directory for ./var/run/secrets/workload-spiffe-uds/socket: mkdir var/run/secrets/workload-spiffe-uds: read-only file system
2022-10-12T05:31:16.684006Z error sds SDS grpc server for workload proxies failed to set up UDS: failed to listen on unix socket "./var/run/secrets/workload-spiffe-uds/socket": listen unix ./var/run/secrets/workload-spiffe-uds/socket: bind: no such file or directory
2022-10-12T05:31:16.684395Z info starting Http service at 127.0.0.1:15004
2022-10-12T05:31:16.685529Z info Pilot SAN: [istiod.istio-system.svc]
2022-10-12T05:31:16.687058Z info Starting proxy agent
2022-10-12T05:31:16.687084Z info Epoch 0 starting
2022-10-12T05:31:16.687112Z info Envoy command: [-c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --drain-strategy immediate --parent-shutdown-time-s 60 --local-address-ip-version v4 --file-flush-interval-msec 1000 --disable-hot-restart --log-format %Y-%m-%dT%T.%fZ %l envoy %n %v -l warning --component-log-level misc:error]
2022-10-12T05:31:16.996590Z info xdsproxy connected to upstream XDS server: istiod.istio-system.svc:15012
2022-10-12T05:31:17.529450Z info cache generated new workload certificate latency=845.662467ms ttl=23h59m59.470564871s
2022-10-12T05:31:17.529496Z info cache Root cert has changed, start rotating root cert
2022-10-12T05:31:17.529553Z info cache returned workload trust anchor from cache ttl=23h59m59.4704497s
2022-10-12T05:31:17.684970Z warn Failed to create directory for ./var/run/secrets/workload-spiffe-uds/socket: mkdir var/run/secrets/workload-spiffe-uds: read-only file system
2022-10-12T05:31:17.685072Z error sds SDS grpc server for workload proxies failed to set up UDS: failed to listen on unix socket "./var/run/secrets/workload-spiffe-uds/socket": listen unix ./var/run/secrets/workload-spiffe-uds/socket: bind: no such file or directory
2022-10-12T05:31:19.686360Z warn Failed to create directory for ./var/run/secrets/workload-spiffe-uds/socket: mkdir var/run/secrets/workload-spiffe-uds: read-only file system
2022-10-12T05:31:19.686433Z error sds SDS grpc server for workload proxies failed to set up UDS: failed to listen on unix socket "./var/run/secrets/workload-spiffe-uds/socket": listen unix ./var/run/secrets/workload-spiffe-uds/socket: bind: no such file or directory
2022-10-12T05:31:23.687016Z warn Failed to create directory for ./var/run/secrets/workload-spiffe-uds/socket: mkdir var/run/secrets/workload-spiffe-uds: read-only file system
2022-10-12T05:31:23.687094Z error sds SDS grpc server for workload proxies failed to set up UDS: failed to listen on unix socket "./var/run/secrets/workload-spiffe-uds/socket": listen unix ./var/run/secrets/workload-spiffe-uds/socket: bind: no such file or directory
2022-10-12T05:31:31.691479Z warn Failed to create directory for ./var/run/secrets/workload-spiffe-uds/socket: mkdir var/run/secrets/workload-spiffe-uds: read-only file system
2022-10-12T05:31:31.691552Z error sds SDS grpc server for workload proxies failed to set up UDS: failed to listen on unix socket "./var/run/secrets/workload-spiffe-uds/socket": listen unix ./var/run/secrets/workload-spiffe-uds/socket: bind: no such file or directory
2022-10-12T05:31:47.692470Z warn sds SDS grpc server could not be started
2022-10-12T05:31:55.711750Z warning envoy config StreamSecrets gRPC config stream closed since 38s ago: 14, upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: immediate connect error: No such file or directory
2022-10-12T05:32:00.680270Z warning envoy config StreamSecrets gRPC config stream closed since 43s ago: 14, upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: immediate connect error: No such file or directory
2022-10-12T05:32:01.936662Z warning envoy config StreamSecrets gRPC config stream closed since 44s ago: 14, upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: immediate connect error: No such file or directory
2022-10-12T05:32:21.463608Z warning envoy config StreamSecrets gRPC config stream closed since 63s ago: 14, upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: immediate connect error: No such file or directory
2022-10-12T05:32:23.629834Z warning envoy config StreamSecrets gRPC config stream closed since 66s ago: 14, upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: immediate connect error: No such file or directory
こちらの問題の詳細は https://github.com/istio/istio/issues/38217 で報告されています。
エラーメッセージにある通り、 /var/run/secrets/workload-spiffe-uds/
が read-only なので、 /var/run/secrets/workload-spiffe-uds/socket
の mkdir に失敗しているようです。
こちらについては、Istio Operator を活用している OSS プロジェクトの以下の commit や Pull Request を参考に、 /var/run/secrets/workload-spiffe-uds/
をマウントし、 write できるようにしようとしたのですが、私の環境では解決出来ませんでした。
https://github.com/banzaicloud/istio-operator/commit/398e5eb04e7e12b399262c40f69a7fccc9465178
https://github.com/gardener/gardener/pull/6339
引き続き自力で調査して、以下のワークアラウンドでの対処に落ち着きました。
-
istioctl upgrade --dry-run
コマンドを実行する。 - Istio Operator を利用して、 Control Plane と Gateway Pod をアップグレードする
-
istioctl upgrade
コマンドにより生成されるMutatingWebhookConfiguration
リソースであるistio-revision-tag-default
を削除 - Data Plane を rollout restart していく
あくまでもワークアラウンドの対処なので、推奨する対処ではありません。
また、https://github.com/istio/istio/issues/38217 でも解決方法やワークアラウンドの提供、また Istio Operator の改修などは行われていません。
spec.components.*
の設定を更新した Istio Operator の manifest を apply しても 設定が更新されない
これまでの方法で、無事 Istio Operator を使って、1.13 → 1.14 へのアップグレードは実施できました。
ですが、1.14 系にアップグレードしてから、spec.components.*
で指定する istiod や Ingress / Egress Gatewayの設定(例えば、replicas や limits / requests など)を更新した Istio Operator の manifest を kubectl apply しても、設定が反映されなくなってしまいました。
この設定反映がされないタイミングでの Istio Operator のログは以下のようなものでした。
istio-operator-7849d8fc6-jxvnv istio-operator ✘ Ingress gateways encountered an error: failed to update resource with server-side apply for obj HorizontalPodAutoscaler/istio-system/istio-ingressgateway: failed to create typed patch object: .spec.metrics[0].resource.targetAverageUtilization: field not declared in schema
ここでは、Ingrees Gateway に対する Server Side Apply でリソース更新に失敗し、.spec.metrics[0].resource.targetAverageUtilization
フィールドがスキーマで宣言されていないと警告されています。
こちらの問題も https://github.com/istio/istio/issues/41011 で報告されておりますので、詳細はこちらをご覧ください。
発生条件としては、以下のようです。
- 既にクラスタにデプロイされている istiod、Ingress / Egress Gateway には HPA の設定がされている
- Istio Operator の
spec.components.*.k8s.hpaSpec
が宣言されていない
対処方法としては、https://github.com/istio/istio/issues/41011#issuecomment-1249010480 にもある通り、
Istio Operator で管理するすべてのspec.componentes.*
に対して、以下のように hpaSpec の設定を明示することです。
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
components:
pilot:
k8s:
hpaSpec:
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
ingressGateways:
- enabled: true
k8s:
hpaSpec:
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
私たちの環境でも、上記の対応ですべて問題解決できました。
Istio Operator をやめよう
Istio Operator を活用した 1.13.X → 1.14.X のアップグレードはご覧の通り、ハチャメチャにハマりました。
冒頭にも記載しましましたが、Istio Operator を活用したインストール・アップグレードはサポートはされているものの、新しい機能の提供は無く、現在は istioctl や Helm の使用が強く推奨されています。
本記事執筆時点では、Istio 公式 Doc で deprecated(非推奨) という表現までは見当たらないものの、istio/istio の issue や、Istio Community の Slack を眺めていても、Istio Operator を利用する環境で発生した問題については、コミッター等から Istio Operator は deprecated なので、istioctl や Helm を使ってトライしてね、とアナウンスされているケースをしばしば見かけるようになりました。
これから Istio やってみようという方も、既に Istio を運用している方も、是非 istioctl や Helm でのインストール・アップグレードをご検討いただければと思います。