监视 GitOps (Flux v2) 状态与活动

若要在已启用 Azure Arc 的 Kubernetes 群集或 Azure Kubernetes 服务 (AKS) 群集中监视与 Flux v2 的 GitOps 相关的状态和活动,有多种选择:

本主题介绍了监视 Flux 活动和状态的一些方法。

在 Azure 门户中监视 Flux 配置

在群集上创建 Flux 配置后,可以通过导航到群集并选择 GitOps 在 Azure 门户中查看状态信息。

查看有关群集符合性和对象的详细信息

符合性状态显示群集的当前状态是否与所需状态匹配。 可能的值:

  • 符合:群集的状态与所需状态匹配。
  • 挂起:检测到更新的所需状态,但群集上尚未协调该状态。
  • 不符合:当前状态与所需状态不匹配。

Azure 门户中群集合规性和其他值的屏幕截图。

若要帮助调试群集的协调问题,请选择“配置对象”。 在这里,可以查看 Flux 为每个 Flux 配置创建的每个配置对象的日志。 选择对象名称以查看其日志。

显示配置对象的详细条件的屏幕截图。

若要查看因应用 Flux 配置而创建的 Kubernetes 对象,请在群集服务菜单的“Kubernetes 资源”部分中选择“工作负载”。 在这里,可以查看群集上已创建的任何资源的所有详细信息。

默认情况下,可以按命名空间和服务名称进行筛选。 还可以添加可能在应用程序中使用的任何标签筛选器,以帮助缩小搜索范围。

查看 Flux 配置状态和详细信息

对于每个 Flux 配置,“状态”列指示是否已在群集上成功创建 Flux 配置对象。

选择任意 Flux 配置即可查看其概述页面,其中包括以下信息:

  • 上次同步的源提交 ID
  • 最新源更新的时间戳
  • 状态更新时间戳(指示何时获取最新统计信息)
  • 存储库 URL 和分支
  • 查看不同 kustomization 的链接

Azure 门户中 Flux 配置的“概览”页的屏幕截图。

使用仪表板监视 GitOps 状态和活动

我们提供仪表板来帮助你使用 Flux v2 监控 GitOps 的状态、符合性、资源消耗和协调活动。 可以将这些 JSON 仪表板导入 Grafana,以帮助实时查看和分析数据。 还可以为此信息设置警报。

要导入和使用这些仪表板,需要:

  • 一个或多个已启用 Arc 的现有 Kubernetes 群集或 AKS 群集。
  • 安装在群集上的 microsoft.flux 扩展
  • 在群集上至少创建了一个 Flux 配置

监视部署和符合性状态

按照以下步骤导入仪表板,以便跨群集监视 Flux 扩展部署和状态,以及这些群集上 Flux 配置的符合性状态。

注意

这些步骤介绍了将仪表板导入 Azure 托管 Grafana 的过程。 还可以将此仪表板导入任何 Grafana 实例。 使用此选项时,必须使用服务主体;Azure 托管 Grafana 外部的数据连接不支持托管标识。

  1. 使用 Azure 门户Azure CLI 创建 Azure 托管 Grafana 实例。 通过在“概述”页上选择 Grafana 终结点,确保能够访问 Grafana。 至少需要“Grafana 编辑”级别权限才能查看和编辑仪表板。 可以通过转到 Grafana 实例上的访问控制 (IAM) 来检查访问权限。

  2. 如果使用 Azure 托管 Grafana 实例的托管标识,请按照以下步骤在你创建 Azure 托管 Grafana 实例的订阅上为其分配“监视读者”角色:

    1. 在 Azure 门户中,导航到要添加的订阅。
    2. 选择“访问控制(IAM)”。
    3. 选择“添加角色分配”。
    4. 选择“监视读者”角色,然后选择“下一步”。
    5. 在“成员”选项卡上,选择“托管标识”,然后选择“选择成员”。
    6. 从托管标识列表中,选择订阅,然后选择 Azure 托管 Grafana 和 Azure 托管 Grafana 实例的名称。
    7. 选择“查看 + 分配”。

    如果使用的是服务主体,请将“监视读者”角色授予要用于数据源连接的服务主体。 请遵循相同的步骤,但在“成员”选项卡中选择“用户、组或服务主体”,然后选择服务主体。 (如果不使用 Azure 托管 Grafana,则必须使用服务主体进行数据连接访问。)

  3. 在 Azure 托管 Grafana 实例中创建 Azure Monitor 数据源连接。 此连接支持仪表板访问 Azure Resource Graph 数据。

  4. 下载 GitOps Flux - 应用程序部署仪表板

  5. 按照以下步骤将 JSON 仪表板导入 Grafana

