Image Cleaner를 사용하여 AKS(Azure Kubernetes Service) 클러스터에서 취약한 부실 이미지를 정리합니다.

적용 대상: ✔️ AKS 자동 ✔️ AKS 표준

파이프라인을 사용하여 AKS(Azure Kubernetes Service) 클러스터에서 이미지를 빌드하고 배포하는 것이 일반적입니다. 이미지 생성에 적합하지만 이 프로세스는 남아 있는 부실 이미지를 고려하지 않는 경우가 많으며 클러스터 노드에서 이미지 비대화를 초래할 수 있습니다. 이러한 이미지에는 보안 문제를 일으킬 수 있는 취약성이 포함되어 있을 수 있습니다. 클러스터의 보안 위험을 제거하려면 참조되지 않은 이미지를 정리하면 됩니다. 이미지를 수동으로 정리하는 데는 시간이 많이 걸릴 수 있습니다. Image Cleaner는 자동 이미지 식별 및 제거를 수행하여 부실한 이미지의 위험을 완화하고 이미지 정리에 필요한 시간을 줄여줍니다.

AKS 자동은 대부분의 AKS 워크로드에 권장되는 프로덕션 준비 기본값입니다. Image Cleaner는 AKS 자동 클러스터에 미리 구성되어 기본적으로 취약성이 있는 사용되지 않는 이미지를 제거할 수 있습니다.

AKS 표준 클러스터에서 Image Cleaner는 선택 사항이며 명시적으로 사용하도록 설정합니다.

AKS Automatic에 대한 자세한 내용은 Azure Kubernetes Service(AKS) Automatic이란?

참고

Image Cleaner는 지우개를 기반으로 하는 기능입니다. AKS에서 기능 이름과 속성 이름은 Image Cleaner이며, 관련 Image Cleaner Pod의 이름에는 Eraser이 포함됩니다.

AKS 자동 및 AKS 표준 동작

필수 구성 요소

  • Azure 구독 Azure 구독이 없는 경우 체험 계정을 만들 수 있습니다.
  • Azure CLI를 통한 AKS 표준 구성의 경우 Azure CLI 버전 2.49.0 이상. az --version를 실행하여 버전을 찾습니다. 설치 또는 업그레이드해야 하는 경우 Azure CLI 설치를 참조하세요.

제한 사항

Image Cleaner는 아직 Windows 노드 풀 또는 AKS 가상 노드를 지원하지 않습니다.

Image Cleaner 작동 방식

클러스터에서 Image Cleaner를 활성화하면 라는 eraser-controller-manager컨트롤러 관리자 Pod가 배포됩니다.

ImageCleaner의 워크플로를 보여주는 다이어그램 스크린샷. 클러스터에서 실행되는 ImageCleaner Pod는 ImageList를 생성하거나 수동 입력을 제공할 수 있습니다.

Image Cleaner는 자동 및 수동 정리 모드를 지원합니다.

AKS 표준에 대한 구성 옵션

AKS Standard에서 Azure CLI 이미지 클리너를 구성할 때 이러한 옵션을 사용합니다.

Name 설명 필수
--enable-image-cleaner AKS 클러스터에 대해 이미지 클리너 사용 예, 사용 안 함을 지정하지 않는 한
--disable-image-cleaner AKS 클러스터에 대해 이미지 클리너 사용 안 함 예, 'enable'을 지정하는 경우를 제외하고는 그렇습니다.
--image-cleaner-interval-hours 예약된 실행에 대한 시간 간격입니다. Azure CLI 기본값은 1주일입니다. 최소 시간은 24시간입니다. 최대값은 3개월입니다. ARM 템플릿 또는 다른 클라이언트에 필요한 Azure CLI; 에 필요하지 않음

참고

이미지 클리너를 사용하지 않도록 설정하고 나중에 명시적으로 구성을 전달하지 않고 다시 활성화하면 이전 구성 값이 다시 사용됩니다.

자동 모드

배포 eraser-controller-manager할 때 Image Cleaner는 다음 작업을 자동으로 수행합니다.

  • 정리를 시작하고 각 노드에 대해 eraser-aks-xxxxx 워커 Pod를 생성합니다.
  • 사용되지 않는 이미지를 수집하기 위해 collector 컨테이너를 사용합니다.
  • trivy 스캐너 컨테이너를 사용하여 trivy로 취약성을 검사합니다.
  • 제거기 컨테이너를 사용하여 취약성이 있는 사용되지 않는 이미지를 제거합니다.
  • 완료 후 작업자 Pod를 삭제합니다.
  • --image-cleaner-interval-hours에 따라 다음 정리 작업을 예약합니다.

수동 모드

CRD 개체, ImageList를 정의하여 정리를 수동으로 트리거할 수 있습니다. 그러면 eraser-contoller-manager가 트리거되어 각 노드에 대해 eraser-aks-xxxxx 작업자 Pod를 만들고 수동 제거 프로세스를 완료합니다.

참고

Image Cleaner를 사용하지 않도록 설정한 후에도 이전 구성은 계속 존재합니다. 즉, 구성을 명시적으로 전달하지 않고 기능을 다시 사용하도록 설정하면 기본값 대신 기존 값이 사용됩니다.

AKS 자동 및 AKS 표준에서 이미지 클리너 사용

AKS 자동화

Image Cleaner는 AKS 자동 클러스터에 미리 구성되어 있으며, 이는 대부분의 AKS 워크로드에 권장되는 프로덕션 준비 기본값입니다. 별도의 사용 명령을 실행할 필요가 없습니다.

