すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Service Mesh:セキュリティを向上させるための CNI プラグインの有効化

最終更新日:Jan 13, 2025

サービスメッシュ(ASM)では、Container Network Interface(CNI)プラグインを使用して、ポッドから iptables ルールを削除できます。 CNI プラグインでは、昇格された Kubernetes ロールベースアクセス制御(RBAC)権限は必要ありません。これにより、ユーザー権限の要件が軽減され、ASM のセキュリティが向上します。このトピックでは、CNI プラグインを有効にする方法について説明します。

前提条件

背景情報

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 という名前のコンテナが含まれている。

  • ポッドに複数のコンテナが含まれている。

  • ポッドに keysidecar.istio.io/inject であるアノテーションがない。

  • Pod にはアノテーション sidecar.istio.io/inject があり、その値は false ではありません。

CNI プラグインを有効にする

ASM コンソールで ASM インスタンスの CNI プラグインを有効にできます。次の手順を実行します。

  1. ASM コンソール にログインします。

  2. [メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションペインで、[データプレーンコンポーネント管理] > [ASM CNI プラグイン] を選択します。

  3. [ASM CNI プラグイン] ページで、[グリッド CNI プラグインを有効にする] をオンにし、除外する名前空間を選択して、[設定の更新] をクリックします。

    除外された名前空間のポッドは、ネットワーク構成に CNI プラグインではなく istio-init コンテナを使用します。 ASM インスタンスに対応する [ステータス] 列の値が [更新中] から [実行中] に変わると、CNI プラグインが有効になります。

iptables ルールを確認する

この例では、bookinfo アプリケーションがクラスターにデプロイされ、iptables ルールが有効になっているかどうかが確認されます。

  1. 次の内容を含む bookinfo.yaml ファイルを作成します。

    bookinfo.yaml ファイルを表示

    ##################################################################################################
    # 詳細サービス
    ##################################################################################################
    apiVersion: v1
    kind: Service
    metadata:
      name: details
      labels:
        app: details
        service: details
    spec:
      ports:
      - port: 9080
        name: http
      selector:
        app: details
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: bookinfo-details
      labels:
        account: details
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: details-v1
      labels:
        app: details
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: details
          version: v1
      template:
        metadata:
          labels:
            app: details
            version: v1
        spec:
          serviceAccountName: bookinfo-details
          containers:
          - name: details
            image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 9080
            securityContext:
              runAsUser: 1000
    ---
    ##################################################################################################
    # 評価サービス
    ##################################################################################################
    // ... (remaining YAML content translated in the same manner)
                            
  2. 次のコマンドを実行して、bookinfo アプリケーションをデプロイします。

    kubectl apply -f bookinfo.yaml
  3. 次のコマンドを実行して、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}"
  4. Productpage サービスのポッドが実行されているノードにログインします。たとえば、SSH コマンドを実行できます。ログイン後、次のコマンドを実行して、コンテナの ID に対応するプロセスを取得します。

    # コンテナランタイムが Docker の場合、次のコマンドを実行します。
    docker inspect --format '{{ .State.Pid }}' $container_id
    # コンテナランタイムが Containerd の場合、次のコマンドを実行します。
    crictl inspect $container_id|jq ".info.pid"
  5. 次のコマンドを実行して、Productpage コンテナのネットワーク名前空間に移動し、現在の構成を取得します。

    nsenter -t $ -n iptables -L -t nat -n -v --line-numbers -x

    期待される出力の表示

    Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
    num      pkts      bytes target     prot opt in     out     source               destination
    1       34938  2096280 ISTIO_INBOUND  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0
    
    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    num      pkts      bytes target     prot opt in     out     source               destination
    
    // ... (remaining codeblock content is the same)
    
    

    上記の出力は、ISTIO_INBOUNDISTIO_REDIRECTISTIO_IN_REDIRECTISTIO_OUTPUT などの iptables ルールが存在することを示しています。これは、iptables ルールが有効になっていることを示しています。