Istio CNIノードエージェントのインストール
IstioのCNIノードエージェントは、メッシュ内のPodのトラフィックリダイレクトを設定するために使用されます。これは、すべてのノードで、昇格された権限を持つDaemonSetとして実行されます。CNIノードエージェントは、Istioの両方のデータプレーンモードで使用されます。
サイドカーデータプレーンモードの場合、Istio CNIノードエージェントはオプションです。これにより、メッシュ内のすべてのPodで特権を持つinitコンテナを実行する必要がなくなり、そのモデルが各Kubernetesノード上の単一の特権を持つノードエージェントPodに置き換えられます。
Istio CNIノードエージェントは、アンビエントデータプレーンモードでは必須です。
このガイドは、Istio CNIノードエージェントをサイドカーデータプレーンモードのオプションコンポーネントとして使用することに焦点を当てています。アンビエントデータプレーンモードの使用については、アンビエントモードのドキュメントを参照してください。
このガイドに従って、Istio CNIノードエージェントをサイドカーデータプレーンモードでインストール、設定、および使用します。
サイドカートラフィックリダイレクトの仕組み
initコンテナの使用(Istio CNIノードエージェントなし)
デフォルトでは、IstioはメッシュにデプロイされたPodにistio-init
initコンテナを注入します。istio-init
コンテナは、Istioサイドカープロキシとの間のPodネットワークトラフィックのリダイレクトを設定します。これには、メッシュにPodをデプロイするユーザーまたはサービスアカウントが、NET_ADMIN
およびNET_RAW
機能を持つコンテナをデプロイするのに十分なKubernetes RBAC権限を持っている必要があります。
Istio CNIノードエージェントの使用
Istioユーザーに昇格されたKubernetes RBAC権限を要求することは、すべてのワークロードで特権を持つinitコンテナをデプロイする必要性と同様に、一部の組織のセキュリティコンプライアンスにとって問題となります。
istio-cni
ノードエージェントは、istio-init
コンテナの事実上の代替であり、同じネットワーク機能を有効にしますが、すべてのワークロードで特権を持つinitコンテナの使用またはデプロイを必要としません。代わりに、istio-cni
自体はノード上の単一の特権を持つPodとして実行されます。これは、この特権を使用して、ノードにチェーンされたCNIプラグインをインストールします。これは、「プライマリ」インターフェースCNIプラグインの後で呼び出されます。CNIプラグインは、新しいPodが作成されるたびに、ホストノードで特権プロセスとしてKubernetesによって動的に呼び出され、Podネットワークを設定できます。
IstioチェーンCNIプラグインは、常にプライマリインターフェースプラグインの後に実行され、トラフィックリダイレクトを必要とするサイドカーを持つユーザーアプリケーションPodを識別し、Kubernetes Podライフサイクルのネットワーク設定フェーズでリダイレクトを設定します。これにより、特権を持つinitコンテナの必要性と、NET_ADMIN
およびNET_RAW
機能の要件がユーザーとPodデプロイメントから削除されます。
使用のための前提条件
正しく構成されたプライマリインターフェースCNIプラグインを使用してKubernetesをインストールします。Kubernetesネットワークモデルを実装するには、サポートされているCNIプラグインが必要であるため、機能的なPodネットワークを持つ比較的新しいKubernetesクラスタがある場合は、おそらく既にこれがあります。
- AWS EKS、Azure AKS、およびIBM Cloud IKSクラスタはこの機能を備えています。
- Google Cloud GKEクラスタは、次の機能のいずれかが有効になっている場合、CNIが有効になります。ネットワークポリシー、ノード内可視性、ワークロードアイデンティティ、Podセキュリティポリシー、またはデータプレーンv2。
- KindはデフォルトでCNIが有効になっています。
- OpenShiftはデフォルトでCNIが有効になっています。
ServiceAccountアドミッションコントローラを有効にしてKubernetesをインストールします。
- Kubernetesのドキュメントでは、
ServiceAccounts
が使用されるすべてのKubernetesインストールに対して、これを強く推奨しています。
- Kubernetesのドキュメントでは、
CNIノードエージェントのインストール
istio-cni
コンポーネントを使用したIstioのインストール
ほとんどの環境では、istio-cni
コンポーネントが有効になっている基本的なIstioクラスタを、次のコマンドを使用してインストールできます。
$ cat <<EOF > istio-cni.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
components:
cni:
namespace: istio-system
enabled: true
EOF
$ istioctl install -f istio-cni.yaml -y
$ helm install istio-cni istio/cni -n istio-system --wait
これにより、クラスタにistio-cni
DaemonSetがデプロイされ、アクティブなノードごとに1つのPodが作成され、各ノードにIstio CNIプラグインバイナリがデプロイされ、プラグインに必要なノードレベルの設定が設定されます。CNI DaemonSetはsystem-node-critical
PriorityClass
で実行されます。これは、Podネットワークを再構成してIstioメッシュに追加する唯一の方法であるためです。
Helm チャートを使用してHelm によるインストールガイドに従って istiod
をインストールする場合、特権付き init コンテナの注入を無効にするために、次の追加のオーバーライド値を使用して istiod
をインストールする必要があります。
$ helm install istiod istio/istiod -n istio-system --set pilot.cni.enabled=true --wait
追加の設定
上記の基本設定に加えて、設定できる追加の構成フラグがあります。
values.cni.cniBinDir
とvalues.cni.cniConfDir
は、プラグインバイナリをインストールし、プラグイン構成を作成するディレクトリパスを設定します。values.cni.cniConfFileName
は、プラグイン構成ファイルの名前を設定します。values.cni.chained
は、プラグインをチェーンされた CNI プラグインとして構成するかどうかを制御します。
通常、これらは変更する必要はありませんが、一部のプラットフォームでは非標準パスを使用する場合があります。該当する場合は、特定のプラットフォームのガイドラインを確認してください。こちら。
リビジョンに対するinitコンテナインジェクションの処理
CNI コンポーネントが有効になっているリビジョン付きコントロールプレーンをインストールする場合、各インストール済みリビジョンに対して values.pilot.cni.enabled=true
を設定する必要があります。これにより、サイドカーインジェクターがそのリビジョンに対して istio-init
init コンテナの注入を試行しません。
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
revision: REVISION_NAME
...
values:
pilot:
cni:
enabled: true
...
バージョン1.x
の CNI プラグインは、バージョン1.x-1
、1.x
、および1.x+1
のコントロールプレーンと互換性があります。つまり、CNI とコントロールプレーンのバージョン差がマイナーバージョン1つ以内であれば、どちらの順序でアップグレードしても問題ありません。
CNIノードエージェントがインストールされたクラスタの運用
アップグレード
インプレースアップグレードで Istio をアップグレードする場合、CNI コンポーネントは 1 つの IstioOperator
リソースを使用してコントロールプレーンと共にアップグレードできます。
カナリアアップグレードで Istio をアップグレードする場合、CNI コンポーネントはクラスタシングルトンとして実行されるため、リビジョン付きコントロールプレーンとは別に CNI コンポーネントを操作およびアップグレードすることをお勧めします。
次の IstioOperator
を使用して、CNI コンポーネントを独立してアップグレードできます。
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: empty # Do not include other components
components:
cni:
enabled: true
values:
cni:
excludeNamespaces:
- istio-system
istio-cni は個別にインストールされ、Helm でアップグレードできるため、Helm の場合は問題ありません。
$ helm upgrade istio-cni istio/cni -n istio-system --wait
競合状態と軽減策
Istio CNI DaemonSet は、すべてのノードに CNI ネットワークプラグインをインストールします。ただし、DaemonSet Pod がノードにスケジュールされ、CNI プラグインがインストールされて使用可能になるまでには時間差があります。その時間差中にアプリケーション Pod が起動し、kubelet
が Istio CNI プラグインを認識しない可能性があります。その結果、アプリケーション Pod は Istio トラフィックリダイレクトなしで起動し、Istio サイドカーをバイパスします。
アプリケーション Pod と Istio CNI DaemonSet の間の競合状態を軽減するために、サイドカーインジェクションの一部として istio-validation
init コンテナが追加されます。これは、トラフィックリダイレクトが正しく設定されているかどうかを検出し、正しくない場合は Pod の起動をブロックします。CNI DaemonSet は、そのような状態に陥っている Pod を検出して処理します。Pod の処理方法は、以下に説明する構成によって異なります。この軽減策はデフォルトで有効になっており、values.cni.repair.enabled
を false に設定することで無効にすることができます。
この修復機能は、ISTIO-SECURITY-2023-005
で詳述されている理論的な攻撃ベクトルを軽減するために、異なる RBAC 権限でさらに構成できます。以下のフィールドを必要に応じて true/false に設定することで、Istio CNI に付与される Kubernetes RBAC 権限を選択できます。
設定 | ロール | エラー時の動作 | 備考 |
---|---|---|---|
values.cni.repair.deletePods | Pod の削除 | Pod は削除され、再スケジュールされると正しい構成になります。 | 1.20以前のデフォルト |
values.cni.repair.labelPods | Pod の更新 | Pod にラベルが付けられるだけです。ユーザーは手動で解決する必要があります。 | |
values.cni.repair.repairPods | なし | Pod は、適切な構成を持つように動的に再構成されます。コンテナが再起動すると、Pod は通常の処理を続行します。 | 1.21以降のデフォルト |
トラフィックリダイレクトパラメータ
アプリケーション Pod のネットワーク名前空間内のトラフィックを Istio プロキシサイドカーとの間でリダイレクトするには、Istio CNI プラグインは名前空間の iptables を構成します。ポートや、リダイレクションに含めるか除外する IP 範囲など、通常の Pod アノテーションと同じ Pod アノテーションを使用して、トラフィックリダイレクションパラメーターを調整できます。使用可能なパラメーターについては、リソースアノテーションを参照してください。
アプリケーションinitコンテナとの互換性
Istio CNI プラグインは、サイドカーデータプレーンモードのアプリケーション init コンテナのネットワーク接続の問題を引き起こす可能性があります。Istio CNI を使用する場合、kubelet
は次の手順で Pod を開始します。
- デフォルトのインターフェース CNI プラグインは、Pod ネットワークインターフェースを設定し、Pod IP を割り当てます。
- Istio CNI プラグインは、Pod 内の Istio サイドカープロキシへのトラフィックリダイレクションを設定します。
- すべての init コンテナが正常に実行され、完了します。
- Pod 内の他のコンテナと共に、Istio サイドカープロキシが Pod で起動します。
init コンテナはサイドカープロキシの起動前に実行されるため、実行中にトラフィックが損失する可能性があります。次の設定のいずれかを使用して、このトラフィック損失を防ぎます。
runAsUser
を使用して、init コンテナのuid
を1337
に設定します。1337
は、サイドカープロキシで使用されるuid
です。このuid
によって送信されたトラフィックは、Istio のiptables
ルールによってキャプチャされません。アプリケーションコンテナのトラフィックは通常どおりキャプチャされます。traffic.sidecar.istio.io/excludeOutboundIPRanges
アノテーションを設定して、init コンテナが通信する任意の CIDR へのトラフィックのリダイレクトを無効にします。traffic.sidecar.istio.io/excludeOutboundPorts
アノテーションを設定して、init コンテナが使用する特定のアウトバウンドポートへのトラフィックのリダイレクトを無効にします。
他のCNIとの互換性
Istio CNI プラグインはCNI 仕様に従っており、仕様にも従っている CNI、コンテナーランタイム、またはその他のプラグインと互換性があるはずです。
Istio CNI プラグインは、チェーンされた CNI プラグインとして動作します。つまり、その構成は既存の CNI プラグイン構成のリストに追加されます。詳細については、CNI 仕様リファレンスを参照してください。
Pod が作成または削除されると、コンテナーランタイムはリスト内の各プラグインを順番に呼び出します。
Istio CNI プラグインは、アプリケーション Pod のトラフィックリダイレクションを設定するアクションを実行します。サイドカーデータプレーンモードでは、これは Pod のネットワーク名前空間でiptables
ルールを適用して、Pod 内のトラフィックを注入された Istio プロキシサイドカーにリダイレクトすることを意味します。