AKS 자동 클러스터를 만들려면 AKS 자동 클러스터 만들기를 참조하세요.

대상 수정 또는 운영 확인을 원하는 경우 이 문서의 수동 정리 및 모니터링 지침을 사용합니다.

AKS 표준: 새 클러스터에서 사용

az aks create 명령과 --enable-image-cleaner 매개 변수를 사용하여 새 AKS Standard 클러스터에서 Image Cleaner를 사용하도록 설정합니다.

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

AKS 표준: 기존 클러스터에서 사용

az aks update 명령을 사용하여 기존 AKS Standard 클러스터에서 Image Cleaner를 사용 설정합니다.

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

AKS 표준: 새 클러스터 또는 기존 클러스터의 업데이트 간격

매개 변수를 사용하여 새 또는 기존 AKS 표준 클러스터에서 Image Cleaner 간격을 --image-cleaner-interval-hours 업데이트합니다.

# 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

수동 정리는 일회성 작업이며 새 imagelist가 만들어지거나 기존 imagelist가 변경될 때만 트리거됩니다. 이미지가 삭제된 후에도 imagelist는 자동으로 삭제되지 않습니다.

또 다른 수동 정리를 실행해야 하는 경우 새 imagelist를 만들거나 기존 항목을 변경해야 합니다. 동일한 이미지를 다시 제거하려면 새 imagelist를 만들어야 합니다.

기존 ImageList를 삭제하고 새 ImageList를 만듭니다.

  1. imagelist 명령을 사용하여 이전 kubectl delete를 삭제합니다.

    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 수정

imagelist 명령을 사용하여 기존 kubectl edit를 수정합니다.

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

수동 모드를 사용하는 경우 작업 완료 후 10분 이내에 eraser-aks-xxxxx Pod가 삭제됩니다.

이미지 제외 목록

제외 목록에 지정된 이미지는 클러스터에서 제거되지 않습니다. 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. 다음 configmapkubectl create 명령을 사용하여 샘플 JSON 파일을 사용하여 kubectl label을 만듭니다.

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

AKS 표준에서 이미지 클리너 사용 안 함

--disable-image-cleaner 매개 변수를 사용하여 az aks update 명령으로 AKS Standard 클러스터에서 Image Cleaner를 사용 안 함으로 설정합니다.

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

FAQ(질문과 대답)

AKS 자동에서 이미지 클리너가 기본적으로 사용하도록 설정되어 있나요?

Yes. 이미지 클리너는 AKS 자동 클러스터에서 미리 구성됩니다.

AKS Automatic에서 Image Cleaner를 사용하도록 설정하는 명령을 실행해야 하나요?

아니요. AKS Standard의 경우 활성화 명령을 사용합니다.

Image Cleaner가 어떤 버전을 사용하고 있는지 어떻게 확인할 수 있나요?

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

Image Cleaner는 trivy-scanner 외에 다른 취약성 스캐너를 지원하나요?

아니요.

정리할 이미지의 취약성 수준을 지정할 수 있나요?

아니요. 취약성 수준의 기본 설정은 다음과 같습니다.

  • LOW;
  • MEDIUM;
  • HIGH
  • CRITICAL

기본 설정은 사용자 지정할 수 없습니다.

Image Cleaner로 정리된 이미지를 검토하는 방법은 무엇인가요?

이미지 로그는 eraser-aks-xxxxx 작업자 Pod에 저장됩니다. 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 Pod는 작업 완료 후 10분 이내에 삭제됩니다. 다음 단계에 따라 Azure Monitor 추가 기능을 사용하도록 설정하고 Container Insights Pod 로그 테이블을 사용할 수 있습니다. 그 후에는 기록 로그가 저장되며 eraser-aks-xxxxx가 삭제되어도 검토할 수 있습니다.

  1. 클러스터에서 Azure Monitor 사용하도록 설정되어 있는지 확인합니다. 자세한 단계는 AKS 클러스터에 Container Insights 사용을 참조하세요.

  2. 기본적으로 kube-system 네임스페이스에서 실행 중인 컨테이너의 로그는 수집되지 않습니다. kube-system 구성 맵에서 exclude_namespaces 네임스페이스를 제거하고 구성 맵을 적용하여 이러한 로그의 컬렉션을 사용하도록 설정합니다. 자세한 내용은 컨테이너 인사이트 데이터 수집 구성을 참조하세요.

  3. 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
      }
    }
    
  4. Azure 포털에서 작업 영역 리소스 ID를 검색한 다음 로그 선택합니다.

  5. 다음 쿼리 중 하나를 복사하여 쿼리 창에 붙여넣습니다.

    • 클러스터가 ContainerLogV2 스키마를 사용하는 경우 다음 쿼리를 사용합니다. 계속 사용 ContainerLog중인 경우 ContainerLogV2로 업그레이드합니다.

      ContainerLogV2
      | where PodName startswith "eraser-aks-" and PodNamespace == "kube-system"
      | project TimeGenerated, PodName, LogMessage, LogSource
      
    • 계속 사용 ContainerLog하려면 다음 쿼리를 대신 사용합니다.

      let startTimestamp = ago(1h);
      KubePodInventory
      | where TimeGenerated > startTimestamp
      | project ContainerID, PodName=Name, Namespace
      | where PodName startswith "eraser-aks-" and Namespace == "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
       ```
      
      
  6. 실행을 선택합니다. 삭제된 이미지 로그는 모두 결과 영역에 표시됩니다.