Не видно никаких следов от Alloy в Grafana.

Вопрос или проблема

Я пытаюсь использовать Grafana Alloy с включенным Grafana Beyla и надеюсь, что он может отправить некоторые трассы в Grafana Tempo.
С этой настройкой Alloy успешно отправляет логи в Loki. Однако для трасс я не могу видеть никаких трасс в Grafana и также нет Service Graph.

enter image description here

Helm Charts:

Grafana

---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-hm-grafana
  namespace: production-hm-argo-cd
  labels:
    app.kubernetes.io/name: hm-grafana
spec:
  project: production-hm
  sources:
    - repoURL: https://grafana.github.io/helm-charts
      # https://artifacthub.io/packages/helm/grafana/grafana
      targetRevision: 8.8.5
      chart: grafana
      helm:
        releaseName: hm-grafana
        values: |
          # https://github.com/grafana/helm-charts/blob/main/charts/grafana/values.yaml
          ---
          sidecar:
            dashboards:
              enabled: true
              searchNamespace: ALL
          datasources:
            datasources.yaml:
              apiVersion: 1
              datasources:
                - name: hm-prometheus
                  type: prometheus
                  isDefault: true
                  url: http://hm-prometheus-kube-pr-prometheus.production-hm-prometheus:9090
                  access: proxy
                - name: hm-loki
                  type: loki
                  isDefault: false
                  url: http://hm-loki-gateway.production-hm-loki:80
                  access: proxy
                - name: hm-tempo
                  type: tempo
                  isDefault: false
                  url: http://hm-tempo-query-frontend.production-hm-tempo:3100
                  access: proxy
                  # https://grafana.com/docs/grafana/next/datasources/tempo/configure-tempo-data-source/#example-file
                  jsonData:
                    tracesToLogsV2:
                      datasourceUid: 'hm-loki'
                      spanStartTimeShift: '-1h'
                      spanEndTimeShift: '1h'
                      tags: ['job', 'instance', 'pod', 'namespace']
                      filterByTraceID: false
                      filterBySpanID: false
                      customQuery: true
                      query: 'method="$${__span.tags.method}"'
                    tracesToMetrics:
                      datasourceUid: 'hm-prometheus'
                      spanStartTimeShift: '-1h'
                      spanEndTimeShift: '1h'
                      tags: [{ key: 'service.name', value: 'service' }, { key: 'job' }]
                      queries:
                        - name: 'Sample query'
                          query: 'sum(rate(traces_spanmetrics_latency_bucket{$$__tags}[5m]))'
                    serviceMap:
                      datasourceUid: 'hm-prometheus'
                    nodeGraph:
                      enabled: true
                    search:
                      hide: false
                    traceQuery:
                      timeShiftEnabled: true
                      spanStartTimeShift: '-1h'
                      spanEndTimeShift: '1h'
                    spanBar:
                      type: 'Tag'
                      tag: 'http.path'
                    streamingEnabled:
                      search: true
    - repoURL: [email protected]:hongbo-miao/hongbomiao.com.git
      targetRevision: main
      path: kubernetes/argo-cd/applications/production-hm/grafana/kubernetes-manifests
  destination:
    namespace: production-hm-grafana
    server: https://kubernetes.default.svc
  syncPolicy:
    syncOptions:
      - ServerSideApply=true
    automated:
      prune: true

Tempo

---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-hm-tempo
  namespace: production-hm-argo-cd
  labels:
    app.kubernetes.io/name: hm-tempo
