Image Cleaner を使用して Azure Kubernetes Service (AKS) クラスターで脆弱な古いイメージをクリーンアップする

パイプラインを使用して Azure Kubernetes Service (AKS) クラスターでイメージをビルドしてデプロイするのが一般的です。 このプロセスはイメージの作成には適していますが、残された古いイメージを考慮していないことが多く、クラスター ノードでイメージが肥大化することがあります。 これらのイメージには脆弱性が含まれている可能性があり、セキュリティの問題が発生する可能性があります。 クラスターのセキュリティ リスクを削除するには、これらの参照されていないイメージをクリーンします。 手動で画像をクリーニングすると、時間がかかる場合があります。 Image Cleaner は、イメージの自動識別と削除を実行します。これにより、古いイメージのリスクが軽減され、イメージをクリーンするのに必要な時間が短縮されます。

Note

Image Cleaner は Eraser に基づいた機能です。 AKS クラスターでは、機能名とプロパティ名は Image Cleaner ですが、関連する Image Cleaner ポッドの名前には Eraser が含まれます。

前提条件

  • Azure サブスクリプション。 Azure サブスクリプションをお持ちでない場合は、無料のアカウントを作成できます。
  • Azure CLI バージョン 2.49.0 以降。 バージョンを確認するには az --version を実行します。 インストールまたはアップグレードする必要がある場合は、Azure CLI のインストールに関するページを参照してください。

制限事項

Image Clearner では、Windows ノード プールまたは AKS 仮想ノードはまだサポートされていません。

Image Cleaner のしくみ

Image Cleaner を有効にすると、eraser-controller-manager という名前のコントローラー マネージャー ポッドがクラスターにデプロイされます。

Image Cleaner のワークフローを示した図のスクリーンショット。ImageList は、クラスターで実行されている Image Cleaner ポッドで生成できます。手動で入力することもできます。

Image Cleaner を使用すると、手動モードと自動モードと、次の構成オプションのいずれかを選択できます:

構成オプション

名前 説明 必須
--enable-image-cleaner AKS クラスターの Image Cleaner 機能を有効にします はい (disable を指定した場合を除く)
--disable-image-cleaner AKS クラスターの Image Cleaner 機能を無効にします はい (enable を指定した場合を除く)
--image-cleaner-interval-hours このパラメーターは、Image Cleaner が実行に使用する時間間隔 (時間単位) を決定します。 Azure CLI の既定値は 1 週間であり、最小値は 24 時間、最大値は 3 か月です。 Azure CLI では必須ではありません。ARM テンプレートまたはその他のクライアントに必要です

自動モード

eraser-controller-manager がデプロイされると、以下の手順が自動的に実行されます。

  • クリーンアップ プロセスが直ちに開始され、ノードごとに eraser-aks-xxxxx ワーカー ポッドが作成されます。
  • 各ワーカー ポッドには 3 つのコンテナーがあります。
    • collector。使われていないイメージを収集します。
    • trivy-scannertrivy を利用してイメージの脆弱性をスキャンします。
    • remover。脆弱性のある使われていないイメージを削除します。
  • クリーンアップ プロセスが完了すると、ワーカー ポッドが削除され、次にスケジュールされたクリーン アップが定義した --image-cleaner-interval-hours に従って実行されます。

手動モード

CRD オブジェクト ImageList を定義することで、クリーンアップを手動でトリガーすることができます。 これにより、eraser-contoller-manager がトリガーされて各ノードに eraser-aks-xxxxx ワーカー ポッドが作成され、手動削除プロセスが完了します。

Note

Image Cleaner を無効にした後も、古い構成はそのまま残ります。 つまり、構成を明示的に渡さずに機能を再度有効にすると、既定値ではなく既存の値が使用されます。

AKS クラスターで Image Cleaner を有効にする

新しいクラスターで Image Cleaner を有効にする

  • --enable-image-cleaner パラメーターを指定して az aks create コマンドを使用して、新しい AKS クラスターで Image Cleaner を有効にします。

    az aks create \
        --resource-group myResourceGroup \
        --name myManagedCluster \
        --enable-image-cleaner \
        --generate-ssh-keys
    

既存のクラスターで Image Cleaner を有効にする

  • az aks update コマンドを使用して、既存の AKS クラスターで Image Cleaner を有効にします。

    az aks update \
      --resource-group myResourceGroup \
      --name myManagedCluster \
      --enable-image-cleaner
    

新規または既存のクラスターで Image Cleaner の間隔を更新する

  • --image-cleaner-interval-hours パラメーターを使用して、新規または既存の AKS クラスターの Image Cleaner の間隔を更新します。

    # Create a new cluster with specifying the interval
    az aks create \
        --resource-group myResourceGroup \
        --name myManagedCluster \
        --enable-image-cleaner \
        --image-cleaner-interval-hours 48 \
        --generate-ssh-keys
    
    # Update the interval on an existing cluster
    az aks update \
        --resource-group myResourceGroup \
        --name myManagedCluster \
        --enable-image-cleaner \
        --image-cleaner-interval-hours 48
    

Image Cleaner を使用して画像を手動で削除する

重要

nameimagelist に設定する必要があります。

  • 次の kubectl apply コマンドを使って、イメージを手動で削除します。 この例では、docker.io/library/alpine:3.7.3 イメージが使われていない場合は削除します。

    cat <<EOF | kubectl apply -f -
    apiVersion: eraser.sh/v1
    kind: ImageList
    metadata:
      name: imagelist
    spec:
      images:
        - docker.io/library/alpine:3.7.3
    EOF
    

手動クリーンアップは 1 回限りの操作であり、新しい imagelist が作成されるか、既存の imagelist に変更が加えられた場合にのみトリガーされます。 イメージが削除された後、imagelist は自動的には削除されません。

