<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Beyla tutorials on Grafana Labs</title><link>https://grafana.com/docs/beyla/v1.6.x/tutorial/</link><description>Recent content in Beyla tutorials on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/beyla/v1.6.x/tutorial/index.xml" rel="self" type="application/rss+xml"/><item><title>Beyla and Kubernetes walkthrough</title><link>https://grafana.com/docs/beyla/v1.6.x/tutorial/k8s-walkthrough/</link><pubDate>Mon, 17 Mar 2025 08:44:01 +0100</pubDate><guid>https://grafana.com/docs/beyla/v1.6.x/tutorial/k8s-walkthrough/</guid><content><![CDATA[&lt;h1 id=&#34;beyla-and-kubernetes-walkthrough&#34;&gt;Beyla and Kubernetes walkthrough&lt;/h1&gt;
&lt;p&gt;Kubernetes is fully integrated into the Beyla operation mode.&lt;/p&gt;
&lt;p&gt;On one side, metrics and traces can be decorated
with the metadata of the kubernetes entities running the automatically instrumented
services.&lt;/p&gt;
&lt;p&gt;On the other side, DaemonSet has become the preferred deployment
mode for Beyla: thanks to the versatility of the new service selectors,
a user can precisely define which services need to be instrumented and which
don&amp;rsquo;t. A single instance of Beyla will be able to instrument the selected
group of services within a single Kubernetes node.&lt;/p&gt;
&lt;h2 id=&#34;beyla-service-selectors&#34;&gt;Beyla service selectors&lt;/h2&gt;
&lt;p&gt;A service selector is a set of properties that let Beyla to query which processes need
to be instrumented.&lt;/p&gt;
&lt;p&gt;When Beyla is deployed as a regular operating system process that instrument other processes,
the unique service selectors are the network port where the instrumented process should
be listening to (can be specified with the &lt;code&gt;BEYLA_OPEN_PORT&lt;/code&gt; environment variable) or
a regular expression to match against the executable file name of the process to
instrument (&lt;code&gt;BEYLA_EXECUTABLE_NAME&lt;/code&gt; environment variable).&lt;/p&gt;
&lt;p&gt;To select multiple groups of processes, the Beyla YAML configuration file format
provides a &lt;code&gt;discovery.services&lt;/code&gt; section that accepts multiple selector groups:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;discovery:
  services:
    # Instrument any process using the ports from 8080 to 8089
    - open_ports: 8080-8089
    # Instrument any process whose executable contains &amp;#34;http&amp;#34;
    - exe_path: &amp;#34;http&amp;#34;
    # Instrument any process with an executable containing &amp;#34;nginx&amp;#34;
    # and using the port 443 (both conditions must be fulfilled)
    - open_ports: 443
      exe_path: &amp;#34;nginx&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The above criteria are insufficient for Kubernetes pods where the ports are ephemeral
and internal to the pods. Also, pods are a level of abstraction that should hide
details such as the name of their executables.
For that reason, Beyla v1.2 introduces the new Kubernetes service
selection criteria. All of them accept a &lt;a href=&#34;https://github.com/google/re2/wiki/Syntax&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Go RE2-syntax regular expression&lt;/a&gt;
as value:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;k8s_namespace&lt;/code&gt;: only instrument applications in the
namespace matching the provided regular expression.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;k8s_deployment_name&lt;/code&gt;: only instrument Pods that belong to
a Deployment with a name matching the provided regular expression.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;k8s_replicaset_name&lt;/code&gt;: only instrument Pods that belong to
a ReplicaSet with a name matching the provided regular expression.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;k8s_pod_name&lt;/code&gt;: only instrument Pods with a name matching the provided regular expression.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;example-scenario&#34;&gt;Example scenario&lt;/h2&gt;
&lt;h3 id=&#34;1-deploy-testing-instrumentable-services&#34;&gt;1. Deploy testing instrumentable services&lt;/h3&gt;
&lt;p&gt;You can instrument any HTTP or HTTPS service in your Kubernetes cluster. If you prefer, you
can first try instrumenting the dummy services provided in this example.&lt;/p&gt;
&lt;p&gt;The following Kubernetes example file contains two Apache HTTP servers: one pretends to be
a company &lt;code&gt;website&lt;/code&gt; and the other pretends to be a documentation site (&lt;code&gt;docs&lt;/code&gt;).
Let&amp;rsquo;s ignore that both servers will just return an &amp;ldquo;It Works!&amp;rdquo; string when the root directory
is requested and a 404 error if any other path is requested.&lt;/p&gt;
&lt;p&gt;Copy the following contents into a file (for example, &lt;code&gt;sampleapps.yml&lt;/code&gt;) and deploy it with
the command &lt;code&gt;kubectl apply -f sampleapps.yml&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;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&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To test that they are up and running, open two terminal sessions and run one of
each command below on a different session:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;# Redirect website to local port 8080
kubectl port-forward services/website 8080:80

# Redirect docs site to local port 8081
kubectl port-forward services/docs 8081:80&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;From your computer, each request to &lt;code&gt;http://localhost:8080&lt;/code&gt; will be a
hypothetical request to the company website and each request to &lt;code&gt;http://localhost:8081&lt;/code&gt;
will be a hypothetical request to the documentation website.&lt;/p&gt;
&lt;h3 id=&#34;2-create-beyla-namespace&#34;&gt;2. Create &lt;code&gt;beyla&lt;/code&gt; namespace&lt;/h3&gt;
&lt;p&gt;Before configuring and deploying Beyla, let&amp;rsquo;s create a &lt;code&gt;beyla&lt;/code&gt; namespace.
We will group there all the permissions, configurations and deployments
related to it:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;kubectl create namespace beyla&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;3-get-grafana-cloud-credentials&#34;&gt;3. Get Grafana Cloud credentials&lt;/h3&gt;
&lt;p&gt;Beyla can export metrics and traces to any OpenTelemetry endpoint, as well as exposing metrics as a Prometheus endpoint. However, we recommend using the OpenTelemetry endpoint in Grafana Cloud. You can get a &lt;a href=&#34;/pricing/&#34;&gt;Free Grafana Cloud Account at Grafana&amp;rsquo;s website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;From the Grafana Cloud Portal, look for the &lt;strong&gt;OpenTelemetry&lt;/strong&gt; box and click &lt;strong&gt;Configure&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/quickstart/otel-cloud-portal-box.png&#34;
  alt=&#34;OpenTelemetry Grafana Cloud portal&#34; width=&#34;1002&#34;
     height=&#34;312&#34;/&gt;&lt;/p&gt;
