菜单
文档breadcrumb arrow Grafana Alloybreadcrumb arrow 设置breadcrumb arrow 迁移breadcrumb arrow 从 Agent Operator 迁移
开源

从 Grafana Agent Operator 迁移到 Grafana Alloy

您可以从 Grafana Agent Operator 迁移到 Alloy。

  • 监控类型(PodMonitorServiceMonitorProbeScrapeConfigPodLogs)均由 Alloy 原生支持。
  • Grafana Agent Operator 中用于部署 Grafana Agent 的部分,即 GrafanaAgentMetricsInstanceLogsInstance CRD,已被废弃。

使用 Helm 部署 Alloy

  1. 创建一个 values.yaml 文件,其中包含部署 Alloy 的选项。您可以从默认值开始并根据需要进行自定义,或者从以下代码片段开始,这应该是一个不错的起点,它与 Grafana Agent Operator 的功能类似。

    yaml
    alloy:
      configMap:
        create: true
      clustering:
        enabled: true
    controller:
      type: 'statefulset'
      replicas: 2
    crds:
      create: false

    此配置使用内置的集群功能将 Alloy 部署为 StatefulSet,以便在所有 Alloy Pod 之间分配抓取任务。

    这是众多可能的部署模式之一。例如,您可能希望使用 DaemonSet 来收集主机级别的日志或指标。有关不同拓扑的更多详细信息,请参阅 Alloy 的部署指南

  2. 创建一个 Alloy 配置文件 config.alloy

    在下一步中,当您转换 MetricsInstance 时,将添加到此配置中。您可以根据需要向此文件添加任何额外的配置。

  3. 安装 Grafana Helm 仓库

    shell
    helm repo add grafana https://grafana.github.io/helm-charts
    helm repo update
  4. 创建一个 Helm 发布。您可以随意命名该发布。以下命令将在 monitoring 命名空间中安装一个名为 alloy-metrics 的发布。

    shell
    helm upgrade alloy-metrics grafana/alloy -i -n monitoring -f values.yaml --set-file alloy.configMap.content=config.alloy

    此命令使用 --set-file 标志将配置文件作为 Helm 值传递,以便您可以继续将其作为常规 Alloy 配置文件进行编辑。

将 MetricsInstance 转换为 Alloy 组件

MetricsInstance 资源主要定义

  • Grafana Agent 应将指标发送到的远程端点。
  • 此 Alloy 应发现的 PodMonitorServiceMonitorScrapeConfigProbe 资源。

您可以在 Alloy 中使用 prometheus.remote_writeprometheus.operator.podmonitorsprometheus.operator.servicemonitorsprometheus.operator.probes 组件来实现这些功能。

以下 Alloy 语法示例等同于操作员指南中的 MetricsInstance

alloy

// read the credentials secret for remote_write authorization
remote.kubernetes.secret "credentials" {
  namespace = "monitoring"
  name = "primary-credentials-metrics"
}

prometheus.remote_write "primary" {
    endpoint {
        url = "https://<PROMETHEUS_URL>/api/v1/push"
        basic_auth {
            username = convert.nonsensitive(remote.kubernetes.secret.credentials.data["username"])
            password = remote.kubernetes.secret.credentials.data["password"]
        }
    }
}

prometheus.operator.podmonitors "primary" {
    forward_to = [prometheus.remote_write.primary.receiver]
    // leave out selector to find all podmonitors in the entire cluster
    selector {
        match_labels = {instance = "primary"}
    }
}

prometheus.operator.servicemonitors "primary" {
    forward_to = [prometheus.remote_write.primary.receiver]
    // leave out selector to find all servicemonitors in the entire cluster
    selector {
        match_labels = {instance = "primary"}
    }
}

替换以下内容

  • <PROMETHEUS_URL>:您希望将指标发送到的端点。

此配置发现集群中所有匹配标签选择器 instance=primaryPodMonitorServiceMonitorScrapeConfigProbe 资源。然后,它从目标中抓取指标并将它们转发到您的远程写入端点。

如果您在 MetricsInstance 资源中使用了其他功能,您可能需要进一步自定义此配置。有关更多信息,请参阅相关组件的文档:

收集日志

当前建议是创建一个额外的 Alloy DaemonSet 部署来抓取日志。

