TT Lab
はじめる
学ぶ 学習パス コース

ICA — Istio認定アソシエイト

IstioOperator でインストールを調整し、revision でアップグレードする

TT Labで続きを見る

一言でいうと

Istioのインストールは、IstioOperatorという1つのドキュメントで表現され、profileはそのドキュメントのデフォルト値のまとまりで、MeshConfigはメッシュ全体に適用される設定です。アップグレードは、revisionを並べて立てるcanary方式が基本で、in-placeはより危険なので条件が付きます。

なぜ必要なのか

istioctl installの1行でIstioが立ち上がると、すべて終わったように見えます。ところが、運用ではすぐに、「アクセスログを有効にする必要がある」「egressゲートウェイを追加する必要がある」「外部の宛先をデフォルトでブロックに変える必要がある」という要求が来ます。このとき、--setフラグを1つずつ付けていくと、何を変えたのか誰も覚えていられなくなります。Istioのドキュメントは、--setと-fが同じことを行うものの、運用では-fでファイルを渡す方式を強く勧めると書いています。インストールの状態が1つのファイルに残っていて初めて、アップグレードのときに同じファイルをもう一度使えるからです。

アップグレードも同じです。コントロールプレーンをその場で入れ替えるin-place方式は、すべてのサイドカーが一度に新しいistiodを見ることになるので、問題が起きるとメッシュ全体が影響を受けます。そのためIstioは、新しいコントロールプレーンを隣にもう1つ立てて、ネームスペース単位で移していくcanary方式を推奨しています。ICA試験のInstall/Upgrade/Configドメイン(20%)は、まさにこの2つ、つまり何でインストールを揃えるのかと2つのアップグレード方式をいつ選ぶのかを問います。

どう動くのか

IstioOperator: クラスターに適用されない設定ドキュメント

istioctl install -fに渡すファイルは、install.istio.io/v1alpha1のIstioOperatorリソースです。公式のリファレンスは、このリソースを「Kubernetesのオブジェクトに似た形式だが、クラスターに適用されるものではなく、istioctlのファイル入力である」と説明しています。つまり、kubectl applyで入れるものではなく、istioctlが読んでマニフェストを作る材料です。

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  profile: default          # 기본값 묶음. 비우면 default
  revision: 1-31-0          # canary 업그레이드용 식별자. '.' 은 쓸 수 없다
  meshConfig:               # 메시 전체 설정
    accessLogFile: /dev/stdout
    outboundTrafficPolicy:
      mode: REGISTRY_ONLY
  components:               # 어떤 구성요소를 켜고 끌지, k8s 리소스 설정
    egressGateways:
    - name: istio-egressgateway
      enabled: true
  values: {}                # Helm values 로 바로 넘기는 통로(검증됨)

specの主要なフィールドは、profile、hub/tag(イメージの場所)、revision、meshConfig、components(base、pilot、cni、ztunnel、istiodRemote、ingressGateways、egressGateways)、valuesです。ドキュメントは、valuesがHelmテンプレートに渡る検証済みの通路であり、IstioOperatorSpecにある項目は、valuesの代わりに上のフィールドで書くように案内しています。古いHelmのvaluesのパスを--setで使うには、values.のプレフィックスを付けます。

profile: 名前の付いたHelm valuesのまとまり

profileは、Helmチャートに組み込まれた名前の付いたvaluesのオーバーライドのまとまりです。そのため、helmとistioctlの両方で、同じ名前で使います。デプロイのprofileは次のとおりです。

profile 用途 istioctlが一緒にインストールする構成要素
default 運用とマルチクラスターのprimaryで推奨 istiod、istio-ingressgateway
demo 機能のデモ用。トレーシングとアクセスログを高く有効にするので、性能テストには不向き istiod、ingress、egressゲートウェイ
minimal defaultと同じだが、コントロールプレーンだけ istiod
ambient ambientモードの開始用 istiod、CNI、ztunnel
remote / empty / preview 外部のコントロールプレーン用 / 何もインストールしない土台 / 実験的な機能 —

ここで、試験が好む違いが1つあります。istioctlのprofileはどの構成要素をインストールするかの一覧まで含みますが、Helmのprofileは値の集まりにすぎず、各構成要素をhelm installで1つずつ立てる必要があります。そして、--set profile=default --set values.global.platform=gkeのように、プラットフォームのprofile(gke、eks、openshift、k3sなど)を、デプロイのprofileと一緒に渡すことが推奨されます。

MeshConfig: メッシュ全体に適用される値