別の手動クリーンアップをトリガーする必要がある場合は、新しい imagelist を作成するか、既存のものを変更する必要があります。 同じイメージを再度削除する場合は、新しい imagelist を作成する必要があります。

既存の ImageList を削除し、新しいものを作成する

  1. kubectl delete コマンドを使って古い imagelist を削除します。

    kubectl delete ImageList imagelist
    
  2. 同じイメージ名で新しい imagelist を作成します。 次の例では、前の例と同じイメージを使います。

    cat <<EOF | kubectl apply -f -
    apiVersion: eraser.sh/v1
    kind: ImageList
    metadata:
      name: imagelist
    spec:
      images:
        - docker.io/library/alpine:3.7.3
    EOF
    

既存の ImageList を変更する

  • kubectl edit コマンドを使って既存の imagelist を変更します。

    kubectl edit ImageList imagelist
    
    # Add a new image to the list
    apiVersion: eraser.sh/v1
    kind: ImageList
    metadata:
      name: imagelist
    spec:
      images:
          docker.io/library/python:alpine3.18
    

手動モードを使う場合、eraser-aks-xxxxx ポッドは作業完了後 10 分以内に削除されます。

イメージ除外リスト

除外リストで指定されたイメージは、クラスターから削除されません。 Image Cleaner では、システムとユーザー定義の除外リストがサポートされます。 システム除外リストの編集はサポートされていません。

システム除外リストを確認する

  • 次の kubectl get のコマンドを使用して、システム除外リストを確認します。

    kubectl get -n kube-system configmap eraser-system-exclusion -o yaml
    

ユーザー定義の除外リストを作成する

  1. 除外されたイメージを含むサンプル JSON ファイルを作成します。

    cat > sample.json <<EOF
    {"excluded": ["excluded-image-name"]}
    EOF
    
  2. 次の kubectl create コマンドと kubectl label コマンドを使用して、サンプル JSON ファイルを使用して configmap を作成します。

    kubectl create configmap excluded --from-file=sample.json --namespace=kube-system
    kubectl label configmap excluded eraser.sh/exclude.list=true -n kube-system
    

Image Cleaner を無効にする

  • --disable-image-cleaner パラメーターを指定して az aks update コマンドを使用して、新しい AKS クラスターで Image Cleaner を無効にします。

    az aks update \
      --resource-group myResourceGroup \
      --name myManagedCluster \
      --disable-image-cleaner
    

よく寄せられる質問

イメージ クリーナーが使っているバージョンを確認するにはどうすればよいですか?

kubectl describe configmap -n kube-system eraser-manager-config | grep tag -C 3

Image Cleaner では、trivy スキャナー以外の脆弱性スキャナーもサポートされていますか?

不正解です。

イメージをクリーンアップする脆弱性レベルを指定できますか?

いいえ。 脆弱性レベルの既定の設定は次のとおりです。

  • LOW,
  • MEDIUM,
  • HIGH、および
  • CRITICAL

既定の設定をカスタマイズすることはできません。

Image Cleaner によってクリーンアップされたイメージを確認する方法は?

イメージ ログは、eraser-aks-xxxxx ワーカー ポッドに格納されます。 eraser-aks-xxxxx が有効な場合、次のコマンドを実行して削除ログを表示できます。

kubectl logs -n kube-system <worker-pod-name> -c collector
kubectl logs -n kube-system <worker-pod-name> -c trivy-scanner
kubectl logs -n kube-system <worker-pod-name> -c remover

eraser-aks-xxxxx ポッドは作業完了後 10 分以内に削除されます。 以下の手順に従って、Azure Monitor アドオンを有効にし、コンテナーの分析情報ポッド ログ テーブルを使用できます。 その後、履歴ログが保存され、eraser-aks-xxxxx が削除されてもそれらを確認できます。

  1. クラスターで Azure Monitoring が有効になっていることを確認します。 詳細な手順については、「AKS クラスターの Container Insights を有効にする」を参照してください。

  2. az aks show コマンドを使用して Log Analytics リソース ID を取得します。

      az aks show --resource-group myResourceGroup --name myManagedCluster
    

    数分後、コマンドによって、ワークスペース リソース ID を含むソリューションに関する情報が JSON 形式で返されます:

    "addonProfiles": {
      "omsagent": {
        "config": {
          "logAnalyticsWorkspaceResourceID": "/subscriptions/<WorkspaceSubscription>/resourceGroups/<DefaultWorkspaceRG>/providers/Microsoft.OperationalInsights/workspaces/<defaultWorkspaceName>"
        },
        "enabled": true
      }
    }
    
  3. Azure portal で、ワークスペース リソース ID を検索し、[ログ] を選択します。

  4. 次のクエリをテーブルにコピーし、nameeraser-aks-xxxxx (ワーカー ポッド名) に置き換えます。

    let startTimestamp = ago(1h);
    KubePodInventory
    | where TimeGenerated > startTimestamp
    | project ContainerID, PodName=Name, Namespace
    | where PodName contains "name" and Namespace startswith "kube-system"
    | distinct ContainerID, PodName
    | join
    (
        ContainerLog
        | where TimeGenerated > startTimestamp
    )
    on ContainerID
    // at this point before the next pipe, columns from both tables are available to be "projected". Due to both
    // tables having a "Name" column, we assign an alias as PodName to one column which we actually want
    | project TimeGenerated, PodName, LogEntry, LogEntrySource
    | summarize by TimeGenerated, LogEntry
    | order by TimeGenerated desc
    
  5. [実行] を選択します。 削除されたイメージのログは、[結果] 領域に表示されます。