使用 Grafana Alloy Helm Chart 在 Kubernetes 中运行 Beyla
Grafana Alloy 是 OpenTelemetry Collector 的厂商中立分发版。Alloy 为 OpenTelemetry、Prometheus 和其他遥测信号提供了原生管道。
Grafana Alloy 捆绑了 Beyla,让您可以在对基础设施进行插桩的同时,对应用程序进行插桩。它还提供了一个 Helm Chart,用于在 Kubernetes 中部署 Alloy。
在本教程中,您将学习如何使用 Grafana Alloy Helm Chart 在 Kubernetes 中部署 Beyla。
先决条件
- 一个 Kubernetes 集群,您可以使用 kind 创建本地集群
kubectl
已安装并为您的集群配置- Helm 已安装
- 一个 Grafana Cloud 账号或兼容的 Prometheus 和/或 OpenTelemetry 后端以接收数据
1. 在 Kubernetes 中准备 Alloy 环境
您需要在 Kubernetes 集群中安装 Grafana Alloy 的 Helm Chart。
helm install --namespace alloy alloy grafana/alloy
此命令将在 alloy
命名空间中安装 Grafana Alloy Helm Chart。
2. 部署服务
您可以在 Kubernetes 集群中对任何 HTTP 或 HTTPS 服务进行插桩。
将以下内容复制到文件(例如 sampleapps.yml
)中,并使用命令 kubectl apply -f sampleapps.yml
部署它。
kind: Deployment
apiVersion: apps/v1
metadata:
name: docs
spec:
replicas: 2
selector:
matchLabels:
app: docs
template:
metadata:
labels:
app: docs
spec:
containers:
- name: docs-server
image: httpd:latest
ports:
- containerPort: 80
protocol: TCP
name: http
---
apiVersion: v1
kind: Service
metadata:
name: docs
spec:
selector:
app: docs
ports:
- protocol: TCP
port: 80
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: website
spec:
replicas: 2
selector:
matchLabels:
app: website
template:
metadata:
labels:
app: website
spec:
containers:
- name: website-server
image: httpd:latest
ports:
- containerPort: 80
protocol: TCP
name: http
---
apiVersion: v1
kind: Service
metadata:
name: website
spec:
selector:
app: website
ports:
- protocol: TCP
port: 80
3. 配置凭据
Alloy 可以将指标和追踪数据导出到任何 OpenTelemetry 端点,也可以将指标公开为 Prometheus 端点。然而,建议使用 Grafana Cloud 中的 Prometheus 和 Tempo 远程写入端点。您可以获取一个 免费的 Grafana Cloud 账号。
在 Grafana Cloud Portal 中,找到 **Prometheus** 框并点击 **发送指标**。对于 **Tempo** 框,点击 **发送追踪**。
创建一个 secrets.yml
文件,其中包含用于 Prometheus 和 Tempo 远程写入的 Grafana Cloud 凭据。使用命令 kubectl apply -f secrets.yml
部署它。
apiVersion: v1
kind: Secret
metadata:
namespace: alloy
name: grafana-credentials
type: Opaque
stringData:
prometheus-rw-user: "prom-user"
prometheus-rw-pwd: "prom-pwd"
tempo-rw-user: "tempo-user"
tempo-rw-pwd: "tempo-pwd"
3. 创建带有 Alloy 配置的 ConfigMap
创建一个带有 Alloy 配置的 ConfigMap
。将以下内容复制到文件(例如 config.alloy
)中
beyla.ebpf "default" {
attributes {
kubernetes {
enable = "true"
}
}
discovery {
services {
kubernetes {
namespace = "default"
deployment_name = "."
}
}
}
metrics {
features = [
"application",
]
}
output {
traces = [otelcol.exporter.otlp.grafana_cloud_tempo.input]
}
}
prometheus.scrape "beyla" {
targets = beyla.ebpf.default.targets
honor_labels = true
forward_to = [prometheus.remote_write.rw.receiver]
}
prometheus.remote_write "rw" {
endpoint {
url = "https://prometheus-us-central1.grafana.net/api/prom/push"
basic_auth {
username = env("PROMETHEUS_REMOTE_WRITE_USERNAME")
password = env("PROMETHEUS_REMOTE_WRITE_PASSWORD")
}
}
}
otelcol.exporter.otlp "grafana_cloud_tempo" {
client {
endpoint = "tempo-us-central1.grafana.net:443"
auth = otelcol.auth.basic.grafana_cloud_tempo.handler
}
}
otelcol.auth.basic "grafana_cloud_tempo" {
username = env("TEMPO_REMOTE_WRITE_USERNAME")
password = env("TEMPO_REMOTE_WRITE_PASSWORD")
}
使用此命令部署配置
kubectl create configmap --namespace alloy alloy-config "--from-file=config.alloy=./config.alloy"
使用此配置,Beyla 会对在 Kubernetes 集群中运行的服务进行插桩,并将追踪数据发送到 Grafana Cloud Tempo,将指标发送到 Prometheus。
attributes > kubernetes > enable
启用指标和追踪的 Kubernetes 装饰,这将添加运行自动插桩服务的 Kubernetes 实体元数据。
参数 discovery > services > kubernetes
根据 Kubernetes 元数据指定服务的选择。在此示例中,Beyla 会对命名空间“default”中的所有部署进行插桩。
prometheus.scrape
部分配置 Prometheus 抓取配置以从 Beyla 收集指标。prometheus.remote_write
部分配置远程写入以将指标发送到 Grafana Cloud Prometheus。
output
部分配置 Beyla 组件将追踪发送到 otelcol.exporter.otlp
组件。otelcol.exporter.otlp
部分配置 OTLP exporter 以将追踪发送到 Grafana Cloud Tempo。
有关配置选项的更多详细信息,请参阅 Grafana Alloy Beyla 组件的文档
4. 使用 Helm 部署 Alloy
创建包含 Alloy Helm Chart 配置的 values.yaml
文件。将以下内容复制到文件(例如 values.yaml
)中。
# -- Overrides the chart's name. Used to change the infix in the resource names.
nameOverride: null
# -- Overrides the chart's computed fullname. Used to change the full prefix of
# resource names.
fullnameOverride: null
## Global properties for image pulling override the values defined under `image.registry` and `configReloader.image.registry`.
## If you want to override only one image registry, use the specific fields but if you want to override them all, use `global.image.registry`
global:
image:
# -- Global image registry to use if it needs to be overridden for some specific use cases (e.g local registries, custom images, ...)
registry: ""
# -- Optional set of global image pull secrets.
pullSecrets: []
# -- Security context to apply to the Grafana Alloy pod.
podSecurityContext: {}
crds:
# -- Whether to install CRDs for monitoring.
create: true
## Various Alloy settings. For backwards compatibility with the grafana-agent
## chart, this field may also be called "agent". Naming this field "agent" is
## deprecated and will be removed in a future release.
alloy:
configMap:
# -- Create a new ConfigMap for the config file.
create: false
# -- Name of existing ConfigMap to use. Used when create is false.
name: alloy-config
# -- Key in ConfigMap to get config from.
key: config.alloy
clustering:
# -- Deploy Alloy in a cluster to allow for load distribution.
enabled: false
# -- Minimum stability level of components and behavior to enable. Must be
# one of "experimental", "public-preview", or "generally-available".
stabilityLevel: "public-preview"
# -- Path to where Grafana Alloy stores data (for example, the Write-Ahead Log).
# By default, data is lost between reboots.
storagePath: /tmp/alloy
# -- Address to listen for traffic on. 0.0.0.0 exposes the UI to other
# containers.
listenAddr: 0.0.0.0
# -- Port to listen for traffic on.
listenPort: 12345
# -- Scheme is needed for readiness probes. If enabling tls in your configs, set to "HTTPS"
listenScheme: HTTP
# -- Base path where the UI is exposed.
uiPathPrefix: /
# -- Enables sending Grafana Labs anonymous usage stats to help improve Grafana
# Alloy.
enableReporting: true
# -- Extra environment variables to pass to the Alloy container.
extraEnv:
- name: PROMETHEUS_REMOTE_WRITE_USERNAME
valueFrom:
secretKeyRef:
name: grafana-credentials
key: prometheus-rw-user
- name: PROMETHEUS_REMOTE_WRITE_PASSWORD
valueFrom:
secretKeyRef:
name: grafana-credentials
key: prometheus-rw-pwd
- name: TEMPO_REMOTE_WRITE_USERNAME
valueFrom:
secretKeyRef:
name: grafana-credentials
key: tempo-rw-user
- name: TEMPO_REMOTE_WRITE_PASSWORD
valueFrom:
secretKeyRef:
name: grafana-credentials
key: tempo-rw-pwd
# -- Maps all the keys on a ConfigMap or Secret as environment variables. https://kubernetes.ac.cn/docs/reference/generated/kubernetes-api/v1.24/#envfromsource-v1-core
envFrom: []
# -- Extra args to pass to `alloy run`: https://grafana.org.cn/docs/alloy/latest/reference/cli/run/
extraArgs: []
# -- Extra ports to expose on the Alloy container.
extraPorts: []
# - name: "faro"
# port: 12347
# targetPort: 12347
# protocol: "TCP"
mounts:
# -- Mount /var/log from the host into the container for log collection.
varlog: false
# -- Mount /var/lib/docker/containers from the host into the container for log
# collection.
dockercontainers: false
# -- Extra volume mounts to add into the Grafana Alloy container. Does not
# affect the watch container.
extra: []
# -- Security context to apply to the Grafana Alloy container.
securityContext:
privileged: true # important!
# -- Resource requests and limits to apply to the Grafana Alloy container.
resources: {}
image:
# -- Grafana Alloy image registry (defaults to docker.io)
registry: "docker.io"
# -- Grafana Alloy image repository.
repository: grafana/alloy
# -- (string) Grafana Alloy image tag. When empty, the Chart's appVersion is
# used.
tag: null
# -- Grafana Alloy image's SHA256 digest (either in format "sha256:XYZ" or "XYZ"). When set, will override `image.tag`.
digest: null
# -- Grafana Alloy image pull policy.
pullPolicy: IfNotPresent
# -- Optional set of image pull secrets.
pullSecrets: []
rbac:
# -- Whether to create RBAC resources for Alloy.
create: true
serviceAccount:
# -- Whether to create a service account for the Grafana Alloy deployment.
create: true
# -- Additional labels to add to the created service account.
additionalLabels: {}
# -- Annotations to add to the created service account.
annotations: {}
# -- The name of the existing service account to use when
# serviceAccount.create is false.
name: null
# Options for the extra controller used for config reloading.
configReloader:
# -- Enables automatically reloading when the Alloy config changes.
enabled: true
image:
# -- Config reloader image registry (defaults to docker.io)
registry: "ghcr.io"
# -- Repository to get config reloader image from.
repository: jimmidyson/configmap-reload
# -- Tag of image to use for config reloading.
tag: v0.12.0
# -- SHA256 digest of image to use for config reloading (either in format "sha256:XYZ" or "XYZ"). When set, will override `configReloader.image.tag`
digest: ""
# -- Override the args passed to the container.
customArgs: []
# -- Resource requests and limits to apply to the config reloader container.
resources:
requests:
cpu: "1m"
memory: "5Mi"
# -- Security context to apply to the Grafana configReloader container.
securityContext: {}
controller:
# -- Type of controller to use for deploying Grafana Alloy in the cluster.
# Must be one of 'daemonset', 'deployment', or 'statefulset'.
type: 'daemonset'
# -- Number of pods to deploy. Ignored when controller.type is 'daemonset'.
replicas: 1
# -- Annotations to add to controller.
extraAnnotations: {}
# -- Whether to deploy pods in parallel. Only used when controller.type is
# 'statefulset'.
parallelRollout: true
# -- Configures Pods to use the host network. When set to true, the ports that will be used must be specified.
hostNetwork: false
# -- Configures Pods to use the host PID namespace.
hostPID: true # important!
# -- Configures the DNS policy for the pod. https://kubernetes.ac.cn/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy
dnsPolicy: ClusterFirst
# -- Update strategy for updating deployed Pods.
updateStrategy: {}
# -- nodeSelector to apply to Grafana Alloy pods.
nodeSelector: {}
# -- Tolerations to apply to Grafana Alloy pods.
tolerations: []
# -- Topology Spread Constraints to apply to Grafana Alloy pods.
topologySpreadConstraints: []
# -- priorityClassName to apply to Grafana Alloy pods.
priorityClassName: ''
# -- Extra pod annotations to add.
podAnnotations: {}
# -- Extra pod labels to add.
podLabels: {}
# -- Whether to enable automatic deletion of stale PVCs due to a scale down operation, when controller.type is 'statefulset'.
enableStatefulSetAutoDeletePVC: false
autoscaling:
# -- Creates a HorizontalPodAutoscaler for controller type deployment.
enabled: false
# -- The lower limit for the number of replicas to which the autoscaler can scale down.
minReplicas: 1
# -- The upper limit for the number of replicas to which the autoscaler can scale up.
maxReplicas: 5
# -- Average CPU utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetCPUUtilizationPercentage` to 0 will disable CPU scaling.
targetCPUUtilizationPercentage: 0
# -- Average Memory utilization across all relevant pods, a percentage of the requested value of the resource for the pods. Setting `targetMemoryUtilizationPercentage` to 0 will disable Memory scaling.
targetMemoryUtilizationPercentage: 80
scaleDown:
# -- List of policies to determine the scale-down behavior.
policies: []
# - type: Pods
# value: 4
# periodSeconds: 60
# -- Determines which of the provided scaling-down policies to apply if multiple are specified.
selectPolicy: Max
# -- The duration that the autoscaling mechanism should look back on to make decisions about scaling down.
stabilizationWindowSeconds: 300
scaleUp:
# -- List of policies to determine the scale-up behavior.
policies: []
# - type: Pods
# value: 4
# periodSeconds: 60
# -- Determines which of the provided scaling-up policies to apply if multiple are specified.
selectPolicy: Max
# -- The duration that the autoscaling mechanism should look back on to make decisions about scaling up.
stabilizationWindowSeconds: 0
# -- Affinity configuration for pods.
affinity: {}
volumes:
# -- Extra volumes to add to the Grafana Alloy pod.
extra: []
# -- volumeClaimTemplates to add when controller.type is 'statefulset'.
volumeClaimTemplates: []
## -- Additional init containers to run.
## ref: https://kubernetes.ac.cn/docs/concepts/workloads/pods/init-containers/
##
initContainers: []
# -- Additional containers to run alongside the Alloy container and initContainers.
extraContainers: []
service:
# -- Creates a Service for the controller's pods.
enabled: true
# -- Service type
type: ClusterIP
# -- NodePort port. Only takes effect when `service.type: NodePort`
nodePort: 31128
# -- Cluster IP, can be set to None, empty "" or an IP address
clusterIP: ''
# -- Value for internal traffic policy. 'Cluster' or 'Local'
internalTrafficPolicy: Cluster
annotations: {}
# cloud.google.com/load-balancer-type: Internal
serviceMonitor:
enabled: false
# -- Additional labels for the service monitor.
additionalLabels: {}
# -- Scrape interval. If not set, the Prometheus default scrape interval is used.
interval: ""
# -- MetricRelabelConfigs to apply to samples after scraping, but before ingestion.
# ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig
metricRelabelings: []
# - action: keep
# regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'
# sourceLabels: [__name__]
# -- Customize tls parameters for the service monitor
tlsConfig: {}
# -- RelabelConfigs to apply to samples before scraping
# ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig
relabelings: []
# - sourceLabels: [__meta_kubernetes_pod_node_name]
# separator: ;
# regex: ^(.*)$
# targetLabel: nodename
# replacement: $1
# action: replace
ingress:
# -- Enables ingress for Alloy (Faro port)
enabled: false
# For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
# See https://kubernetes.ac.cn/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
# ingressClassName: nginx
# Values can be templated
annotations:
{}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
labels: {}
path: /
faroPort: 12347
# pathType is only for k8s >= 1.1=
pathType: Prefix
hosts:
- chart-example.local
## Extra paths to prepend to every host configuration. This is useful when working with annotation based services.
extraPaths: []
# - path: /*
# backend:
# serviceName: ssl-redirect
# servicePort: use-annotation
## Or for k8s > 1.19
# - path: /*
# pathType: Prefix
# backend:
# service:
# name: ssl-redirect
# port:
# name: use-annotation
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
使用此命令部署配置
helm upgrade --namespace alloy alloy grafana/alloy -f values.yaml
- 要在 DaemonSet 模式下运行,Beyla 需要访问节点中的所有进程。因此,在
controller
部分设置hostPID: true
。 - Beyla 容器需要以特权模式运行,因为它需要执行加载 BPF 程序和创建 BPF map 等特权操作。因此,在
securityContext
部分设置privileged: true
。要将 Beyla 作为无特权容器运行(即不带privileged: true
选项),请访问部署无特权的 Beyla指南。 extraEnv
部分设置 Prometheus 和 Tempo 远程写入凭据的环境变量。
5. 测试设置
在第一步中的 kubectl port-forward
命令仍在运行的情况下,测试两个 Web 服务器实例。例如
curl https://:8080
curl https://:8080/foo
curl https://:8081
curl https://:8081/foo
导航到 Grafana Cloud 中的实例,在左侧面板的**探索**部分,选择追踪数据源,其名称为 grafanacloud-<您的用户名>-traces
。
要搜索所有追踪,请在查询栏中选择**搜索**框,留空表单,然后点击**运行查询**
这会显示端口 8081 上的 docs
实例的追踪数据。您可能会看到来自您自己服务的追踪,但不应看到来自 website
服务的追踪,因为 Beyla 没有对其进行插桩。
在追踪详细信息中,追踪的资源属性包含运行插桩服务的 Kubernetes Pod 的元数据