在 Kubernetes 中部署 Beyla
注意
本文档介绍了如何在 Kubernetes 中手动部署 Beyla,并自行设置所有必需的实体。
您可能更倾向于遵循使用 Helm 在 Kubernetes 中部署 Beyla 文档。
目录
配置 Kubernetes 元数据装饰
Beyla 可以使用以下 Kubernetes 标签装饰您的链路追踪
k8s.namespace.name
k8s.deployment.name
k8s.statefulset.name
k8s.replicaset.name
k8s.daemonset.name
k8s.node.name
k8s.pod.name
k8s.container.name
k8s.pod.uid
k8s.pod.start_time
k8s.cluster.name
要启用元数据装饰,您需要
- 创建一个 ServiceAccount 并绑定一个 ClusterRole,授予对 Pods 和 ReplicaSets 的列表和监视权限。您可以通过部署以下示例文件来实现
apiVersion: v1
kind: ServiceAccount
metadata:
name: beyla
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: beyla
rules:
- apiGroups: [ "apps" ]
resources: [ "replicasets" ]
verbs: [ "list", "watch" ]
- apiGroups: [ "" ]
resources: [ "pods", "services", "nodes" ]
verbs: [ "list", "watch" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: beyla
subjects:
- kind: ServiceAccount
name: beyla
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: beyla
(如果您在其他命名空间中部署 Beyla,则需要更改 namespace: default
的值)。
使用
BEYLA_KUBE_METADATA_ENABLE=true
环境变量配置 Beyla,或在 YAML 配置中使用attributes.kubernetes.enable: true
。请不要忘记在您的 Beyla Pod 中指定
serviceAccountName: beyla
属性(如后面的部署示例所示)。
(可选)在 YAML 配置文件的 discovery -> services
部分选择要插桩哪些 Kubernetes 服务。更多信息请参阅配置文档中的 *Service discovery*(服务发现)部分,以及本页的提供外部配置文件部分。
部署 Beyla
您可以通过两种不同的方式在 Kubernetes 中部署 Beyla
- 作为边车容器
- 作为 DaemonSet
将 Beyla 作为边车容器部署
如果您想监控某个可能未部署在所有主机上的特定服务,则可以按此方式部署 Beyla,这样您只需为每个服务实例部署一个 Beyla 实例。
将 Beyla 作为边车容器部署有以下配置要求
- Pod 中的所有容器必须共享进程命名空间(
shareProcessNamespace: true
pod 变量) - 自动插桩容器必须在特权模式下运行(容器配置的
securityContext.privileged: true
属性)。- 某些 Kubernetes 安装允许以下
securityContext
配置,但它可能无法与所有容器运行时配置一起使用,因为其中一些配置会限制容器并移除部分权限securityContext: runAsUser: 0 capabilities: add: - SYS_ADMIN - SYS_RESOURCE # not required for kernels 5.11+
- 某些 Kubernetes 安装允许以下
以下示例通过将 Beyla 作为容器附加(镜像位于 grafana/beyla:latest
)来对 goblog
Pod 进行插桩。自动插桩工具配置为将指标和链路追踪转发到 Grafana Alloy,该服务在同一命名空间中可通过 grafana-alloy
服务访问
apiVersion: apps/v1
kind: Deployment
metadata:
name: goblog
labels:
app: goblog
spec:
replicas: 2
selector:
matchLabels:
app: goblog
template:
metadata:
labels:
app: goblog
spec:
# Required so the sidecar instrument tool can access the service process
shareProcessNamespace: true
serviceAccountName: beyla # required if you want kubernetes metadata decoration
containers:
# Container for the instrumented service
- name: goblog
image: mariomac/goblog:dev
imagePullPolicy: IfNotPresent
command: ["/goblog"]
ports:
- containerPort: 8443
name: https
# Sidecar container with Beyla - the eBPF auto-instrumentation tool
- name: beyla
image: grafana/beyla:latest
securityContext: # Privileges are required to install the eBPF probes
privileged: true
env:
# The internal port of the goblog application container
- name: BEYLA_OPEN_PORT
value: "8443"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://grafana-alloy:4318"
# required if you want kubernetes metadata decoration
- name: BEYLA_KUBE_METADATA_ENABLE
value: "true"
有关不同配置选项的更多信息,请查阅本文档站点的配置部分。
将 Beyla 作为 DaemonSet 部署
您还可以将 Beyla 作为 Daemonset 部署。如果出现以下情况,这是首选方式
- 您想对 Daemonset 进行插桩
- 您想从单个 Beyla 实例插桩多个进程,甚至插桩集群中的所有进程。
以上面的示例 (goblog
Pod) 为例,我们无法通过其开放端口选择要插桩的进程,因为该端口对 Pod 内部开放。同时,该服务的多个实例将具有不同的开放端口。在这种情况下,我们需要使用应用程序服务可执行文件的名称进行插桩(参见后面的示例)。
除了边车方案的特权要求外,您还需要在自动插桩 Pod 模板中启用 hostPID: true
选项,以便它可以访问在同一主机上运行的所有进程。
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: beyla
labels:
app: beyla
spec:
selector:
matchLabels:
app: beyla
template:
metadata:
labels:
app: beyla
spec:
hostPID: true # Required to access the processes on the host
serviceAccountName: beyla # required if you want kubernetes metadata decoration
containers:
- name: autoinstrument
image: grafana/beyla:latest
securityContext:
privileged: true
env:
# Select the executable by its name instead of BEYLA_OPEN_PORT
- name: BEYLA_EXECUTABLE_NAME
value: "goblog"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://grafana-alloy:4318"
# required if you want kubernetes metadata decoration
- name: BEYLA_KUBE_METADATA_ENABLE
value: "true"
在非特权模式下部署 Beyla
到目前为止的所有示例中,Beyla 部署的 securityContext
部分都使用了 privileged:true
或 SYS_ADMIN
Linux 能力。虽然这在所有情况下都适用,但如果您的安全配置要求如此,也有办法在降低特权的情况下在 Kubernetes 中部署 Beyla。这是否可能取决于您使用的 Kubernetes 版本以及底层的容器运行时(例如 Containerd、CRI-O 或 Docker)。
以下指南主要基于使用 containerd
运行 GKE
、kubeadm
、k3s
、microk8s
和 kind
执行的测试。
要在非特权模式下运行 Beyla,您需要将 privileged:true
设置替换为一组 Linux 能力。Beyla 所需能力的完整列表可在安全性、权限和能力中找到。
注意 加载 BPF 程序需要 Beyla 能够读取 Linux 性能事件,或者至少能够执行 Linux 内核 API perf_event_open()
。
此权限由 CAP_PERFMON
授予,或通过 CAP_SYS_ADMIN
更宽松地授予。由于 CAP_PERFMON
和 CAP_SYS_ADMIN
都授予 Beyla 读取性能事件的权限,您应该使用 CAP_PERFMON
,因为它授予的权限较少。但是,在系统级别,对性能事件的访问是通过设置 kernel.perf_event_paranoid
控制的,您可以使用 sysctl
或修改文件 /proc/sys/kernel/perf_event_paranoid
来读取或写入此设置。kernel.perf_event_paranoid
的默认设置通常为 2
,这在内核文档的 perf_event_paranoid
部分中有记录。一些 Linux 发行版为 kernel.perf_event_paranoid
定义了更高的级别,例如基于 Debian 的发行版也使用 kernel.perf_event_paranoid=3
,这在没有 CAP_SYS_ADMIN
的情况下禁止访问 perf_event_open()
。如果您正在运行 kernel.perf_event_paranoid
设置高于 2 的发行版,您可以修改配置将其降低到 2,或使用 CAP_SYS_ADMIN
代替 CAP_PERFMON
。
下面是 Beyla 非特权容器配置示例,您也可以下载完整的示例部署文件。
...
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: beyla
namespace: beyla-demo
labels:
k8s-app: beyla
spec:
selector:
matchLabels:
k8s-app: beyla
template:
metadata:
labels:
k8s-app: beyla
spec:
serviceAccount: beyla
hostPID: true # <-- Important. Required in Daemonset mode so Beyla can discover all monitored processes
containers:
- name: beyla
terminationMessagePolicy: FallbackToLogsOnError
image: grafana/beyla:latest
env:
- name: BEYLA_TRACE_PRINTER
value: "text"
- name: BEYLA_KUBE_METADATA_ENABLE
value: "autodetect"
- name: KUBE_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
...
securityContext:
runAsUser: 0
readOnlyRootFilesystem: true
capabilities:
add:
- BPF # <-- Important. Required for most eBPF probes to function correctly.
- SYS_PTRACE # <-- Important. Allows Beyla to access the container namespaces and inspect executables.
- NET_RAW # <-- Important. Allows Beyla to use socket filters for http requests.
- CHECKPOINT_RESTORE # <-- Important. Allows Beyla to open ELF files.
- DAC_READ_SEARCH # <-- Important. Allows Beyla to open ELF files.
- PERFMON # <-- Important. Allows Beyla to load BPF programs.
#- SYS_RESOURCE # <-- pre 5.11 only. Allows Beyla to increase the amount of locked memory.
#- SYS_ADMIN # <-- Required for Go application trace context propagation, or if kernel.perf_event_paranoid >= 3 on Debian distributions.
drop:
- ALL
volumeMounts:
- name: var-run-beyla
mountPath: /var/run/beyla
- name: cgroup
mountPath: /sys/fs/cgroup
tolerations:
- effect: NoSchedule
operator: Exists
- effect: NoExecute
operator: Exists
volumes:
- name: var-run-beyla
emptyDir: {}
- name: cgroup
hostPath:
path: /sys/fs/cgroup
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: some-service
namespace: beyla-demo
...
---
提供外部配置文件
在前面的示例中,Beyla 是通过环境变量配置的。但是,您也可以通过外部 YAML 文件进行配置(如本站点的配置部分所述)。
要将配置作为文件提供,推荐的方法是使用所需配置部署一个 ConfigMap,然后将其挂载到 Beyla Pod 中,并通过 BEYLA_CONFIG_PATH
环境变量引用它。
包含 Beyla YAML 文档的 ConfigMap 示例
apiVersion: v1
kind: ConfigMap
metadata:
name: beyla-config
data:
beyla-config.yml: |
trace_printer: text
grafana:
otlp:
submit: ["metrics","traces"]
otel_traces_export:
sampler:
name: parentbased_traceidratio
arg: "0.01"
routes:
patterns:
- /factorial/{num}
Beyla DaemonSet 配置示例,挂载并访问之前的 ConfigMap
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: beyla
spec:
selector:
matchLabels:
instrumentation: beyla
template:
metadata:
labels:
instrumentation: beyla
spec:
serviceAccountName: beyla
hostPID: true #important!
containers:
- name: beyla
image: grafana/beyla:latest
imagePullPolicy: IfNotPresent
securityContext:
privileged: true
readOnlyRootFilesystem: true
# mount the previous ConfigMap as a folder
volumeMounts:
- mountPath: /config
name: beyla-config
- mountPath: /var/run/beyla
name: var-run-beyla
env:
# tell beyla where to find the configuration file
- name: BEYLA_CONFIG_PATH
value: "/config/beyla-config.yml"
volumes:
- name: beyla-config
configMap:
name: beyla-config
- name: var-run-beyla
emptyDir: {}
提供秘密配置
上面的示例适用于常规配置,但不应用于传递密码或 API 密钥等秘密信息。
要提供秘密信息,推荐的方法是部署一个 Kubernetes Secret。例如,这个 Secret 包含一些虚构的 Grafana Cloud 凭据
apiVersion: v1
kind: Secret
metadata:
name: grafana-secret
type: Opaque
stringData:
grafana-user: "123456"
grafana-api-key: "xxxxxxxxxxxxxxx"
然后您可以将 Secret 值作为环境变量访问。按照前面的 DaemonSet 示例,这可以通过向 Beyla 容器添加以下 env
部分来实现。
env:
- name: GRAFANA_CLOUD_ZONE
value: prod-eu-west-0
- name: GRAFANA_CLOUD_INSTANCE_ID
valueFrom:
secretKeyRef:
key: grafana-user
name: grafana-secret
- name: GRAFANA_CLOUD_API_KEY
valueFrom:
secretKeyRef:
key: grafana-api-key
name: grafana-secret