spec:
  project: production-hm
  source:
    repoURL: https://grafana.github.io/helm-charts
    # https://artifacthub.io/packages/helm/grafana/tempo-distributed
    targetRevision: 1.31.0
    chart: tempo-distributed
    helm:
      releaseName: hm-tempo
      values: |
        # https://github.com/grafana/helm-charts/blob/main/charts/tempo-distributed/values.yaml
        # https://grafana.com/docs/tempo/latest/setup/operator/object-storage/
        ---
        tempo:
          structuredConfig:
            # https://grafana.com/docs/tempo/latest/traceql/#stream-query-results
            stream_over_http_enabled: true
        gateway:
          enabled: false
        serviceAccount:
          create: true
          name: hm-tempo
          annotations:
            eks.amazonaws.com/role-arn: arn:aws:iam::272394222652:role/TempoRole-hm-tempo
        storage:
          admin:
            backend: s3
            s3:
              endpoint: s3.amazonaws.com
              region: us-west-2
              bucket: production-hm-tempo-admin-bucket
          trace:
            backend: s3
            s3:
              endpoint: s3.amazonaws.com
              region: us-west-2
              bucket: production-hm-tempo-trace-bucket
        traces:
          otlp:
            http:
              enabled: true
            grpc:
              enabled: true
        metricsGenerator:
          enabled: true
          config:
            processor:
              # https://grafana.com/docs/tempo/latest/operations/traceql-metrics/
              local_blocks:
                filter_server_spans: false
            storage:
              remote_write:
                - url: http://hm-prometheus-kube-pr-prometheus.production-hm-prometheus:9090/api/v1/write
        global_overrides:
          metrics_generator_processors:
            - local-blocks
            - service-graphs
            - span-metrics
  destination:
    namespace: production-hm-tempo
    server: https://kubernetes.default.svc
  syncPolicy:
    syncOptions:
      - ServerSideApply=true
    automated:
      prune: true

Alloy

---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-hm-alloy
  namespace: production-hm-argo-cd
  labels:
    app.kubernetes.io/name: hm-alloy
spec:
  project: production-hm
  source:
    repoURL: https://grafana.github.io/helm-charts
    # https://artifacthub.io/packages/helm/grafana/alloy
    targetRevision: 0.11.0
    chart: alloy
    helm:
      releaseName: hm-alloy
      values: |
        # https://github.com/grafana/alloy/blob/main/operations/helm/charts/alloy/values.yaml
        ---
        alloy:
          # For "beyla.ebpf", see https://grafana.com/docs/grafana-cloud/send-data/alloy/reference/components/beyla/beyla.ebpf/
          stabilityLevel: public-preview
          extraEnv:
            - name: LOKI_URL
              value: http://hm-loki-gateway.production-hm-loki:80/loki/api/v1/push
            - name: TEMPO_ENDPOINT
              value: hm-tempo-distributor.production-hm-tempo:4317
          configMap:
            content: |-
              // https://grafana.com/docs/alloy/latest/configure/kubernetes/
              // https://grafana.com/docs/alloy/latest/collect/logs-in-kubernetes/
              logging {
                level = "info"
                format = "logfmt"
              }

              // Loki related config
              // ...

              // https://grafana.com/docs/tempo/latest/configuration/grafana-alloy/automatic-logging/
              // https://grafana.com/docs/tempo/latest/configuration/grafana-alloy/service-graphs/
              // https://grafana.com/docs/tempo/latest/configuration/grafana-alloy/span-metrics/
              // https://grafana.com/blog/2024/05/21/how-to-use-grafana-beyla-in-grafana-alloy-for-ebpf-based-auto-instrumentation/
              beyla.ebpf "default" {
                attributes {
                  kubernetes {
                    enable = "true"
                  }
                }
                discovery {
                  services {
                    exe_path = "http"
                    open_ports = "80"
                  }
                }
                output {
                  traces = [otelcol.processor.batch.default.input]
                }
              }

              otelcol.processor.batch "default" {
                output {
                  metrics = [otelcol.exporter.otlp.hm_tempo.input]
                  logs    = [otelcol.exporter.otlp.hm_tempo.input]
                  traces  = [otelcol.exporter.otlp.hm_tempo.input]
                }
              }

              otelcol.exporter.otlp "hm_tempo" {
                client {
                  endpoint = env("TEMPO_ENDPOINT")
                  tls {
                    insecure = true
                    insecure_skip_verify = true
                  }
                }
              }
  destination:
    namespace: production-hm-alloy
    server: https://kubernetes.default.svc
  syncPolicy:
    syncOptions:
      - ServerSideApply=true
    automated:
      prune: true

График Alloy

Все в порядке:

