# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: beyla-agent
  labels:
    app: beyla
spec:
  selector:
    matchLabels:
      app: beyla
  template:
    metadata:
      labels:
        app: beyla
      annotations:
        # allow beyla to write to /sys/fs/bpf by setting the
        # apparmor policy to unconfined.
        container.apparmor.security.beta.kubernetes.io/beyla: "unconfined"
    spec:
      serviceAccountName: beyla
      hostPID: true
      initContainers:
        - name: mount-bpf-fs
          image: grafana/beyla:1.8.6
          args:
          # Create the directory using the Pod UID, and mount the BPF filesystem.
          - 'mkdir -p /sys/fs/bpf/$BEYLA_BPF_FS_PATH && mount -t bpf bpf /sys/fs/bpf/$BEYLA_BPF_FS_PATH'
          command:
          - /bin/bash
          - -c
          - --
          securityContext:
            # The init container is privileged so that it can use bidirectional mount propagation
            privileged: true
          volumeMounts:
          - name: bpffs
            mountPath: /sys/fs/bpf
            # Make sure the mount is propagated back to the host so it can be used by the Beyla container
            mountPropagation: Bidirectional
          env:
            - name: KUBE_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: BEYLA_BPF_FS_PATH
              value: beyla-$(KUBE_NAMESPACE)
      containers:
        - name: beyla
          resources:
            requests:
              cpu: 10m
              memory: 100Mi
          image: grafana/beyla:1.8.6
          securityContext:
            seccompProfile:
              type: RuntimeDefault
            runAsUser: 0
            readOnlyRootFilesystem: true
            capabilities:
              add:
                - BPF
                - SYS_PTRACE
                - NET_RAW
                - CHECKPOINT_RESTORE
                - DAC_READ_SEARCH
                - PERFMON
              drop:
                - ALL
          env:
            - name: BEYLA_CONFIG_PATH
              value: "/config/beyla-config.yml"
            - name: KUBE_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: BEYLA_BPF_FS_PATH
              value: beyla-$(KUBE_NAMESPACE)
          volumeMounts:
          - name: bpffs
            mountPath: /sys/fs/bpf
            # Use HostToContainer to propagate the mount from the init container to the Beyla container
            mountPropagation: HostToContainer
          - name: beyla-config
            mountPath: /config
      volumes:
      - name: bpffs
        hostPath:
          path: /sys/fs/bpf
      - name: beyla-config
        configMap:
          name: beyla-config

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: beyla-config
data:
  beyla-config.yml: |
    discovery:
      services:
      # only gather metrics from workloads running as a pod
      - k8s_pod_name: .+
      skip_go_specific_tracers: true
    otel_metrics_export:
      features: []
    otel_traces_export:
      endpoint: http://otel-collector:4317
      interval: 30s
    attributes:
      instance_id:
        dns: false
      kubernetes:
        enable: true
        # drop_external only collects spans for kubernetes entities (e.g. pods), which reduces resource usage.
        drop_external: true
        # disable_informers prevents Beyla from watching k8s resources, and reduces the load on the kubernetes API Server.
        disable_informers: [replicaset, service, node]
    routes:
      unmatched: wildcard
    ebpf:
      bpf_fs_base_dir: /sys/fs/bpf