&lt;p&gt;Under &lt;strong&gt;Password / API token&lt;/strong&gt; click &lt;strong&gt;Generate now&lt;/strong&gt; and follow the instructions to create a default API token.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Environment Variables&lt;/strong&gt; will be populated with a set of standard OpenTelemetry environment variables which will provide the connection endpoint and credentials information for Beyla.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/quickstart/otlp-connection-headers.png&#34;
  alt=&#34;OTLP connection headers&#34; width=&#34;1592&#34;
     height=&#34;998&#34;/&gt;&lt;/p&gt;
&lt;p&gt;From the &lt;strong&gt;Environment Variables&lt;/strong&gt; section, copy the &lt;code&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/code&gt; and &lt;code&gt;OTEL_EXPORTER_OTLP_HEADERS&lt;/code&gt;
values and create a new secret from them. For example, create the following secret file and apply it:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: v1
kind: Secret
metadata:
  namespace: beyla
  name: grafana-credentials
type: Opaque
stringData:
  otlp-endpoint: &amp;#34;https://otlp-gateway-prod-eu-west-0.grafana.net/otlp&amp;#34;
  otlp-headers: &amp;#34;Authorization=Basic ...rest of the secret header value...&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;3-configure-and-run-beyla&#34;&gt;3. Configure and run Beyla&lt;/h3&gt;
