サービスメッシュ(ASM)では、Container Network Interface(CNI)プラグインを使用して、ポッドから iptables ルールを削除できます。 CNI プラグインでは、昇格された Kubernetes ロールベースアクセス制御(RBAC)権限は必要ありません。これにより、ユーザー権限の要件が軽減され、ASM のセキュリティが向上します。このトピックでは、CNI プラグインを有効にする方法について説明します。
前提条件
バージョン 1.14.3.86 以降の ASM インスタンスが作成されていること。詳細については、「ASM インスタンスの作成」をご参照ください。
kubectl クライアントを使用して ASM インスタンスに接続していること。詳細については、「コントロールプレーンで kubectl を使用して Istio リソースにアクセスする」をご参照ください。
背景情報
ASM インスタンスが期待どおりに動作するようにするには、ASM インスタンスの各ポッドに Envoy プロキシを挿入する必要があります。次に、iptables ルールを使用して各ポッドのトラフィックを管理し、挿入された Envoy プロキシがトラフィックを指定されたアプリケーションにリダイレクトできるようにする必要があります。各ポッドの iptables ルールは、ポッドのネットワーク名前空間に属しています。したがって、ポッドの iptables ルールの変更は、同じノード上の他のポッドには影響しません。
デフォルトでは、istio-init コンテナは、ASM インスタンスにデプロイされたポッドに挿入されます。さらに、iptables ルールは、ポッド内の他のコンテナが起動される前に構成されます。これには、NET_ADMIN 機能を必要とするコンテナのデプロイとネットワークの再構成を含む、コンテナをデプロイするための十分な権限が必要です。
ASM では、CNI プラグインを使用してポッドから iptables ルールを削除できます。 CNI プラグインでは、昇格された Kubernetes RBAC 権限は必要ありません。 CNI プラグインを使用して、ポッドライフサイクルのネットワーク設定フェーズでポッドトラフィックリダイレクトを構成できます。この場合、ポッドに NET_ADMIN 機能を必要とする istio-init コンテナを含める必要はありません。 CNI プラグインを有効にすると、その構成がコンテナの既存の CNI プラグインに追加され、コンテナの起動時に CNI プラグインを呼び出すことができます。
CNI プラグインは、ポッドが次のすべての条件を満たしているかどうかを確認することにより、トラフィックリダイレクトを必要とするポッドを識別します。
ポッドの名前空間が excludeNamespaces パラメータの値に含まれていない。
ポッドに istio-proxy という名前のコンテナが含まれている。
ポッドに複数のコンテナが含まれている。
ポッドに
key
がsidecar.istio.io/inject
であるアノテーションがない。Pod にはアノテーション
sidecar.istio.io/inject
があり、その値は false ではありません。
CNI プラグインを有効にする
ASM コンソールで ASM インスタンスの CNI プラグインを有効にできます。次の手順を実行します。
ASM コンソール にログインします。
[メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションペインで、 を選択します。
[ASM CNI プラグイン] ページで、[グリッド CNI プラグインを有効にする] をオンにし、除外する名前空間を選択して、[設定の更新] をクリックします。
除外された名前空間のポッドは、ネットワーク構成に CNI プラグインではなく istio-init コンテナを使用します。 ASM インスタンスに対応する [ステータス] 列の値が [更新中] から [実行中] に変わると、CNI プラグインが有効になります。
iptables ルールを確認する
この例では、bookinfo アプリケーションがクラスターにデプロイされ、iptables ルールが有効になっているかどうかが確認されます。
次の内容を含む bookinfo.yaml ファイルを作成します。
次のコマンドを実行して、bookinfo アプリケーションをデプロイします。
kubectl apply -f bookinfo.yaml
次のコマンドを実行して、Productpage サービスのポッドが実行されているコンテナの ID とノード名を取得します。
ns=default podname=kubectl get pod |grep productpage # コンテナランタイムが Docker の場合、次のコマンドを実行します。 container_id=$(kubectl get pod -n ${ns} ${podname} -o jsonpath="{.status.containerStatuses[?(@.name=='istio-proxy')].containerID}" | sed -n 's/docker:\/\/\(.*\)/\1/p') # コンテナランタイムが Containerd の場合、次のコマンドを実行します。 container_id=$(kubectl get pod -n ${ns} ${podname} -o jsonpath="{.status.containerStatuses[?(@.name=='istio-proxy')].containerID}" | sed -n 's/containerd:\/\/\(.*\)/\1/p') echo $container_id # ノード名を取得します。 kubectl get pod ${podname} -o jsonpath="{.spec.nodeName}"
Productpage サービスのポッドが実行されているノードにログインします。たとえば、SSH コマンドを実行できます。ログイン後、次のコマンドを実行して、コンテナの ID に対応するプロセスを取得します。
# コンテナランタイムが Docker の場合、次のコマンドを実行します。 docker inspect --format '{{ .State.Pid }}' $container_id # コンテナランタイムが Containerd の場合、次のコマンドを実行します。 crictl inspect $container_id|jq ".info.pid"
次のコマンドを実行して、Productpage コンテナのネットワーク名前空間に移動し、現在の構成を取得します。
nsenter -t $ -n iptables -L -t nat -n -v --line-numbers -x