enter image description here

Логи

Лог одного из pod’ов Alloy

Он длинный, я разместил его на https://gist.github.com/hongbo-miao/23bf9d16435098267184f090d5f45044

Я увидел строку

2025/01/30 08:59:35 ERROR Unable to load eBPF watcher for process events component=discover.ProcessWatcher interval=5s error=”loading and assigning BPF objects: field BeylaKprobeSysBind: program beyla_kprobe_sys_bind: map watch_events: map create: operation not permitted (MEMLOCK may be too low, consider rlimit.RemoveMemlock)”

внутри, однако, я не уверен, как это решить. Я использую Amazon EKS.

Лог pod’а tempo-distributor

level=warn ts=2025-01-30T06:36:10.194320099Z caller=main.go:133 msg="-- CONFIGURATION WARNINGS --"
level=warn ts=2025-01-30T06:36:10.19437038Z caller=main.go:139 msg="Inline, unscoped overrides are deprecated. Please use the new overrides config format."
level=info ts=2025-01-30T06:36:10.197225405Z caller=main.go:121 msg="Starting Tempo" version="(version=v2.7.0, branch=HEAD, revision=b0da6b481)"
level=info ts=2025-01-30T06:36:10.197899194Z caller=server.go:248 msg="server listening on addresses" http=[::]:3100 grpc=[::]:9095
ts=2025-01-30T06:36:10Z level=info msg="OTel Shim Logger Initialized" component=tempo
level=info ts=2025-01-30T06:36:10.413004915Z caller=memberlist_client.go:446 msg="Using memberlist cluster label and node name" cluster_label=hm-tempo.production-hm-tempo node=hm-tempo-distributor-6f579f694c-665x8-51b758e5
level=info ts=2025-01-30T06:36:10.414030557Z caller=module_service.go:82 msg=starting module=internal-server
level=info ts=2025-01-30T06:36:10.414226259Z caller=module_service.go:82 msg=starting module=server
level=info ts=2025-01-30T06:36:10.414342161Z caller=module_service.go:82 msg=starting module=memberlist-kv
level=info ts=2025-01-30T06:36:10.414361461Z caller=module_service.go:82 msg=starting module=overrides
level=info ts=2025-01-30T06:36:10.414402831Z caller=module_service.go:82 msg=starting module=ring
level=info ts=2025-01-30T06:36:10.414436302Z caller=module_service.go:82 msg=starting module=metrics-generator-ring
level=info ts=2025-01-30T06:36:10.414457312Z caller=module_service.go:82 msg=starting module=usage-report
level=warn ts=2025-01-30T06:36:10.414641774Z caller=runtime_config_overrides.go:97 msg="Overrides config type mismatch" err="per-tenant overrides config type does not match static overrides config type" config_type=new static_config_type=legacy
level=error ts=2025-01-30T06:36:10.498151365Z caller=resolver.go:87 msg="failed to lookup IP addresses" host=hm-tempo-gossip-ring err="lookup hm-tempo-gossip-ring on 10.215.0.10:53: no such host"
level=warn ts=2025-01-30T06:36:10.498190246Z caller=resolver.go:134 msg="IP address lookup yielded no results. No host found or no addresses found" host=hm-tempo-gossip-ring
level=info ts=2025-01-30T06:36:10.498203496Z caller=memberlist_client.go:563 msg="memberlist fast-join starting" nodes_found=0 to_join=0
level=warn ts=2025-01-30T06:36:10.498217166Z caller=memberlist_client.go:583 msg="memberlist fast-join finished" joined_nodes=0 elapsed_time=83.858295ms
level=info ts=2025-01-30T06:36:10.498238626Z caller=memberlist_client.go:595 phase=startup msg="joining memberlist cluster" join_members=dns+hm-tempo-gossip-ring:7946
level=info ts=2025-01-30T06:36:10.498317557Z caller=ring.go:316 msg="ring doesn't exist in KV store yet"
level=info ts=2025-01-30T06:36:10.498360498Z caller=ring.go:316 msg="ring doesn't exist in KV store yet"
level=info ts=2025-01-30T06:36:10.498495459Z caller=module_service.go:82 msg=starting module=distributor
ts=2025-01-30T06:36:10Z level=warn msg="Using the 0.0.0.0 address exposes this server to every network interface, which may facilitate Denial of Service attacks." component=tempo documentation=https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks
ts=2025-01-30T06:36:10Z level=info msg="Starting GRPC server" component=tempo endpoint=0.0.0.0:4317
ts=2025-01-30T06:36:10Z level=warn msg="Using the 0.0.0.0 address exposes this server to every network interface, which may facilitate Denial of Service attacks." component=tempo documentation=https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md#safeguards-against-denial-of-service-attacks
ts=2025-01-30T06:36:10Z level=info msg="Starting HTTP server" component=tempo endpoint=0.0.0.0:4318
level=info ts=2025-01-30T06:36:10.498914304Z caller=app.go:208 msg="Tempo started"
level=error ts=2025-01-30T06:36:10.509656008Z caller=resolver.go:87 msg="failed to lookup IP addresses" host=hm-tempo-gossip-ring err="lookup hm-tempo-gossip-ring on 10.215.0.10:53: no such host"
level=warn ts=2025-01-30T06:36:10.509682688Z caller=resolver.go:134 msg="IP address lookup yielded no results. No host found or no addresses found" host=hm-tempo-gossip-ring
level=warn ts=2025-01-30T06:36:10.509699598Z caller=memberlist_client.go:629 phase=startup msg="joining memberlist cluster" attempts=1 max_attempts=10 err="found no nodes to join"
level=error ts=2025-01-30T06:36:11.536326569Z caller=resolver.go:87 msg="failed to lookup IP addresses" host=hm-tempo-gossip-ring err="lookup hm-tempo-gossip-ring on 10.215.0.10:53: no such host"
level=warn ts=2025-01-30T06:36:11.536359541Z caller=resolver.go:134 msg="IP address lookup yielded no results. No host found or no addresses found" host=hm-tempo-gossip-ring
level=warn ts=2025-01-30T06:36:11.53637399Z caller=memberlist_client.go:629 phase=startup msg="joining memberlist cluster" attempts=2 max_attempts=10 err="found no nodes to join"
level=error ts=2025-01-30T06:36:15.080790386Z caller=resolver.go:87 msg="failed to lookup IP addresses" host=hm-tempo-gossip-ring err="lookup hm-tempo-gossip-ring on 10.215.0.10:53: no such host"
level=warn ts=2025-01-30T06:36:15.080823057Z caller=resolver.go:134 msg="IP address lookup yielded no results. No host found or no addresses found" host=hm-tempo-gossip-ring
level=warn ts=2025-01-30T06:36:15.080835127Z caller=memberlist_client.go:629 phase=startup msg="joining memberlist cluster" attempts=3 max_attempts=10 err="found no nodes to join"
level=info ts=2025-01-30T06:36:19.988200041Z caller=memberlist_client.go:602 phase=startup msg="joining memberlist cluster succeeded" reached_nodes=7 elapsed_time=9.489949855s