Alloy 具有可以直接从 Kubernetes API 抓取 Pod 日志的组件,而无需 DaemonSet 部署。这些组件目前仍被视为实验性功能,如果您想尝试,请参阅loki.source.kubernetesloki.source.podlogs 的文档。

这些值与 Grafana Agent Operator 部署日志时使用的值接近

yaml
alloy:
  configMap:
    create: true
  clustering:
    enabled: false
  controller:
    type: 'daemonset'
  mounts:
    # -- Mount /var/log from the host into the container for log collection.
    varlog: true

此命令将在 monitoring 命名空间中安装一个名为 alloy-logs 的发布

shell
helm upgrade alloy-logs grafana/alloy -i -n monitoring -f values-logs.yaml --set-file alloy.configMap.content=config-logs.alloy

这个简单的配置会抓取每个节点上每个 Pod 的日志

alloy
// read the credentials secret for remote_write authorization
remote.kubernetes.secret "credentials" {
  namespace = "monitoring"
  name      = "primary-credentials-logs"
}

discovery.kubernetes "pods" {
  role = "pod"
  // limit to pods on this node to reduce the amount you need to filter
  selectors {
    role  = "pod"
    field = "spec.nodeName=" + sys.env("<HOSTNAME>")
  }
}

discovery.relabel "pod_logs" {
  targets = discovery.kubernetes.pods.targets
  rule {
    source_labels = ["__meta_kubernetes_namespace"]
    target_label  = "namespace"
  }
  rule {
    source_labels = ["__meta_kubernetes_pod_name"]
    target_label  = "pod"
  }
  rule {
    source_labels = ["__meta_kubernetes_pod_container_name"]
    target_label  = "container"
  }
  rule {
    source_labels = ["__meta_kubernetes_namespace", "__meta_kubernetes_pod_name"]
    separator     = "/"
    target_label  = "job"
  }
  rule {
    source_labels = ["__meta_kubernetes_pod_uid", "__meta_kubernetes_pod_container_name"]
    separator     = "/"
    action        = "replace"
    replacement   = "/var/log/pods/*$1/*.log"
    target_label  = "__path__"
  }
  rule {
    action = "replace"
    source_labels = ["__meta_kubernetes_pod_container_id"]
    regex = "^(\\w+):\\/\\/.+$"
    replacement = "$1"
    target_label = "tmp_container_runtime"
  }
}

local.file_match "pod_logs" {
  path_targets = discovery.relabel.pod_logs.output
}

loki.source.file "pod_logs" {
  targets    = local.file_match.pod_logs.targets
  forward_to = [loki.process.pod_logs.receiver]
}

// basic processing to parse the container format. You can add additional processing stages
// to match your application logs.
loki.process "pod_logs" {
  stage.match {
    selector = "{tmp_container_runtime=\"containerd\"}"
    // the cri processing stage extracts the following k/v pairs: log, stream, time, flags
    stage.cri {}
    // Set the extract flags and stream values as labels
    stage.labels {
      values = {
        flags   = "",
        stream  = "",
      }
    }
  }

  // if the label tmp_container_runtime from above is docker parse using docker
  stage.match {
    selector = "{tmp_container_runtime=\"docker\"}"
    // the docker processing stage extracts the following k/v pairs: log, stream, time
    stage.docker {}

    // Set the extract stream value as a label
    stage.labels {
      values = {
        stream  = "",
      }
    }
  }

  // drop the temporary container runtime label as it is no longer needed
  stage.label_drop {
    values = ["tmp_container_runtime"]
  }

  forward_to = [loki.write.loki.receiver]
}

loki.write "loki" {
  endpoint {
    url = "https://<LOKI_URL>/loki/api/v1/push"
    basic_auth {
      username = convert.nonsensitive(remote.kubernetes.secret.credentials.data["username"])
      password = remote.kubernetes.secret.credentials.data["password"]
    }
}
}

替换以下内容

  • <LOKI_URL>:您的 Loki 实例的端点。

日志子系统非常强大,提供了许多处理日志的选项。更多详细信息,请参阅组件文档

集成

Alloy 不支持 Integration CRD。但是,所有 Grafana Agent Static 模式的集成在 prometheus.exporter 命名空间中都有对应的组件。参考文档应该能帮助您将这些集成转换为对应的 Alloy 组件。