GitOps(Flux v2) 상태 및 활동 모니터링

Azure Arc 지원 Kubernetes 클러스터 또는 Azure Kubernetes Service(AKS) 클러스터에서 Flux v2를 사용하는 GitOps와 관련된 상태 및 작업을 모니터링하기 위해 다음과 같은 몇 가지 옵션을 사용할 수 있습니다.

이 주제에서는 Flux 활동 및 상태를 모니터링할 수 있는 몇 가지 방법을 설명합니다.

Azure Portal에서 Flux 구성 모니터링

클러스터에서 Flux 구성을 만든 후에는 클러스터로 이동하고 GitOps를 선택하여 Azure Portal에서 상태 정보를 볼 수 있습니다.

클러스터 규정 준수 및 개체에 대한 세부 정보 보기

규정 준수 상태는 클러스터의 현재 상태가 원하는 상태와 일치하는지 여부를 보여줍니다. 가능한 값:

  • 준수: 클러스터의 상태가 원하는 상태와 일치합니다.
  • 보류 중: 업데이트된 원하는 상태가 검색되었지만 해당 상태는 클러스터에서 아직 조정되지 않았습니다.
  • 비준수: 현재 상태가 원하는 상태와 일치하지 않습니다.

Screenshot of cluster compliance and other values in the Azure portal.

클러스터의 조정 문제를 디버그하려면 구성 개체를 선택합니다. 여기서는 Flux가 각 Flux 구성에 대해 만드는 각 구성 개체의 로그를 볼 수 있습니다. 로그를 보려는 개체 이름을 선택합니다.

Screenshot showing detailed conditions for a configuration object.

Flux 구성이 적용된 결과로 만들어진 Kubernetes 개체를 보려면 클러스터 왼쪽에 있는 탐색 창의 Kubernetes 리소스 섹션에서 워크로드를 선택합니다. 여기서는 클러스터에 만들어진 모든 리소스의 세부 정보를 볼 수 있습니다.

기본적으로 네임스페이스 및 서비스 이름으로 필터링할 수 있습니다. 애플리케이션에서 사용할 수 있는 레이블 필터를 추가하여 검색 범위를 좁힐 수도 있습니다.

Flux 구성 상태 및 세부 정보 보기

각 Flux 구성의 상태 열은 Flux 구성 개체가 클러스터에 성공적으로 만들어졌는지 여부를 나타냅니다.

원하는 Flux 구성을 선택하면 다음 정보를 비롯한 개요 페이지가 표시됩니다.

  • 마지막 동기화의 원본 커밋 ID
  • 최신 원본 업데이트의 타임스탬프
  • 상태 업데이트 타임스탬프(최신 통계를 얻은 시간 표시)
  • 리포지토리 URL 및 분기
  • 다양한 kustomization을 볼 수 있는 링크

Screenshot of the Overview page of a Flux configuration in the Azure portal.

대시보드를 사용하여 GitOps 상태 및 활동 모니터링

Flux v2에서 GitOps의 상태, 규정 준수, 리소스 소비 및 조정 활동을 모니터링할 수 있는 대시보드가 제공됩니다. 이러한 JSON 대시보드를 Grafana로 가져와 데이터를 실시간으로 살펴보고 분석할 수 있습니다. 이 정보에 대한 알림을 설정할 수도 있습니다.

이러한 대시보드를 가져오고 사용하려면 다음이 필요합니다.

  • 하나 이상의 기존 Arc 지원 Kubernetes 클러스터 또는 AKS 클러스터
  • 클러스터에 설치된 microsoft.flux 확장
  • 클러스터에 만들어진 하나 이상의 Flux 구성

배포 및 규정 준수 상태 모니터링

다음 단계에 따라 클러스터의 Flux 확장 배포 및 상태를 모니터링하고 해당 클러스터의 Flux 구성 규정 준수 상태를 모니터링할 수 있는 대시보드를 가져옵니다.

참고 항목