В S3 имеется только файл tempo_cluster_seed.json, что означает, что Tempo может записывать в S3 успешно. Однако никаких других данных трасс нет:

enter image description here

Любые советы будут приветствоваться, спасибо!

Обновление 2/15/2025

Что касается

loading and assigning BPF objects: field BeylaKprobeSysBind: program beyla_kprobe_sys_bind: map watch_events: map create: operation not permitted (MEMLOCK may be too low, consider rlimit.RemoveMemlock)

В pod’е Alloy, я уже проверил, что ulimit -l уже возвращает unlimited. В моем случае, фактической причиной, вызвавшей это, является отсутствие следующего раздела, основанного на https://grafana.com/docs/grafana-cloud/send-data/alloy/reference/components/beyla/beyla.ebpf/

        alloy:
          stabilityLevel: public-preview
          securityContext:
            appArmorProfile:
              type: Unconfined
            capabilities:
              add:
                - SYS_ADMIN
                - SYS_PTRACE

После добавления вышеупомянутых частей, больше нет ошибок, связанных с Бейлой.

Я провел дальнейшее исследование, поскольку никакое внешнее приложение не отправляет трассы в Alloy, то никаких трасс нет. Однако, я ожидал, что Grafana Beyla будет генерировать трассы. Поэтому я удалил нерелевантные коды, сосредотачиваясь лишь на отладке этой части:

---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-hm-alloy
  namespace: production-hm-argo-cd
  labels:
    app.kubernetes.io/name: hm-alloy
spec:
  project: production-hm
  source:
    repoURL: https://grafana.github.io/helm-charts
    # https://artifacthub.io/packages/helm/grafana/alloy
    targetRevision: 0.11.0
    chart: alloy
    helm:
      releaseName: hm-alloy
      values: |
        # https://github.com/grafana/alloy/blob/main/operations/helm/charts/alloy/values.yaml
        ---
        alloy:
          # https://grafana.com/docs/grafana-cloud/send-data/alloy/reference/components/beyla/beyla.ebpf/
          stabilityLevel: public-preview
          securityContext:
            appArmorProfile:
              type: Unconfined
            capabilities:
              add:
                - SYS_ADMIN
                - SYS_PTRACE
          extraEnv:
            - name: LOKI_URL
              value: http://hm-loki-gateway.production-hm-loki:80/loki/api/v1/push
            - name: TEMPO_ENDPOINT
              value: hm-tempo-distributor.production-hm-tempo.svc:4317
            - name: MIMIR_URL
              value: http://hm-mimir-distributor-headless.production-hm-mimir.svc:8080/api/v1/push
          configMap:
            content: |-
              // https://grafana.com/docs/alloy/latest/configure/kubernetes/
              // https://grafana.com/docs/alloy/latest/collect/logs-in-kubernetes/
              logging {
                level = "info"
                format = "logfmt"
              }

              // https://grafana.com/docs/alloy/latest/reference/config-blocks/livedebugging/
              livedebugging {
                enabled = true
              }
              
              // HM Beyla
              // https://grafana.com/docs/grafana-cloud/send-data/alloy/reference/components/beyla/beyla.ebpf/
              beyla.ebpf "hm_beyla" {
                debug = true
                open_port = 8080
                attributes {
                  kubernetes {
                    enable = "true"
                  }
                }
                discovery {
                  services {}
                }
                metrics {
                  features = [
                    "application",
                    "application_service_graph",
                    "application_span",
                    "network",
                  ]
                  instrumentations = ["*"]
                  network {
                    enable = true
                  }
                }
                output {
                  traces = [otelcol.processor.batch.hm_beyla.input]
                }
              }

              // HM Beyla - Trace
              otelcol.processor.batch "hm_beyla" {
                output {
                  traces = [otelcol.exporter.otlp.hm_tempo_for_hm_beyla.input]
                }
              }
              // https://grafana.com/docs/alloy/latest/reference/components/otelcol/otelcol.auth.headers/
              otelcol.auth.headers "hm_tempo_for_hm_beyla" {
                header {
                  key   = "X-Scope-OrgID"
                  value = "hm"
                }
              }
              otelcol.exporter.otlp "hm_tempo_for_hm_beyla" {
                client {
                  endpoint = env("TEMPO_ENDPOINT")
                  compression = "zstd"
                  auth = otelcol.auth.headers.hm_tempo_for_hm_beyla.handler
                  tls {
                    insecure = true
                    insecure_skip_verify = true
                  }
                }
              }

              // HM Beyla - Metrics
              // https://grafana.com/docs/alloy/latest/reference/components/beyla/beyla.ebpf/
              prometheus.scrape "hm_beyla" {
                targets = beyla.ebpf.hm_beyla.targets
                honor_labels = true
                forward_to = [prometheus.remote_write.hm_mimir.receiver]
              }

              prometheus.remote_write "hm_mimir" {
                endpoint {
                  url = env("MIMIR_URL")
                  headers = {
                    "X-Scope-OrgID" = "hm",
                  }
                }
              }

  destination:
    namespace: production-hm-alloy
    server: https://kubernetes.default.svc
  syncPolicy:
    syncOptions:
      - ServerSideApply=true
    automated:
      prune: true