导入仪表板后,画面上将显示你正在监视的群集中的信息,其中包含多个提供详细信息的面板。 有关某项的更多详细信息,请选择链接以访问 Azure 门户,可在其中找到有关配置、错误和日志的信息。

Flux 应用程序部署仪表板的屏幕截图。

Flux 扩展部署状态”表列出了部署 Flux 扩展的所有群集,以及当前部署状态。

屏幕截图显示了“应用程序部署”仪表板中的“Flux 扩展部署状态”表。

Flux 配置符合性状态”表列出了在群集上创建的所有 Flux 配置及其符合性状态。 要查看配置对象(如 Helm 版本和自定义)的状态和错误日志,请从“ComplianceState”列中选择“不符合”链接。

屏幕截图显示了“应用程序部署”仪表板中的“Flux 配置符合性状态”表。

Flux 扩展部署计数(按状态)”图表可根据群集的预配状态显示群集计数。

“应用程序部署”仪表板中“Flux 扩展部署(按状态)”饼图的屏幕截图。

Flux 配置的计数(按符合性状态)”图表可根据 Flux 配置相对于源存储库的符合性状态显示 Flux 配置的计数。

“应用程序部署”仪表板中“Flux 配置(按符合性状态)”图表的屏幕截图。

筛选仪表板数据以跟踪应用程序部署

可以在 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”,以便即使群集上只有一个扩展失败时也能接收警报。 将此标记为“警报条件”。

    屏幕截图显示了警报创建过程。

  6. 指定警报计算间隔:

    • 对于“条件”,请选择要触发警报规则的查询或表达式。
    • 对于“计算每个”,请输入 10 秒的倍数作为计算频率。
    • 对于“计算对象”,指定创建警报之前条件必须为 true 的时长。
    • 在“配置无数据和错误处理”中,指示当警报规则未返回任何数据或返回错误时应发生的情况。
    • 要检查运行查询的结果,请选择“预览”。
  7. 添加存储位置、规则组以及要与规则关联的任何其他元数据。

    • 对于“文件夹”,请选择应存储规则的文件夹。
    • 对于“”,指定预定义的组。
    • 如果需要,请添加说明和摘要以自定义警报消息。
    • 根据需要添加 Runbook URL、面板、仪表板和警报 ID。
  8. 如果需要,请添加任何自定义标签。 再选择“保存” 。

还可以为警报配置联系点和通知策略

监视资源消耗和协调情况

按照以下步骤导入仪表板,以便监视 Flux 资源消耗、协调、API 请求和协调器状态。

  1. 按照步骤创建 Azure Monitor 工作区

  2. 使用 Azure 门户Azure CLI 创建 Azure 托管 Grafana 实例。

  3. 在要监视的 AKS 群集和/或已启用 Arc 的 Kubernetes 群集上启用 Prometheus 指标收集。

  4. 通过创建 configmap 将 Azure Monitor 代理配置为抓取 Azure 托管 Flux 指标:

    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 工作区链接到托管 Grafana 实例。 此过程需要几分钟才能完成。

  7. 按照步骤将这些 JSON 仪表板导入 Grafana

导入仪表板后,它们将会显示你正在监视的群集中的信息。 要仅显示特定群集或命名空间的信息,请使用每个仪表板顶部附近的筛选器。

Flux 控制平面仪表板可显示有关资源消耗状态、群集级别的协调和 Kubernetes API 请求的详细信息。

Flux 控制平面仪表板的屏幕截图。

Flux 群集统计信息仪表板可显示有关协调器数量的详细信息,以及每个协调器的状态和执行持续时间。

Flux 群集统计信息仪表板的屏幕截图。

创建面向资源消耗和协调问题的警报

按上一部分所述导入仪表板后,可以设置警报。 这些警报会通知你可能需要注意的资源消耗和协调问题。

要启用这些警报,请部署类似于此处所示的 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
          }
        ]
      }
    ]
  }
}

后续步骤