이러한 단계에서는 대시보드를 Azure Managed Grafana로 가져오는 프로세스를 설명합니다. 이 대시보드를 Grafana 인스턴스로 가져올 수도 있습니다. 이 옵션을 선택하는 경우 서비스 주체를 사용해야 합니다. 관리 ID는 Azure Managed Grafana 외부의 데이터 연결을 지원하지 않습니다.

  1. Azure portal 또는 Azure CLI를 사용하여 Azure Managed Grafana 인스턴스를 만듭니다. 개요 페이지에서 해당 엔드포인트를 선택하여 Grafana에 액세스할 수 있는지 확인합니다. 대시보드를 살펴보고 편집하려면 적어도 Grafana 편집자 수준 권한이 필요합니다. Grafana 인스턴스에서 액세스 제어(IAM)로 이동하여 액세스 권한을 확인할 수 있습니다.

  2. Azure Managed Grafana 인스턴스에 관리 ID를 사용하는 경우 다음 단계에 따라 구독에서 관리 ID에 모니터링 읽기 권한자 역할을 할당합니다.

    1. Azure Portal에서 추가하려는 구독으로 이동합니다.
    2. 액세스 제어(IAM) 를 선택합니다.
    3. 역할 할당 추가를 선택합니다.
    4. 모니터링 읽기 권한자 역할을 선택하고 다음을 선택합니다.
    5. 멤버 탭에서 관리 ID를 선택하고 멤버 선택을 선택합니다.
    6. 관리 ID 목록에서 Azure Managed Grafana 인스턴스를 만든 구독을 선택합니다. Azure Managed Grafana를 선택하고 Azure Managed Grafana 인스턴스의 이름을 선택합니다.
    7. 검토 + 할당을 선택합니다.

    서비스 주체를 사용하는 경우 데이터 원본 연결에 사용할 서비스 주체에 모니터링 읽기 권한자 역할을 부여합니다. 동일한 단계를 수행하되, 멤버 탭에서 사용자, 그룹 또는 서비스 주체를 선택한 다음, 해당하는 서비스 주체를 선택합니다. (Azure Managed Grafana를 사용하지 않는 경우 데이터 연결 액세스에 서비스 주체를 사용해야 합니다.)

  3. Azure Managed Grafana 인스턴스에서 Azure Monitor 데이터 원본 연결을 만듭니다. 이 연결을 통해 대시보드가 Azure Resource Graph 데이터에 액세스할 수 있습니다.

  4. GitOps Flux - 애플리케이션 배포 대시보드를 다운로드합니다.

  5. JSON 대시보드를 Grafana로 가져오는 단계를 수행합니다.

대시보드를 가져온 후에는 모니터링하는 클러스터의 정보와 세부 정보를 제공하는 여러 패널이 대시보드에 표시됩니다. 항목에 대한 자세한 내용을 보려면 링크를 선택하여 Azure Portal을 방문합니다. 구성, 오류 및 로그에 대한 자세한 정보를 확인할 수 있습니다.

Screenshot of the Flux Application Deployments Dashboard.

Flux 확장 배포 상태 표에는 Flux 확장이 배포된 모든 클러스터와 현재 배포 상태가 표시됩니다.

Screenshot showing the Flux Extension Deployments Status table in the Application Deployments dashboard.

Flux 구성 규정 준수 상태 표에는 클러스터에서 만든 모든 Flux 구성과 규정 준수 상태가 표시됩니다. Helm 릴리스 및 kustomization과 같은 구성 개체의 상태 및 오류 로그를 보려면 ComplianceState 열에서 비준수 링크를 선택합니다.

Screenshot showing the Flux Configuration Compliance Status table in the Application Deployments dashboard.

상태별 Flux 확장 배포 수 차트에는 프로비전 상태별 클러스터 수가 표시됩니다.

Screenshot of the Flux Extension Deployments by Status pie chart in the Application Deployments dashboard.

규정 준수 상태별 Flux 구성 수 차트에는 원본 리포지토리와 관련하여 규정 준수 상태별 Flux 구성 수가 표시됩니다.

Screenshot of the Flux Configuration by Compliance Status chart on the Application Deployments dashboard.

대시보드 데이터를 필터링하여 애플리케이션 배포 추적

GitOps Flux - 애플리케이션 배포 대시보드에서 데이터를 필터링하여 표시되는 정보를 변경할 수 있습니다. 예를 들어 특정 구독 또는 리소스 그룹에 대한 데이터만 표시할 수도 있고, 데이터를 특정 클러스터로 제한할 수도 있습니다. 이렇게 하려면 최상위 드롭다운 또는 표의 열 머리글에서 필터 옵션을 선택합니다.

예를 들어 Flux 구성 규정 준수 상태 표의 SourceLastSyncCommit 열에서 특정 커밋을 선택할 수 있습니다. 그러면 해당 커밋의 영향을 받는 모든 클러스터에 배포된 구성 상태를 추적할 수 있습니다.