Среди этих компонентов otelcol.processor.batch поддерживает отладку в реальном времени. Однако входящих трасс нет. Так что, видимо, он не получает никаких данных от Grafana Beyla:

enter image description here

enter image description here

С другой стороны, pod Alloy действительно показывает логи, указывающие на соединения между Grafana Alloy и Grafana Tempo:

network_flow: transport=6 beyla.ip=172.31.179.149 iface= iface_direction=1 src.address=172.31.179.149 dst.address=10.215.206.123 src.name=hm-alloy-dvv7d dst.name=hm-tempo-distributor src.port=45582 dst.port=4317 k8s.src.namespace=production-hm-alloy k8s.src.name=hm-alloy-dvv7d k8s.src.type=Pod k8s.src.owner.name=hm-alloy k8s.src.owner.type=DaemonSet k8s.dst.name=hm-tempo-distributor k8s.dst.type=Service k8s.dst.owner.type=Service k8s.src.node.ip=172.31.178.125 k8s.src.node.name=ip-172-31-178-125.us-west-2.compute.internal k8s.dst.namespace=production-hm-tempo k8s.dst.owner.name=hm-tempo-distributor
network_flow: transport=6 beyla.ip=172.31.179.149 iface= iface_direction=1 src.address=172.31.179.149 dst.address=10.215.206.123 src.name=hm-alloy-dvv7d dst.name=hm-tempo-distributor src.port=45574 dst.port=4317 k8s.src.name=hm-alloy-dvv7d k8s.src.type=Pod k8s.src.owner.name=hm-alloy k8s.dst.namespace=production-hm-tempo k8s.dst.type=Service k8s.dst.owner.name=hm-tempo-distributor k8s.dst.owner.type=Service k8s.src.namespace=production-hm-alloy k8s.src.owner.type=DaemonSet k8s.src.node.ip=172.31.178.125 k8s.src.node.name=ip-172-31-178-125.us-west-2.compute.internal k8s.dst.name=hm-tempo-distributor
network_flow: transport=6 beyla.ip=172.31.179.149 iface= iface_direction=0 src.address=10.215.206.123 dst.address=172.31.179.149 src.name=hm-tempo-distributor dst.name=hm-alloy-dvv7d src.port=4317 dst.port=45590 k8s.dst.namespace=production-hm-alloy k8s.dst.type=Pod k8s.src.type=Service k8s.src.owner.name=hm-tempo-distributor k8s.src.owner.type=Service k8s.dst.name=hm-alloy-dvv7d k8s.dst.owner.name=hm-alloy k8s.dst.owner.type=DaemonSet k8s.dst.node.ip=172.31.178.125 k8s.dst.node.name=ip-172-31-178-125.us-west-2.compute.internal k8s.src.namespace=production-hm-tempo k8s.src.name=hm-tempo-distributor

Оказывается, не хватает некоторых разрешений. Официальная документация по Alloy не упоминает их. Исходя из этого файла конфигураций Beyla, который я нашел, после обновления securityContext в Alloy, я могу видеть трассы.

          securityContext:
            # https://grafana.com/docs/grafana-cloud/send-data/alloy/reference/components/beyla/beyla.ebpf/
            appArmorProfile:
              type: Unconfined
            # https://github.com/grafana/beyla/blob/main/examples/k8s/unprivileged.yaml
            runAsUser: 0
            capabilities:
              drop:
                - ALL
              add:
                - BPF
                - CHECKPOINT_RESTORE
                - DAC_READ_SEARCH
                - NET_RAW
                - PERFMON
                - SYS_ADMIN
                - SYS_PTRACE

Полный конфиг:

---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: production-hm-alloy
  namespace: production-hm-argo-cd
  labels:
    app.kubernetes.io/name: hm-alloy