&lt;p&gt;Next, you need to provide Beyla with permissions to watch and inspect the metadata of the
diverse Kubernetes resources that Beyla&amp;rsquo;s discovery mechanism requires. You must create
the following YAML file and apply it:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: beyla
  name: beyla
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: beyla
rules:
  - apiGroups: [&amp;#34;apps&amp;#34;]
    resources: [&amp;#34;replicasets&amp;#34;]
    verbs: [&amp;#34;list&amp;#34;, &amp;#34;watch&amp;#34;]
  - apiGroups: [&amp;#34;&amp;#34;]
    resources: [&amp;#34;pods&amp;#34;]
    verbs: [&amp;#34;list&amp;#34;, &amp;#34;watch&amp;#34;]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: beyla
subjects:
  - kind: ServiceAccount
    name: beyla
    namespace: beyla
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: beyla&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And now, deploy Beyla by creating the following Kubernetes entities:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;ConfigMap&lt;/code&gt; storing the &lt;code&gt;beyla-config.yml&lt;/code&gt; Beyla configuration file, which defines
the service discovery criteria. To verify that Beyla is able to discriminate
by service instance even if they run the same image and executable,
Beyla is configured to select ONLY the &lt;code&gt;docs&lt;/code&gt; Apache web server.&lt;/li&gt;
&lt;li&gt;A Beyla &lt;code&gt;DaemonSet&lt;/code&gt; providing the Beyla pod and its configuration:
&lt;ul&gt;
&lt;li&gt;Loads the &lt;code&gt;beyla-config.yml&lt;/code&gt; file from the &lt;code&gt;ConfigMap&lt;/code&gt;, as specified in the &lt;code&gt;BEYLA_CONFIG_PATH&lt;/code&gt;
environment variable.&lt;/li&gt;
&lt;li&gt;References to the &lt;code&gt;grafana-secrets&lt;/code&gt; values for the endpoint and credentials.&lt;/li&gt;
&lt;li&gt;Uses the &lt;code&gt;beyla&lt;/code&gt; &lt;code&gt;ServiceAccount&lt;/code&gt; to get all the permissions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Copy and deploy the following YAML file:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: v1
kind: ConfigMap
metadata:
  namespace: beyla
  name: beyla-config
data:
  beyla-config.yml: |
    # this is required to enable kubernetes discovery and metadata
    attributes:
      kubernetes:
        enable: true
    # this will provide automatic routes report while minimizing cardinality
    routes:
      unmatched: heuristic
    # let&amp;#39;s instrument only the docs server
    discovery:
      services:
        - k8s_deployment_name: &amp;#34;^docs$&amp;#34;
        # uncomment the following line to also instrument the website server
        # - k8s_deployment_name: &amp;#34;^website$&amp;#34;
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  namespace: beyla
  name: beyla
spec:
  selector:
    matchLabels:
      instrumentation: beyla
  template:
    metadata:
      labels:
        instrumentation: beyla
    spec:
      serviceAccountName: beyla
      hostPID: true # mandatory!
      containers:
        - name: beyla
          image: grafana/beyla:1.2
          imagePullPolicy: IfNotPresent
          securityContext:
            privileged: true # mandatory!
            readOnlyRootFilesystem: true
          volumeMounts:
            - mountPath: /config
              name: beyla-config
            - mountPath: /var/run/beyla
              name: var-run-beyla
          env:
            - name: BEYLA_CONFIG_PATH
              value: &amp;#34;/config/beyla-config.yml&amp;#34;
            - name: OTEL_EXPORTER_OTLP_ENDPOINT
              valueFrom:
                secretKeyRef:
                  name: grafana-credentials
                  key: otlp-endpoint
            - name: OTEL_EXPORTER_OTLP_HEADERS
              valueFrom:
                secretKeyRef:
                  name: grafana-credentials
                  key: otlp-headers
      volumes:
        - name: beyla-config
          configMap:
            name: beyla-config
        - name: var-run-beyla
          emptyDir: {}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Also notice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To run in DaemonSet mode, Beyla requires to have access to all the
processes in the node. Then the Beyla Pod requires to run with &lt;code&gt;hostPID: true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The Beyla container needs to run with &lt;code&gt;privileged: true&lt;/code&gt;, as it requires
to perform privileged actions such as loading BPF programs and creating
BPF maps. For running Beyla as &lt;code&gt;unprivileged&lt;/code&gt; container, i.e. without the
&lt;code&gt;privileged: true&lt;/code&gt; option, visit the
&lt;a href=&#34;../../setup/kubernetes/#deploy-beyla-unprivileged&#34;&gt;Deploy Beyla unprivileged&lt;/a&gt;
guide.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;4-test-your-instrumented-services-and-see-the-results-in-grafana&#34;&gt;4. Test your instrumented services and see the results in Grafana&lt;/h3&gt;
&lt;p&gt;With the &lt;code&gt;kubectl port-forward&lt;/code&gt; commands from the firs step still running,
test both web server instances. For example:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;curl http://localhost:8080
curl http://localhost:8080/foo
curl http://localhost:8081
curl http://localhost:8081/foo&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Some requests will return 404 error, but it&amp;rsquo;s OK because they are also instrumented.&lt;/p&gt;
&lt;p&gt;Now, go to the instance in Grafana Cloud, and from the &lt;strong&gt;Explore&lt;/strong&gt; section in the left panel, select the data source for the traces (usually named &lt;code&gt;grafanacloud-&amp;lt;your user name&amp;gt;-traces&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/k8s/select-traces.png&#34;
  alt=&#34;Select the traces data source&#34; width=&#34;1896&#34;
     height=&#34;440&#34;/&gt;&lt;/p&gt;
&lt;p&gt;To search for all the traces, select the &lt;strong&gt;Search&lt;/strong&gt; box in the Query bar, leave the form empty, and click &lt;strong&gt;Run query&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/k8s/run-query.png&#34;
  alt=&#34;Searching for all the traces in the system&#34; width=&#34;1766&#34;
     height=&#34;904&#34;/&gt;&lt;/p&gt;
&lt;p&gt;This will show the traces for the &lt;code&gt;docs&lt;/code&gt; instance (port 8081). You might see traces from your own services, but shouldn&amp;rsquo;t see traces from the &lt;code&gt;website&lt;/code&gt; service, as it has not been instrumented by Beyla.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/k8s/tut-traces-list.png&#34;
  alt=&#34;Grafana Cloud list of traces&#34; width=&#34;1614&#34;
     height=&#34;316&#34;/&gt;&lt;/p&gt;
&lt;p&gt;In the trace details, the resource attributes of the traces are decorated with the metadata of the Kubernetes Pod running the instrumented service:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/k8s/tut-trace-details.png&#34;
  alt=&#34;Details of the trace&#34; width=&#34;1630&#34;
     height=&#34;1470&#34;/&gt;&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../configure/options/&#34;&gt;Documentation: Beyla configuration options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;../../setup/kubernetes/&#34;&gt;Documentation: run Beyla as Kubernetes DaemonSet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="beyla-and-kubernetes-walkthrough">Beyla and Kubernetes walkthrough&lt;/h1>
&lt;p>Kubernetes is fully integrated into the Beyla operation mode.&lt;/p>
&lt;p>On one side, metrics and traces can be decorated
with the metadata of the kubernetes entities running the automatically instrumented
services.&lt;/p></description></item><item><title>Getting started with Beyla</title><link>https://grafana.com/docs/beyla/v1.6.x/tutorial/getting-started/</link><pubDate>Mon, 17 Mar 2025 08:44:01 +0100</pubDate><guid>https://grafana.com/docs/beyla/v1.6.x/tutorial/getting-started/</guid><content><![CDATA[&lt;h1 id=&#34;getting-started-with-beyla&#34;&gt;Getting started with Beyla&lt;/h1&gt;
&lt;p&gt;To reduce the time it takes to instrument an application and improve the adoption of Application Observability, Grafana built Beyla, an eBPF auto-instrumentation tool, that is able to report transactions span information, as well as &lt;a href=&#34;/blog/2018/08/02/the-red-method-how-to-instrument-your-services/&#34;&gt;RED metrics&lt;/a&gt; for Linux HTTP/S and gRPC services, without any application code or configuration changes.&lt;/p&gt;
&lt;h2 id=&#34;ebpf-overview&#34;&gt;eBPF overview&lt;/h2&gt;
&lt;p&gt;eBPF stands for Extended Berkeley Packet Filter, and allows attaching applications to different points of the Linux Kernel. eBPF applications run in privileged mode and allow the runtime information of the Linux Kernel to be inspected: system calls, network stack, as well as inserting probes in user space applications.&lt;/p&gt;
&lt;p&gt;The eBPF applications are safe, they are compiled for their own &lt;a href=&#34;https://docs.kernel.org/bpf/instruction-set.html&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Virtual Machine instruction set&lt;/a&gt; and run in a sandboxed environment that verifies each loaded eBPF program for memory access safety and finite execution time. Unlike older technologies, such as the natively-compiled Kprobes and Uprobes, there is no chance that a poorly programmed probe will cause the Linux Kernel to hang.&lt;/p&gt;
&lt;p&gt;After being the eBPF binaries have been verified they are compiled with a Just-In-Time (JIT) compiler for the native host architecture (x86-64, ARM64, etc). This allows for efficient and fast execution.&lt;/p&gt;
&lt;p&gt;The eBPF code is loaded from ordinary applications running in user space. The kernel and the user space applications can share information through a set of well defined communication mechanisms, which are provided by the eBPF specification. For example: ring buffers, arrays, hash maps, etc.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/ebpf-arch.svg&#34;
  alt=&#34;Beyla eBPF architecture&#34;/&gt;&lt;/p&gt;
&lt;h2 id=&#34;running-an-instrumented-service&#34;&gt;Running an instrumented service&lt;/h2&gt;
&lt;p&gt;For this quick start tutorial, instrument any HTTP, HTTPS or gRPC Go service that uses any of the following libraries:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Standard &lt;code&gt;net/http&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/gorilla/mux&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Gorilla Mux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gin-gonic.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Gin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/grpc/grpc-go&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;gRPC-Go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HTTP and HTTPS services written in other languages can also be instrumented:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node.js (HTTP 1.1 and HTTPS with OpenSSL)&lt;/li&gt;
&lt;li&gt;Python (HTTP 1.1 and HTTPS with OpenSSL)&lt;/li&gt;
&lt;li&gt;Rust (HTTP 1.1 and HTTPS with OpenSSL)&lt;/li&gt;
&lt;li&gt;Ruby (HTTP 1.1 and HTTPS with OpenSSL)&lt;/li&gt;
&lt;li&gt;.NET Core 6&#43; (HTTP 1.1 and HTTPS with OpenSSL)&lt;/li&gt;
&lt;li&gt;Java (HTTP 1.1)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The HTTP 1.1 and OpenSSL support is generic, services written in different programming languages than those listed above might work, but haven&amp;rsquo;t been tested.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t have a service to instrument, create a &lt;code&gt;server.go&lt;/code&gt; file with the following code:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Go&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-go&#34;&gt;package main

import (
	&amp;#34;net/http&amp;#34;
	&amp;#34;strconv&amp;#34;
	&amp;#34;time&amp;#34;
)

func handleRequest(rw http.ResponseWriter, req *http.Request) {
	status := 200
	for k, v := range req.URL.Query() {
		if len(v) == 0 {
			continue
		}
		switch k {
		case &amp;#34;status&amp;#34;:
			if s, err := strconv.Atoi(v[0]); err == nil {
				status = s
			}
		case &amp;#34;delay&amp;#34;:
			if d, err := time.ParseDuration(v[0]); err == nil {
				time.Sleep(d)
			}
		}
	}
	rw.WriteHeader(status)
}

func main() {
	http.ListenAndServe(&amp;#34;:8080&amp;#34;, http.HandlerFunc(handleRequest))
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The code implements an HTTP service that accepts request on port 8080. The HTTP handler behavior can be specified with the following query parameters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;status&lt;/code&gt; will override the returned HTTP status code (which defaults to 200). For example &lt;code&gt;curl -v &amp;quot;http://localhost:8080/foo?status=404&amp;quot;&lt;/code&gt; will return a 404 status code.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delay&lt;/code&gt; will artificially increase the service response time. For example &lt;code&gt;curl &amp;quot;http://localhost:8080/bar?delay=3s&amp;quot;&lt;/code&gt; will take at least 3 seconds to complete.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Download the &lt;a href=&#34;/docs/beyla/latest/tutorial/resources/server.go&#34;&gt;server.go&lt;/a&gt; file from this tutorial.&lt;/p&gt;
&lt;p&gt;Run the test HTTP service with the following command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;go run server.go&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;instrument-a-service&#34;&gt;Instrument a service&lt;/h2&gt;
&lt;p&gt;Set up Beyla as a standalone linux process by following the &lt;a href=&#34;../../setup/standalone/&#34;&gt;standalone setup&lt;/a&gt; documentation.&lt;/p&gt;
&lt;p&gt;First, we will locally check that Beyla is able to instrument the provided test server application,
after configuring it to print the traces to the standard output.&lt;/p&gt;
&lt;p&gt;Set environment variables and run Beyla:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;BEYLA_PRINT_TRACES=true BEYLA_OPEN_PORT=8080 sudo -E beyla&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;BEYLA_PRINT_TRACES=true&lt;/code&gt; configuration option tells Beyla to log any trace to the standard output.
The &lt;code&gt;BEYLA_OPEN_PORT=8080&lt;/code&gt; option tells Beyla to instrument the service that owns the port 8080.
Since Beyla requires administrator rights to load eBPF programs, the &lt;code&gt;beyla&lt;/code&gt; command
must run with &lt;code&gt;sudo -E&lt;/code&gt; (or as a &lt;code&gt;root&lt;/code&gt; user).&lt;/p&gt;
&lt;p&gt;After running the above command, you should see a log message confirming that the
test service has been found:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;time=2023-11-14T09:10:00.513Z level=INFO msg=&amp;#34;instrumenting process&amp;#34;
component=discover.TraceAttacher cmd=/tmp/go-build898688565/b001/exe/server pid=8710&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now, open a new terminal and send a few HTTP GET calls to the test service:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;curl -v &amp;#34;http://localhost:8080/hello&amp;#34;
curl -v &amp;#34;http://localhost:8080/bye&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For each request, Beyla will log trace information to the first terminal:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;2023-11-14 09:11:13 (2.89ms[859.99µs]) 200 GET /hello
  [127.0.0.1]-&amp;gt;[localhost:8080] size:0B svc=[{server go your-hostname-8710}]

2023-11-14 09:11:13 (1.87ms[191µs]) 200 GET /bye
  [127.0.0.1]-&amp;gt;[localhost:8080] size:0B svc=[{server go your-hostname-8710}]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The output format is:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;Request_time (response_duration) status_code http_method path
  source-&amp;gt;destination request_size service_id&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Experiment with the &lt;code&gt;curl&lt;/code&gt; command and make additional requests to see how it affects the trace output. For example, the following request would send a 6-bytes POST request and the service will take 200ms to respond:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;curl -X POST -d &amp;#34;abcdef&amp;#34; &amp;#34;http://localhost:8080/post?delay=200ms&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Beyla will log the following trace information:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;2023-11-14 09:12:49 (208.32ms[206.79ms]) 200 POST /post
[127.0.0.1]-&amp;gt;[localhost:8080] size:6B svc=[{server go your-hostname-8710}]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;send-data-to-grafana-cloud&#34;&gt;Send data to Grafana Cloud&lt;/h2&gt;
&lt;p&gt;Once we have verified that our application is correctly instrumented, we can set up
a Grafana Cloud OpenTelemetry exporter to read the generated traces and forward them
to Grafana Cloud. You can get a &lt;a href=&#34;/pricing/&#34;&gt;Free Grafana Cloud Account at Grafana&amp;rsquo;s website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For information on how to configure Beyla to submit data to other &lt;a href=&#34;https://opentelemetry.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;OpenTelemetry&lt;/a&gt;
collectors, or how to generate &lt;a href=&#34;https://prometheus.io&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Prometheus&lt;/a&gt; metrics, see the
&lt;a href=&#34;../../configure/options/&#34;&gt;configuration options&lt;/a&gt; documentation.&lt;/p&gt;
&lt;p&gt;There are two ways to forward your OpenTelemetry traces to Grafana Cloud:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using &lt;a href=&#34;/docs/alloy/&#34;&gt;Grafana Alloy&lt;/a&gt; and configuring Beyla to forward the traces to it via
the standard OpenTelemetry export.&lt;/li&gt;
&lt;li&gt;Configuring Beyla to submit data directly to the
&lt;a href=&#34;/docs/grafana-cloud/send-data/otlp/send-data-otlp/&#34;&gt;Grafana Cloud OpenTelemetry Protocol endpoint&lt;/a&gt;,
as shown in this tutorial.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;running-grafana-beyla-with-your-grafana-credentials&#34;&gt;Running Grafana Beyla with your Grafana Credentials&lt;/h3&gt;
&lt;p&gt;In your Grafana Cloud Portal, click on the &amp;ldquo;Details&amp;rdquo; button in the &amp;ldquo;OpenTelemetry&amp;rdquo; box. Next,
copy your Grafana OTLP Endpoint and Instance ID, as in the image below.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/otlp-connection-details.png&#34;
  alt=&#34;Beyla OTLP connection details&#34; width=&#34;966&#34;
     height=&#34;1310&#34;/&gt;&lt;/p&gt;
&lt;p&gt;Also generate a Password/API token with metrics push privileges.&lt;/p&gt;
&lt;p&gt;Now you can run Beyla by using the above information to set the
&lt;code&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/code&gt;, &lt;code&gt;GRAFANA_CLOUD_INSTANCE_ID&lt;/code&gt; and &lt;code&gt;GRAFANA_CLOUD_API_KEY&lt;/code&gt;
environment variables.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;GRAFANA_CLOUD_SUBMIT&lt;/code&gt; environment variable (whose value defaults to &lt;code&gt;traces&lt;/code&gt;)
lets you choose which type of data to submit to the Grafana OpenTelemetry endpoint:
metrics and/or traces. To make use of the metrics dashboard presented in the next section,
we will set &lt;code&gt;GRAFANA_CLOUD_SUBMIT=metrics&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;export OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp-gateway-prod-eu-west-0.grafana.net/otlp
export GRAFANA_CLOUD_SUBMIT=metrics
export GRAFANA_CLOUD_INSTANCE_ID=123456
export GRAFANA_CLOUD_API_KEY=&amp;#34;your api key here...&amp;#34;

BEYLA_OPEN_PORT=8080 sudo -E beyla&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Optionally, open another terminal and run the following command to generate some artificial load:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;while true; do curl -v &amp;#34;http://localhost:8080/service?delay=1s&amp;#34;; done&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To verify that metrics are properly received by Grafana, you can go to the left panel,
choose the Explore tab and your Prometheus data source. Next, write &lt;code&gt;http_&lt;/code&gt; in the
Metrics Browser input field and you should see the available metric names in the auto-complete drop-down.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/dropdown-metrics-v1.0.png&#34;
  alt=&#34;Beyla metrics&#34; width=&#34;968&#34;
     height=&#34;744&#34;/&gt;&lt;/p&gt;
&lt;h2 id=&#34;add-the-beyla-red-metrics-dashboard&#34;&gt;Add the Beyla RED Metrics Dashboard&lt;/h2&gt;
&lt;p&gt;You could start composing your PromQL queries for better visualization of
your auto-instrumented RED metrics; to save you time, we provide a sample
&lt;a href=&#34;/grafana/dashboards/19923-beyla-red-metrics/&#34;&gt;public dashboard with some basic information&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To import the sample dashboard into your Grafana instance, choose &amp;ldquo;Dashboards&amp;rdquo; in the Grafana left panel.
Next, in the Dashboards page, click on the &amp;ldquo;New&amp;rdquo; drop-down menu and select &amp;ldquo;Import&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/import-dashboard.png&#34;
  alt=&#34;Beyla import dashboard&#34; width=&#34;1976&#34;
     height=&#34;864&#34;/&gt;&lt;/p&gt;
&lt;p&gt;In the &amp;ldquo;Import via grafana.com&amp;rdquo; textbox, copy the Grafana ID from the
&lt;a href=&#34;/grafana/dashboards/19923-beyla-red-metrics/&#34;&gt;Beyla RED Metrics&lt;/a&gt;
dashboard: &lt;code&gt;19923&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Rename the dashboard to match your service, select the folder and, most importantly, select the
data source in the &lt;code&gt;prometheus-data-source&lt;/code&gt; drop-down at the bottom.&lt;/p&gt;
&lt;p&gt;And &lt;em&gt;voilà!&lt;/em&gt; you can see some of your test RED metrics:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/beyla-dashboard-screenshot-v1.0.png&#34;
  alt=&#34;Beyla RED metrics&#34; width=&#34;1866&#34;
     height=&#34;1264&#34;/&gt;&lt;/p&gt;
&lt;p&gt;The dashboard contains the following components:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A list with the slowest HTTP routes for all instrumented services. Since you only
have a single service, only one entry appears. If you configure Beyla to
&lt;a href=&#34;../../configure/options/#routes-decorator&#34;&gt;report the HTTP routes&lt;/a&gt;,
many entries could appear there, one for each HTTP path seen by the server.&lt;/li&gt;
&lt;li&gt;A list with the slowest GRPC methods. Since the test service in this tutorial only
serves HTTP, this table is empty.&lt;/li&gt;
&lt;li&gt;For each instrumented service, a list of RED metrics for the inbound (server) traffic. This includes:
&lt;ul&gt;
&lt;li&gt;Duration: average and top percentiles for both HTTP and gRPC traffic.&lt;/li&gt;
&lt;li&gt;Request rate: number of requests per second, faceted by its HTTP or gRPC return code.&lt;/li&gt;
&lt;li&gt;Error rate as a percentage of 5xx HTTP responses or non-zero gRPC responses over the total
of the requests. They are faceted by return code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For each instrumented service, a list of RED metrics for the outbound (client) traffic. In
the above screenshot they are empty because the test service does not perform HTTP or gRPC
calls to other services.
&lt;ul&gt;
&lt;li&gt;The Duration, Request Rate and Errors charts are analogues to the inbound traffic charts,
with the only difference that 4xx return codes are also considered errors on the
client side.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the top of the chart, you can use the &amp;ldquo;Service&amp;rdquo; dropdown to filter the services you
want to visualize.&lt;/p&gt;
&lt;h2 id=&#34;conclusions-and-future-work&#34;&gt;Conclusions and future work&lt;/h2&gt;
&lt;p&gt;eBPF proved to be a low-overhead, safe, and reliable way to observe some basic metrics for
HTTP/gRPC services. Beyla is not a replacement for language
specific agents, however it significantly decreases the landing time of your application insights in Grafana.
Beyla does not require any code changes, recompilation nor repackaging, simply run
it together with your service, and your application metrics will start to flow.&lt;/p&gt;
&lt;p&gt;eBPF also allows you to get deeper insights which manual instrumentation doesn&amp;rsquo;t. For example,
Beyla is able to show you how much time a request is enqueued, after
the connection is established, and before its code is actually executed (requires &lt;a href=&#34;../../configure/options/#otel-traces-exporter&#34;&gt;exporting
OpenTelemetry traces&lt;/a&gt;,
but this functionality is not explained in this tutorial).&lt;/p&gt;
&lt;p&gt;Beyla has its limitations too. It only provides generic metrics and
transaction level trace span information. Language agents and manual
instrumentation is still recommended, so that you can specify the granularity of each
part of the code to be instrumented, putting the focus on your critical operations.&lt;/p&gt;
&lt;p&gt;Another limitation to consider is that Beyla requires
elevated privileges; not actually a &lt;code&gt;root&lt;/code&gt; user, but at least it has to run with the
&lt;code&gt;CAP_SYS_ADMIN&lt;/code&gt; capability. If you run the tool as a container (Docker, Kubernetes&amp;hellip;), it
has to be privileged.&lt;/p&gt;
&lt;p&gt;In the future, we plan to add metrics about other well-established protocols, like
database or message queuing connections.&lt;/p&gt;
&lt;p&gt;Distributed tracing is only supported for Go services, while other programming language
support remains on the road-map. Distributed tracing can correlate
requests from multiple services (web, database, messaging&amp;hellip;). One complexity of
distributed tracing is the injection of client-side headers and matching them to the context of
the server-side requests. Each release is making progressive advances towards this goal.&lt;/p&gt;
&lt;p&gt;Another shorter term goal is to reduce the surface of the code that requires administrative
privileges, executing a small eBPF loader with &lt;code&gt;root&lt;/code&gt; or &lt;code&gt;CAP_SYS_ADMIN&lt;/code&gt; privileges,
and running the rest of data processing/exposition with normal user privileges.&lt;/p&gt;
]]></content><description>&lt;h1 id="getting-started-with-beyla">Getting started with Beyla&lt;/h1>
&lt;p>To reduce the time it takes to instrument an application and improve the adoption of Application Observability, Grafana built Beyla, an eBPF auto-instrumentation tool, that is able to report transactions span information, as well as &lt;a href="/blog/2018/08/02/the-red-method-how-to-instrument-your-services/">RED metrics&lt;/a> for Linux HTTP/S and gRPC services, without any application code or configuration changes.&lt;/p></description></item><item><title>Run Beyla in Kubernetes using Grafana Alloy Helm's chart</title><link>https://grafana.com/docs/beyla/v1.6.x/tutorial/helm-alloy/</link><pubDate>Mon, 17 Mar 2025 08:44:01 +0100</pubDate><guid>https://grafana.com/docs/beyla/v1.6.x/tutorial/helm-alloy/</guid><content><![CDATA[&lt;h1 id=&#34;run-beyla-in-kubernetes-using-grafana-alloy-helms-chart&#34;&gt;Run Beyla in Kubernetes using Grafana Alloy Helm&amp;rsquo;s chart&lt;/h1&gt;
&lt;p&gt;Grafana Alloy is a vendor-neutral distribution of the OpenTelemetry Collector.
Alloy offers native pipelines for OpenTelemetry, Prometheus, and other telemetry signals.&lt;/p&gt;
&lt;p&gt;Grafana Alloy bundles Beyla allowing you to instrument your applications at the same time
you instrument your infrastructure. It also provides a Helm chart to deploy Alloy in Kubernetes.&lt;/p&gt;
&lt;p&gt;In this tutorial, you learn how to deploy Beyla in Kubernetes using Grafana Alloy Helm&amp;rsquo;s chart. It&amp;rsquo;s based on the examples from the &lt;a href=&#34;../k8s-walkthrough/&#34;&gt;Beyla and Kubernetes walkthrough&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A Kubernetes cluster, you can use &lt;a href=&#34;https://kind.sigs.k8s.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;kind&lt;/a&gt; to create a local cluster&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubectl&lt;/code&gt; installed and configured for your cluster&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://helm.sh/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Helm&lt;/a&gt; installed&lt;/li&gt;
&lt;li&gt;A Grafana Cloud account or a compatible Prometheus and/or OpenTelemetry backend to receive the data&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;1-prepare-the-alloy-environment-in-kubernetes&#34;&gt;1. Prepare the Alloy environment in Kubernetes&lt;/h3&gt;
&lt;p&gt;You need to install the Helm chart for Grafana Alloy in your Kubernetes cluster.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;helm install --namespace alloy alloy grafana/alloy&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This command installs the Grafana Alloy Helm chart in the &lt;code&gt;alloy&lt;/code&gt; namespace.&lt;/p&gt;
&lt;h3 id=&#34;2-deploy-services&#34;&gt;2. Deploy services&lt;/h3&gt;
&lt;p&gt;You can instrument any HTTP or HTTPS service in your Kubernetes cluster.&lt;/p&gt;
&lt;p&gt;Copy the following contents into a file, for example &lt;code&gt;sampleapps.yml&lt;/code&gt;, and deploy it with
the command &lt;code&gt;kubectl apply -f sampleapps.yml&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;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&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;3-configure-credentials&#34;&gt;3. Configure credentials&lt;/h3&gt;
&lt;p&gt;Alloy can export metrics and traces to any OpenTelemetry endpoint, as well as exposing metrics as a Prometheus endpoint. However, it&amp;rsquo;s recommend using the Prometheus and Tempo remote write endpoints in Grafana Cloud. You can get a &lt;a href=&#34;/pricing/&#34;&gt;free Grafana Cloud Account&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;From the Grafana Cloud Portal, look for the &lt;strong&gt;Prometheus&lt;/strong&gt; box and click &lt;strong&gt;Send Metrics&lt;/strong&gt;. For the &lt;strong&gt;Tempo&lt;/strong&gt; box, click &lt;strong&gt;Send Traces&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Create a &lt;code&gt;secrets.yml&lt;/code&gt; file with your Grafana Cloud credentials for Prometheus and Tempo remote write. Deploy it with the command &lt;code&gt;kubectl apply -f secrets.yml&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: v1
kind: Secret
metadata:
  namespace: alloy
  name: grafana-credentials
type: Opaque
stringData:
  prometheus-rw-user: &amp;#34;prom-user&amp;#34;
  prometheus-rw-pwd: &amp;#34;prom-pwd&amp;#34;
  tempo-rw-user: &amp;#34;tempo-user&amp;#34;
  tempo-rw-pwd: &amp;#34;tempo-pwd&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;3-create-a-configmap-with-alloy-configuration&#34;&gt;3. Create a ConfigMap with Alloy configuration&lt;/h3&gt;
&lt;p&gt;Create a &lt;code&gt;ConfigMap&lt;/code&gt; with the Alloy configuration. Copy the following contents into a file, for example &lt;code&gt;config.alloy&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;beyla.ebpf &amp;#34;default&amp;#34; {
	attributes {
		kubernetes {
			enable = &amp;#34;true&amp;#34;
		}
	}

	discovery {
		services {
			exe_path   = &amp;#34;http&amp;#34;
			open_ports = &amp;#34;80&amp;#34;
		}
	}

	output {
		traces = [otelcol.exporter.otlp.grafana_cloud_tempo.input]
	}
}

otelcol.exporter.otlp &amp;#34;grafana_cloud_tempo&amp;#34; {
	client {
		endpoint = &amp;#34;tempo-us-central1.grafana.net:443&amp;#34;
		auth     = otelcol.auth.basic.grafana_cloud_tempo.handler
	}
}

otelcol.auth.basic &amp;#34;grafana_cloud_tempo&amp;#34; {
	username = env(&amp;#34;TEMPO_REMOTE_WRITE_USERNAME&amp;#34;)
	password = env(&amp;#34;TEMPO_REMOTE_WRITE_PASSWORD&amp;#34;)
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Deploy the configuration with the command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Bash&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-bash&#34;&gt;kubectl create configmap --namespace alloy alloy-config &amp;#34;--from-file=config.alloy=./config.alloy&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With this configuration Beyla instruments the services running in the Kubernetes cluster and send traces to Grafana Cloud Tempo and metrics to Prometheus.&lt;/p&gt;
&lt;p&gt;The argument &lt;code&gt;discovery &amp;gt; services &amp;gt; exe_path&lt;/code&gt; specifies the path to the executable of the services to instrument. The &lt;code&gt;discovery &amp;gt; services &amp;gt; open_ports&lt;/code&gt; argument specifies the port where the services are listening.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;attributes &amp;gt; kubernetes &amp;gt; enable&lt;/code&gt; enables Kubernetes decoration for metrics and traces, which adds the metadata of the Kubernetes entities running the automatically instrumented services.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;prometheus.scrape&lt;/code&gt; section configures the Prometheus scrape configuration to collect the metrics from Beyla. The &lt;code&gt;prometheus.remote_write&lt;/code&gt; section configures the remote write to send the metrics to Grafana Cloud Prometheus.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;output&lt;/code&gt; section configures that Beyla component sends traces to &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; component. The &lt;code&gt;otelcol.exporter.otlp&lt;/code&gt; section configures the &lt;a href=&#34;/docs/alloy/latest/reference/components/otelcol.exporter.otlp&#34;&gt;OTLP exporter&lt;/a&gt; to send the traces to Grafana Cloud Tempo.&lt;/p&gt;
&lt;p&gt;For further details on the configuration options, refer to the documentation of the &lt;a href=&#34;/docs/alloy/latest/reference/components/beyla.ebpf&#34;&gt;Grafana Alloy Beyla component&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;4-deploy-alloy-with-helm&#34;&gt;4. Deploy Alloy with Helm&lt;/h3&gt;
&lt;p&gt;Create a &lt;code&gt;values.yaml&lt;/code&gt; with the configuration for the Alloy Helm chart. Copy the following contents into a file, for example &lt;code&gt;values.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;# -- Overrides the chart&amp;#39;s name. Used to change the infix in the resource names.
nameOverride: null

# -- Overrides the chart&amp;#39;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 overriden for some specific use cases (e.g local registries, custom images, ...)
    registry: &amp;#34;&amp;#34;

    # -- 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 &amp;#34;agent&amp;#34;. Naming this field &amp;#34;agent&amp;#34; 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 &amp;#34;experimental&amp;#34;, &amp;#34;public-preview&amp;#34;, or &amp;#34;generally-available&amp;#34;.
  stabilityLevel: &amp;#34;public-preview&amp;#34;

  # -- 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 &amp;#34;HTTPS&amp;#34;
  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.io/docs/reference/generated/kubernetes-api/v1.24/#envfromsource-v1-core
  envFrom: []

  # -- Extra args to pass to `alloy run`: https://grafana.com/docs/alloy/latest/reference/cli/run/
  extraArgs: []

  # -- Extra ports to expose on the Alloy container.
  extraPorts: []
  # - name: &amp;#34;faro&amp;#34;
  #   port: 12347
  #   targetPort: 12347
  #   protocol: &amp;#34;TCP&amp;#34;

  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: &amp;#34;docker.io&amp;#34;
  # -- Grafana Alloy image repository.
  repository: grafana/alloy
  # -- (string) Grafana Alloy image tag. When empty, the Chart&amp;#39;s appVersion is
  # used.
  tag: null
  # -- Grafana Alloy image&amp;#39;s SHA256 digest (either in format &amp;#34;sha256:XYZ&amp;#34; or &amp;#34;XYZ&amp;#34;). 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: &amp;#34;ghcr.io&amp;#34;
    # -- 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 &amp;#34;sha256:XYZ&amp;#34; or &amp;#34;XYZ&amp;#34;). When set, will override `configReloader.image.tag`
    digest: &amp;#34;&amp;#34;
  # -- Override the args passed to the container.
  customArgs: []
  # -- Resource requests and limits to apply to the config reloader container.
  resources:
    requests:
      cpu: &amp;#34;1m&amp;#34;
      memory: &amp;#34;5Mi&amp;#34;
  # -- 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 &amp;#39;daemonset&amp;#39;, &amp;#39;deployment&amp;#39;, or &amp;#39;statefulset&amp;#39;.
  type: &amp;#39;daemonset&amp;#39;

  # -- Number of pods to deploy. Ignored when controller.type is &amp;#39;daemonset&amp;#39;.
  replicas: 1

  # -- Annotations to add to controller.
  extraAnnotations: {}

  # -- Whether to deploy pods in parallel. Only used when controller.type is
  # &amp;#39;statefulset&amp;#39;.
  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.io/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: &amp;#39;&amp;#39;

  # -- 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 &amp;#39;statefulset&amp;#39;.
  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 &amp;#39;statefulset&amp;#39;.
  volumeClaimTemplates: []

  ## -- Additional init containers to run.
  ## ref: https://kubernetes.io/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&amp;#39;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 &amp;#34;&amp;#34; or an IP address
  clusterIP: &amp;#39;&amp;#39;
  # -- Value for internal traffic policy. &amp;#39;Cluster&amp;#39; or &amp;#39;Local&amp;#39;
  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: &amp;#34;&amp;#34;
  # -- 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: &amp;#39;kube_(daemonset|deployment|pod|namespace|node|statefulset).&amp;#43;&amp;#39;
  #   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 &amp;gt;= 1.18 you should specify the ingress-controller via the field ingressClassName
  # See https://kubernetes.io/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: &amp;#34;true&amp;#34;
  labels: {}
  path: /
  faroPort: 12347

  # pathType is only for k8s &amp;gt;= 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 &amp;gt; 1.19
  # - path: /*
  #   pathType: Prefix
  #   backend:
  #     service:
  #       name: ssl-redirect
  #       port:
  #         name: use-annotation

  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Deploy the configuration with the command:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;helm upgrade --namespace alloy alloy grafana/alloy -f values.yaml&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;To run in DaemonSet mode, Beyla requires to have access to all the
processes in the node. Therefore set &lt;code&gt;hostPID: true&lt;/code&gt; the &lt;code&gt;controller&lt;/code&gt; section.&lt;/li&gt;
&lt;li&gt;The Beyla container needs to run with privileges as it requires
to perform privileged actions such as loading BPF programs and creating
BPF maps. Therefore set &lt;code&gt;privileged: true&lt;/code&gt; in &lt;code&gt;securityContext&lt;/code&gt; section. For running Beyla as &lt;code&gt;unprivileged&lt;/code&gt; container, that&amp;rsquo;s without the
&lt;code&gt;privileged: true&lt;/code&gt; option, visit the
&lt;a href=&#34;../../setup/kubernetes/#deploy-beyla-unprivileged&#34;&gt;Deploy Beyla unprivileged&lt;/a&gt;
guide.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;extraEnv&lt;/code&gt; section sets the environment variables for the Prometheus and Tempo remote write credentials.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;5-test-the-setup&#34;&gt;5. Test the setup&lt;/h3&gt;
&lt;p&gt;With the &lt;code&gt;kubectl port-forward&lt;/code&gt; commands from the first step still running,
test both web server instances. For example:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;curl http://localhost:8080
curl http://localhost:8080/foo
curl http://localhost:8081
curl http://localhost:8081/foo&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Navigate to the instance in Grafana Cloud, and from the &lt;strong&gt;Explore&lt;/strong&gt; section in the left panel, select the data source for the traces, named &lt;code&gt;grafanacloud-&amp;lt;your user name&amp;gt;-traces&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/k8s/select-traces.png&#34;
  alt=&#34;Select the traces data source&#34; width=&#34;1896&#34;
     height=&#34;440&#34;/&gt;&lt;/p&gt;
&lt;p&gt;To search for all the traces, select the &lt;strong&gt;Search&lt;/strong&gt; box in the Query bar, leave the form empty, and click &lt;strong&gt;Run query&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/k8s/run-query.png&#34;
  alt=&#34;Searching for all the traces in the system&#34; width=&#34;1766&#34;
     height=&#34;904&#34;/&gt;&lt;/p&gt;
&lt;p&gt;This shows the traces for the &lt;code&gt;docs&lt;/code&gt; instance on port 8081. You might see traces from your own services, but you shouldn&amp;rsquo;t see traces from the &lt;code&gt;website&lt;/code&gt; service, as it Beyla isn&amp;rsquo;t instrumenting it.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/k8s/tut-traces-list.png&#34;
  alt=&#34;Grafana Cloud list of traces&#34; width=&#34;1614&#34;
     height=&#34;316&#34;/&gt;&lt;/p&gt;
&lt;p&gt;In the trace details, the resource attributes of the traces have metadata of the Kubernetes Pod running the instrumented service:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;https://grafana.com/media/docs/grafana-cloud/beyla/tutorial/k8s/tut-trace-details.png&#34;
  alt=&#34;Details of the trace&#34; width=&#34;1630&#34;
     height=&#34;1470&#34;/&gt;&lt;/p&gt;
]]></content><description>&lt;h1 id="run-beyla-in-kubernetes-using-grafana-alloy-helms-chart">Run Beyla in Kubernetes using Grafana Alloy Helm&amp;rsquo;s chart&lt;/h1>
&lt;p>Grafana Alloy is a vendor-neutral distribution of the OpenTelemetry Collector.
Alloy offers native pipelines for OpenTelemetry, Prometheus, and other telemetry signals.&lt;/p></description></item></channel></rss>