확장 및 구성 실패에 대한 경고 만들기

이전 섹션에서 설명한 대로 대시보드를 가져온 후에는 경고를 설정할 수 있습니다. 이러한 경고는 Flux 확장 또는 Flux 구성에 오류가 있을 때 알려줍니다.

아래 단계에 따라 경고를 만듭니다. 확장 프로비전 또는 확장 업그레이드 실패를 감지하거나 규정 준수 상태 오류를 감지하는 예제 쿼리가 제공됩니다.

  1. 대시보드의 왼쪽 탐색 메뉴에서 경고를 선택합니다.

  2. 경고 규칙을 선택합니다.

  3. + 경고 규칙 만들기를 선택합니다. 새 경고 규칙 페이지가 열리고, Grafana 관리 경고 옵션이 기본적으로 선택되어 있습니다.

  4. 규칙 이름에 구체적인 이름을 추가합니다. 이 이름은 경고 규칙 목록에 표시되며, 이 규칙에서 만드는 모든 경고 인스턴스의 alertname 레이블로 사용됩니다.

  5. 쿼리 및 경고 조건 설정에서 다음을 수행합니다.

    • 데이터 원본 선택. 대시보드에 사용되는 동일한 데이터 원본을 여기에 사용할 수 있습니다.

    • 서비스에서는 Azure Resource Graph를 선택합니다.

    • 드롭다운 목록에서 구독을 선택합니다.

    • 사용하려는 쿼리를 입력합니다. 예를 들어 확장 프로비전 또는 업그레이드 실패의 경우 다음 쿼리를 입력할 수 있습니다.

      kubernetesconfigurationresources
      | where type == "microsoft.kubernetesconfiguration/extensions"
      | extend provisioningState = tostring(properties.ProvisioningState)
      | where provisioningState == "Failed"
      | summarize count() by provisioningState
      

      또는 규정 준수 상태 오류의 경우 다음 쿼리를 입력할 수 있습니다.

      kubernetesconfigurationresources
      | where type == "microsoft.kubernetesconfiguration/fluxconfigurations"
      | extend complianceState=tostring(properties.complianceState)
      | where complianceState == "Non-Compliant"
      | summarize count() by complianceState
      
    • 임계값 입력란에서는 입력 유형으로 A를 선택하고, 클러스터에서 확장이 하나만 실패하더라도 경고를 수신하도록 임계값을 0으로 설정합니다. 이를 경고 조건으로 표시합니다.

    Screenshot showing the alert creation process.

  6. 다음과 같이 경고 평가 간격을 지정합니다.

    • 조건에서는 경고 규칙을 트리거하는 쿼리 또는 식을 선택합니다.
    • 평가 빈도에서는 평가 빈도를 10초의 배수로 입력합니다.
    • 평가 기간에서는 조건이 얼마나 오래 true여야 경고가 생성되는지 그 기간을 지정합니다.
    • 데이터 없음 및 오류 처리 구성에서는 경고 규칙이 데이터를 반환하지 않거나 오류를 반환할 때 무엇을 해야 하는지 지정합니다.
    • 쿼리 실행 결과를 확인하려면 미리 보기를 선택합니다.
  7. 스토리지 위치, 규칙 그룹 및 규칙과 연결하려는 추가 메타데이터를 추가합니다.

    • 폴더에서는 규칙을 저장할 폴더를 선택합니다.
    • 그룹에서는 미리 정의된 그룹을 지정합니다.
    • 원한다면 설명 및 요약을 추가하여 경고 메시지를 사용자 지정합니다.
    • Runbook URL, 패널, 대시보드 및 경고 ID를 필요한 대로 추가합니다.
  8. 원한다면 사용자 지정 레이블을 추가합니다. 그런 다음 저장을 선택합니다.

연락처를 구성하고 경고에 대한 알림 정책을 구성할 수도 있습니다.

리소스 사용 및 조정 모니터링