spec:
  project: production-hm
  source:
    repoURL: https://grafana.github.io/helm-charts
    # https://artifacthub.io/packages/helm/grafana/alloy
    targetRevision: 0.11.0
    chart: alloy
    helm:
      releaseName: hm-alloy
      values: |
        # https://github.com/grafana/alloy/blob/main/operations/helm/charts/alloy/values.yaml
        ---
        controller:
          # https://github.com/grafana/beyla/blob/main/examples/k8s/unprivileged.yaml
          hostPID: true
        alloy:
          stabilityLevel: public-preview
          securityContext:
            # https://grafana.com/docs/grafana-cloud/send-data/alloy/reference/components/beyla/beyla.ebpf/
            appArmorProfile:
              type: Unconfined
            # https://github.com/grafana/beyla/blob/main/examples/k8s/unprivileged.yaml
            runAsUser: 0
            capabilities:
              drop:
                - ALL
              add:
                - BPF
                - CHECKPOINT_RESTORE
                - DAC_READ_SEARCH
                - NET_RAW
                - PERFMON
                - SYS_ADMIN
                - SYS_PTRACE
          extraEnv:
            - name: LOKI_URL
              value: http://hm-loki-gateway.production-hm-loki:80/loki/api/v1/push
            - name: TEMPO_ENDPOINT
              value: hm-tempo-distributor.production-hm-tempo.svc:4317
            - name: MIMIR_URL
              value: http://hm-mimir-distributor-headless.production-hm-mimir.svc:8080/api/v1/push
          configMap:
            content: |-
              // https://grafana.com/docs/alloy/latest/configure/kubernetes/
              // https://grafana.com/docs/alloy/latest/collect/logs-in-kubernetes/
              logging {
                level = "info"
                format = "logfmt"
              }

              // https://grafana.com/docs/alloy/latest/reference/config-blocks/livedebugging/
              livedebugging {
                enabled = true
              }

              // Loki related config
              // ...

              // hm Beyla
              // https://grafana.com/docs/grafana-cloud/send-data/alloy/reference/components/beyla/beyla.ebpf/
              beyla.ebpf "hm_beyla" {
                debug = true
                open_port = "80,443,8000-8999"
                attributes {
                  kubernetes {
                    enable = "true"
                  }
                }
                discovery {
                  services {
                    kubernetes {
                      namespace = "."
                    }
                  }
                }
                routes {
                  unmatched = "heuristic"
                }
                metrics {
                  features = [
                    "application",
                    "application_process",
                    "application_service_graph",
                    "application_span",
                    "network",
                  ]
                  instrumentations = ["*"]
                  network {
                    enable = true
                  }
                }
                output {
                  traces = [otelcol.processor.batch.hm_beyla.input]
                }
              }

              // hm Beyla - Trace
              otelcol.processor.batch "hm_beyla" {
                output {
                  traces = [otelcol.exporter.otlp.hm_tempo_for_hm_beyla.input]
                }
              }
              // https://grafana.com/docs/alloy/latest/reference/components/otelcol/otelcol.auth.headers/
              otelcol.auth.headers "hm_tempo_for_hm_beyla" {
                header {
                  key   = "X-Scope-OrgID"
                  value = "hm"
                }
              }
              otelcol.exporter.otlp "hm_tempo_for_hm_beyla" {
                client {
                  endpoint = env("TEMPO_ENDPOINT")
                  compression = "zstd"
                  auth = otelcol.auth.headers.hm_tempo_for_hm_beyla.handler
                  tls {
                    insecure = true
                    insecure_skip_verify = true
                  }
                }
              }

              // hm Beyla - Metrics
              // https://grafana.com/docs/alloy/latest/reference/components/beyla/beyla.ebpf/
              prometheus.scrape "hm_beyla" {
                targets = beyla.ebpf.hm_beyla.targets
                honor_labels = true
                forward_to = [prometheus.remote_write.hm_mimir.receiver]
              }

              prometheus.remote_write "hm_mimir" {
                endpoint {
                  url = env("MIMIR_URL")
                  headers = {
                    "X-Scope-OrgID" = "hm",
                  }
                }
              }
  destination:
    namespace: production-hm-alloy
    server: https://kubernetes.default.svc
  syncPolicy:
    syncOptions:
      - ServerSideApply=true
    automated:
      prune: true