meshConfigは「メッシュ全体の設定」です。accessLogFileは、空ならアクセスログを無効にし、/dev/stdoutを指定すると有効にします。accessLogEncodingはTEXTがデフォルトで、JSONに変えられます。outboundTrafficPolicyのデフォルトはALLOW_ANYなので、登録されていない外部の宛先にも出ていけます。enableTracingは、スパンの生成を有効にしますが、プロキシの設定に収集器が必要です。例外が1つ、defaultConfig(ProxyConfig)です。ドキュメントは、この値がサイドカーの注入時点に一度適用されて、Podが生きている間は変わらず、残りのMeshConfigは、実行中にも動的に配布されると書いています。そのため、プロキシの設定を変えたのに反映されないなら、Podを再起動する必要があります。

istioctlとHelmのインストール経路の違い

Helmのインストールは、3つのチャートを順番に立てます。クラスタースコープのCRDを含むbase、istiodをデプロイするistiod、そしてオプションのgatewayです。revisionでインストールするときは、baseチャートに--set defaultRevision=<revision>を渡して初めて、リソース検証のWebhookが動作します。Helmで削除してもCRDは残りますが、これは意図された設計です。CRDを消すと、VirtualServiceやDestinationRuleのようなユーザーのリソースが連鎖的に削除されるからです。istioctlでインストールしたものをHelmに移すときは、--take-ownershipで既存のリソースを引き継げます。ドキュメントは、Helmガイドのチャートが、istioctlが使うチャートと同じだが、gatewayチャートだけが異なると明記しています。

canaryアップグレード: revisionを並べて立てる

istioctl install --set revision=1-31-0のようにrevisionを指定すると、istiodのDeploymentとService、サイドカー注入のWebhookが、revision名を付けてもう1つできます。既存のサイドカーは、何も影響を受けません。ワークロードを移すには、ネームスペースのistio-injection=enabledラベルを消して、istio.io/rev=<revision>を付けてから、Podを再起動します。istio-injectionラベルは、後方互換のためにistio.io/revより優先されるので、必ず消す必要があります。

ネームスペースごとにラベルを直して回る代わりに、revision tagを使います。istioctl tag set prod-stable --revision 1-30-1でタグを作り、ネームスペースにはistio.io/rev=prod-stableを付けておけば、あとでistioctl tag set prod-stable --revision 1-31-0 --overwriteを1回実行するだけで、そのタグを使うすべてのネームスペースが、新しいrevisionに移ります。defaultタグは特別で、istio-injection=enabledの注入、リソースの検証、リーダーロックを担当します。検証が終わったら、istioctl uninstall --revision 1-30-1で古いコントロールプレーンを削除します。revision方式は、マイナーの2段階スキップ(1.15 → 1.17)をサポートします。

in-placeアップグレード: 条件が多い

istioctl upgradeは、その場でコントロールプレーンとゲートウェイを入れ替えます。ドキュメントが書いている条件は次のとおりです。インストールされているバージョンが、新しいバージョンよりマイナーで1段階以下しか低くてはならず、--revisionでインストールしたものには使えず、インストールのときに使った-fファイルや--setの値をそのまま渡さないと、カスタム設定がデフォルト値に戻ってしまいます。終わったあとは、kubectl rollout restart deploymentで、データプレーンを自分で再起動する必要があります。中断を減らすには、istiodを2つ以上置いて、PodDisruptionBudgetを最小可用1にするよう勧めています。

現場での姿

あるチームが、--set5つでインストールしたメッシュをistioctl upgradeで上げたところ、アクセスログが消えて、outboundTrafficPolicyがALLOW_ANYに戻ったことがあります。アップグレードのコマンドに、同じ--setを渡さなかったからで、原因を見つけるのに1日かかりました。IstioOperatorのファイルをリポジトリに置いて、インストールもアップグレードも-fで同じファイルを渡していれば、起きなかったことです。

もう1つは、canaryを元に戻すときです。defaultのprofileでは、ゲートウェイがrevisionごとに別々には立ち上がらず、新しいrevisionにin-placeでアップグレードされます。そのため、canaryのrevisionを消すと、ゲートウェイが古いコントロールプレーンを指さなくなります。ドキュメントは、canaryを消す前に、古いistioctlでゲートウェイを先に再インストールし、正常に動作することを確認するように書いています。順序を入れ替えると、Ingressが切れます。

次のクイズで確認すること

profileごとにistioctlがインストールする構成要素、defaultConfigだけが再起動を必要とする理由、istio-injectionとistio.io/revの優先順位、revision tagを移すコマンド、そして、in-placeアップグレードが失敗したり設定を失ったりする条件を問います。参考: Install with Istioctl、Installation Configuration Profiles、Canary Upgrades、In-place Upgrades、Install with Helm。