다음 단계에 따라 Flux 리소스 사용, 조정, API 요청 및 조정자 상태를 모니터링할 수 있는 대시보드를 가져옵니다.

  1. Azure Monitor 작업 영역 만들기 단계를 수행합니다.

  2. Azure portal 또는 Azure CLI를 사용하여 Azure Managed Grafana 인스턴스를 만듭니다.

  3. 모니터링하려는 AKS 클러스터 및/또는 Arc 지원 Kubernetes 클러스터에서 Prometheus 메트릭 컬렉션을 사용하도록 설정합니다.

  4. configmap을 만들어서 Azure Managed Flux 메트릭을 스크래핑하도록 Azure Monitor 에이전트를 구성합니다.

    kind: ConfigMap
    apiVersion: v1
    data:
      schema-version:
          #string.used by agent to parse config. supported versions are {v1}. Configs with other schema versions will be rejected by the agent.
        v1
      config-version:
        #string.used by customer to keep track of this config file's version in their source control/repository (max allowed 10 chars, other chars will be truncated)
        ver1
      default-scrape-settings-enabled: |-
        kubelet = true
        coredns = false
        cadvisor = true
        kubeproxy = false
        apiserver = false
        kubestate = true
        nodeexporter = true
        windowsexporter = false
        windowskubeproxy = false
        kappiebasic = true
        prometheuscollectorhealth = false
      # Regex for which namespaces to scrape through pod annotation based scraping.
      # This is none by default. Use '.*' to scrape all namespaces of annotated pods.
      pod-annotation-based-scraping: |-
        podannotationnamespaceregex = "flux-system"
      default-targets-scrape-interval-settings: |-
        kubelet = "30s"
        coredns = "30s"
        cadvisor = "30s"
        kubeproxy = "30s"
        apiserver = "30s"
        kubestate = "30s"
        nodeexporter = "30s"
        windowsexporter = "30s"
        windowskubeproxy = "30s"
        kappiebasic = "30s"
        prometheuscollectorhealth = "30s"
        podannotations = "30s"
    metadata:
      name: ama-metrics-settings-configmap
      namespace: kube-system
    
  5. Flux 컨트롤 플레인Flux 클러스터 통계 대시보드를 다운로드합니다.

  6. 관리되는 Prometheus 작업 영역을 Managed Grafana 인스턴스에 연결합니다. 이 작업은 완료하는 데 몇 분이 소요됩니다.

  7. JSON 대시보드를 Grafana로 가져오는 단계를 수행합니다.

대시보드를 가져온 후에는 모니터링하는 클러스터의 정보가 대시보드에 표시됩니다. 특정 클러스터 또는 네임스페이스에 대한 정보만 표시하려면 각 대시보드의 상단에 있는 필터를 사용합니다.

Flux 컨트롤 플레인 대시보드에는 상태, 리소스 사용, 클러스터 수준의 조정 및 Kubernetes API 요청에 대한 세부 정보가 표시됩니다.

Screenshot of the Flux Control Plane dashboard.

Flux 클러스터 통계 대시보드에는 각 조정자의 상태 및 실행 기간과 함께 조정자 수에 대한 세부 정보가 표시됩니다.

Screenshot of the Flux Cluster Stats dashboard.

리소스 사용 및 조정 문제에 대한 경고 만들기

이전 섹션에서 설명한 대로 대시보드를 가져온 후에는 경고를 설정할 수 있습니다. 이러한 경고는 주의가 필요할 수 있는 리소스 사용 및 조정 문제를 알립니다.

이러한 경고를 사용하도록 설정하려면 다음과 유사한 Bicep 템플릿을 배포합니다. 이 템플릿의 경고 규칙은 필요한 대로 수정할 수 있는 샘플입니다.

Bicep 템플릿을 다운로드하여 변경한 후에는 다음 단계에 따라 템플릿 배포합니다.

param azureMonitorWorkspaceName string
param alertReceiverEmailAddress string

param kustomizationLookbackPeriodInMinutes int = 5
param helmReleaseLookbackPeriodInMinutes int = 5
param gitRepositoryLookbackPeriodInMinutes int = 5
param bucketLookbackPeriodInMinutes int = 5
param helmRepoLookbackPeriodInMinutes int = 5
param timeToResolveAlerts string = 'PT10M'
param location string = resourceGroup().location

resource azureMonitorWorkspace 'Microsoft.Monitor/accounts@2023-04-03' = {
  name: azureMonitorWorkspaceName
  location: location
}

resource fluxRuleActionGroup 'Microsoft.Insights/actionGroups@2023-01-01' = {
  name: 'fluxRuleActionGroup'
  location: 'global'
  properties: {
    enabled: true
    groupShortName: 'fluxGroup'
    emailReceivers: [
      {
        name: 'emailReceiver'
        emailAddress: alertReceiverEmailAddress
      }
    ]
  }
}