enter image description here

На данный момент я должен включить режим debug, чтобы трассы работали

              beyla.ebpf "hm_beyla" {
                debug = true

Я открыл тикет на здесь, если будут обновления, я обновлю этот ответ.

Ответ или решение

Для многих специалистов в области информационных технологий использование инструментов мониторинга, таких как Grafana, стало стандартом. Grafana позволяет интегрировать различные источники данных и наблюдательные системы в единую удобную панель управления. Одним из востребованных сочетаний является использование Grafana Alloy совместно с Grafana Tempo для сбора и анализа трассировки, однако, как показывает ваш опыт, на этом пути может возникнуть несколько сложностей.

Теория

Основное назначение Grafana Alloy и Grafana Tempo — это управление и анализ данных, полученных в режиме реального времени. Grafana Alloy, работающий совместно с Grafana Beyla и другим программным обеспечением, служит для автоматического инструментирования процессов в кластере Kubernetes и передачи данных в такие системы, как Tempo или Loki.

Tempo — это распределенная система для поиска и визуализации трассировок, которая может обрабатывать миллионы данных о трассировках в секунду. Однако интеграция между Alloy и Tempo требует корректной настройки множества компонентов, включая eBPF для автоматического сбора данных на уровне ядра и их передачи в систему аналитики.

Пример

Вы столкнулись с проблемами в настройке Alloy для успешной передачи данных в Tempo. Проблема включала отсутствие трассировок и неподготовленность сервисного графа, что изначально может быть связано с несколькими факторами:

  1. Неправильная конфигурация безопасности: Alloy требует расширенных прав доступа для использования eBPF-программ. Эти права, такие как SYS_ADMIN и SYS_PTRACE, должны быть добавлены в securityContext.

  2. Проблемы с конфигурацией eBPF: Ошибка, упомянутая в ваших логах об "operation not permitted (MEMLOCK may be too low)", указывает на потребность в корректной настройке лимитов памяти. Решение этой проблемы часто заключается в проверке и настройке параметров безопасности, таких как AppArmor и добавить необходимые параметры в securityContext.

  3. Недостаточная видимость компонентов: Параметры конфигурации, такие как debug = true, часто помогают вскрыть скрытые проблемы на этапе интеграции и настройки.

Применение

Учитывая изложенные выше проблемы и решения, можно предложить следующие шаги для настройки:

  1. Проверка прав доступа: Убедитесь, что ваш securityContext настроен правильно. Следует включить все необходимые составляющие, как это описано в примере кода:

    securityContext:
     appArmorProfile:
       type: Unconfined
     runAsUser: 0
     capabilities:
       drop:
         - ALL
       add:
         - BPF
         - CHECKPOINT_RESTORE
         - DAC_READ_SEARCH
         - NET_RAW
         - PERFMON
         - SYS_ADMIN
         - SYS_PTRACE
  2. Отладка и мониторинг: Для начальной стадии интеграции рекомендуется держать debug = true в конфигурации Alloy. Это позволит легче идентифицировать проблемы интеграции.

  3. Поддержание связи с сообществом: Поддерживайте контакт с соответствующими репозиториями и сообществами, такими как репозиторий Grafana на GitHub, чтобы получать последние обновления и лучшие практики.

  4. Ползование документацией: Важно следовать официальной документации и не упускать из виду такие важные детали, как рекомендованные конфигурации и типичные ошибки. Документация Grafana и Alloy может предложить гораздо больше информации, особенно если у вас возникли проблемы уникального характера.

Заключение

Настройка решений, таких как Grafana Alloy и Tempo, требует аккуратности из-за зависимости от компонентов с открытым исходным кодом и сложных конфигураций безопасности. Вижу, что вам удалось найти путь к разрешению вашей первоначальной проблемы через корректировку securityContext с использованием найденного конфига. Это является отличным примером того, как сочетание изучения документации и вовлеченности в сообщество может привести к успешному решению технических затруднений.

Оцените материал
Добавить комментарий

Капча загружается...