resource fluxRuleGroup 'Microsoft.AlertsManagement/prometheusRuleGroups@2023-03-01' = {
  name: 'fluxRuleGroup'
  location: location
  properties: {
    description: 'Flux Prometheus Rule Group'
    scopes: [
      azureMonitorWorkspace.id
    ]
    enabled: true
    interval: 'PT1M'
    rules: [
      {
        alert: 'KustomizationNotReady'
        expression: 'sum by (cluster, namespace, name) (gotk_reconcile_condition{type="Ready", status="False", kind="Kustomization"}) > 0'
        for: 'PT${kustomizationLookbackPeriodInMinutes}M'
        labels: {
          description: 'Kustomization reconciliation failing for last ${kustomizationLookbackPeriodInMinutes} minutes.'
        }
        annotations: {
          description: 'Kustomization reconciliation failing for last ${kustomizationLookbackPeriodInMinutes} minutes.'
        }
        enabled: true
        severity: 3
        resolveConfiguration: {
          autoResolved: true
          timeToResolve: timeToResolveAlerts
        }
        actions: [
          {
            actionGroupId: fluxRuleActionGroup.id
          }
        ]
      }
      {
        alert: 'HelmReleaseNotReady'
        expression: 'sum by (cluster, namespace, name) (gotk_reconcile_condition{type="Ready", status="False", kind="HelmRelease"}) > 0'
        for: 'PT${helmReleaseLookbackPeriodInMinutes}M'
        labels: {
          description: 'HelmRelease reconciliation failing for last ${helmReleaseLookbackPeriodInMinutes} minutes.'
        }
        annotations: {
          description: 'HelmRelease reconciliation failing for last ${helmReleaseLookbackPeriodInMinutes} minutes.'
        }
        enabled: true
        severity: 3
        resolveConfiguration: {
          autoResolved: true
          timeToResolve: timeToResolveAlerts
        }
        actions: [
          {
            actionGroupId: fluxRuleActionGroup.id
          }
        ]
      }
      {
        alert: 'GitRepositoryNotReady'
        expression: 'sum by (cluster, namespace, name) (gotk_reconcile_condition{type="Ready", status="False", kind="GitRepository"}) > 0'
        for: 'PT${gitRepositoryLookbackPeriodInMinutes}M'
        labels: {
          description: 'GitRepository reconciliation failing for last ${gitRepositoryLookbackPeriodInMinutes} minutes.'
        }
        annotations: {
          description: 'GitRepository reconciliation failing for last ${gitRepositoryLookbackPeriodInMinutes} minutes.'
        }
        enabled: true
        severity: 3
        resolveConfiguration: {
          autoResolved: true
          timeToResolve: timeToResolveAlerts
        }
        actions: [
          {
            actionGroupId: fluxRuleActionGroup.id
          }
        ]
      }
      {
        alert: 'BucketNotReady'
        expression: 'sum by (cluster, namespace, name) (gotk_reconcile_condition{type="Ready", status="False", kind="Bucket"}) > 0'
        for: 'PT${bucketLookbackPeriodInMinutes}M'
        labels: {
          description: 'Bucket reconciliation failing for last ${bucketLookbackPeriodInMinutes} minutes.'
        }
        annotations: {
          description: 'Bucket reconciliation failing for last ${bucketLookbackPeriodInMinutes} minutes.'
        }
        enabled: true
        severity: 3
        resolveConfiguration: {
          autoResolved: true
          timeToResolve: timeToResolveAlerts
        }
        actions: [
          {
            actionGroupId: fluxRuleActionGroup.id
          }
        ]
      }
      {
        alert: 'HelmRepositoryNotReady'
        expression: 'sum by (cluster, namespace, name) (gotk_reconcile_condition{type="Ready", status="False", kind="HelmRepository"}) > 0'
        for: 'PT${helmRepoLookbackPeriodInMinutes}M'
        labels: {
          description: 'HelmRepository reconciliation failing for last ${helmRepoLookbackPeriodInMinutes} minutes.'
        }
        annotations: {
          description: 'HelmRepository reconciliation failing for last ${helmRepoLookbackPeriodInMinutes} minutes.'
        }
        enabled: true
        severity: 3
        resolveConfiguration: {
          autoResolved: true
          timeToResolve: timeToResolveAlerts
        }
        actions: [
          {
            actionGroupId: fluxRuleActionGroup.id
          }
        ]
      }
    ]
  }
}

다음 단계