diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bb9049..bab2339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## Unreleased + +- BREAKING: replaces the `grafana-agent` subchart with Grafana Alloy (`alloy` chart 1.13.1). Rename any `grafana-agent:` values overrides to `alloy:`. +- Pod `job` label changes from `/grafana-agent/grafana-agent` to `/alloy/alloy`; update queries and alerts that match the old label. +- Alloy listens on port 12345 instead of 80. + ## v0.3.0 - Adding prebuilt workspace dashboard & alerts diff --git a/README.gotmpl b/README.gotmpl index c7ec9db..6609f40 100644 --- a/README.gotmpl +++ b/README.gotmpl @@ -9,7 +9,7 @@ ## Overview This chart contains a highly opinionated set of integrations between Grafana, Loki, Prometheus, Alertmanager, and -Grafana Agent. +Alloy. Dashboards, alerts, and runbooks are preconfigured for monitoring [Coder](https://coder.com/) installations. @@ -64,11 +64,11 @@ global: ``` If you would like your logs scraped from a process outside Kubernetes, you need to mount the log file(s) in and -configure Grafana Agent to scrape them; here's an example configuration: +configure Alloy to scrape them; here's an example configuration: ```yaml -grafana-agent: - agent: +alloy: + alloy: mounts: extra: - mountPath: /var/log @@ -228,8 +228,8 @@ And open your web browser to http://localhost:9090/graph. Native histograms are an **experimental** Prometheus feature that remove the need to predefine bucket boundaries and instead provide higher-resolution, adaptive buckets (see [Prometheus docs](https://prometheus.io/docs/specs/native_histograms/) for details). Unlike classic histograms, which are sent in plain text, **native histograms require the protobuf protocol**. -In addition to running Prometheus with native histogram support, since the Prometheus Helm chart is configured with remote write, the Grafana Agent must be configured to scrape and remote write using protobuf. -Native histograms are **disabled by default**, but when you enable them globally, the Helm chart automatically updates the Grafana Agent configuration accordingly. +In addition to running Prometheus with native histogram support, since the Prometheus Helm chart is configured with remote write, the Alloy must be configured to scrape and remote write using protobuf. +Native histograms are **disabled by default**, but when you enable them globally, the Helm chart automatically updates the Alloy configuration accordingly. To enable native histograms, define this in your `values.yaml`: @@ -247,9 +247,9 @@ prometheus: - enable-feature=native-histograms ``` -After updating values, it might be required to restart the Grafana Agent so it picks up the new configuration: +After updating values, it might be required to restart the Alloy so it picks up the new configuration: ```bash -kubectl -n coder-observability rollout restart daemonset/grafana-agent +kubectl -n coder-observability rollout restart daemonset/alloy ``` ⚠️ **Important**: Classic and native histograms cannot be aggregated together. @@ -268,11 +268,11 @@ If you switch from classic to native histograms, dashboards may need to account * Native histograms are exposed directly under the metric name. * Example: query `coderd_workspace_creation_duration_seconds` in http://localhost:9090/graph. -3) Check Grafana Agent (if remote write is enabled): +3) Check Alloy (if remote write is enabled): To confirm, run: ```bash - kubectl -n coder-observability port-forward svc/grafana-agent 3030:80 + kubectl -n coder-observability port-forward svc/alloy 3030:12345 ``` Then open http://localhost:3030: * scrape configurations defined in `prometheus.scrape.cadvisor`, should have `enable_protobuf_negotiation: true` @@ -289,7 +289,7 @@ Each subchart can be disabled by setting the `enabled` field to `false`. | Subchart | Setting | |-----------------|-------------------------| | `grafana` | `grafana.enabled` | -| `grafana-agent` | `grafana-agent.enabled` | +| `alloy` | `alloy.enabled` | | `loki` | `loki.enabled` | | `prometheus` | `prometheus.enabled` | diff --git a/README.md b/README.md index c6198cf..1800a22 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## Overview This chart contains a highly opinionated set of integrations between Grafana, Loki, Prometheus, Alertmanager, and -Grafana Agent. +Alloy. Dashboards, alerts, and runbooks are preconfigured for monitoring [Coder](https://coder.com/) installations. @@ -22,7 +22,7 @@ Logs will be scraped from all pods in the Kubernetes cluster. ```bash helm repo add coder-observability https://helm.coder.com/observability -helm upgrade --install coder-observability coder-observability/coder-observability --version 0.7.4 --namespace coder-observability --create-namespace +helm upgrade --install coder-observability coder-observability/coder-observability --version 0.7.5 --namespace coder-observability --create-namespace ``` ## Requirements @@ -64,11 +64,11 @@ global: ``` If you would like your logs scraped from a process outside Kubernetes, you need to mount the log file(s) in and -configure Grafana Agent to scrape them; here's an example configuration: +configure Alloy to scrape them; here's an example configuration: ```yaml -grafana-agent: - agent: +alloy: + alloy: mounts: extra: - mountPath: /var/log @@ -228,8 +228,8 @@ And open your web browser to http://localhost:9090/graph. Native histograms are an **experimental** Prometheus feature that remove the need to predefine bucket boundaries and instead provide higher-resolution, adaptive buckets (see [Prometheus docs](https://prometheus.io/docs/specs/native_histograms/) for details). Unlike classic histograms, which are sent in plain text, **native histograms require the protobuf protocol**. -In addition to running Prometheus with native histogram support, since the Prometheus Helm chart is configured with remote write, the Grafana Agent must be configured to scrape and remote write using protobuf. -Native histograms are **disabled by default**, but when you enable them globally, the Helm chart automatically updates the Grafana Agent configuration accordingly. +In addition to running Prometheus with native histogram support, since the Prometheus Helm chart is configured with remote write, the Alloy must be configured to scrape and remote write using protobuf. +Native histograms are **disabled by default**, but when you enable them globally, the Helm chart automatically updates the Alloy configuration accordingly. To enable native histograms, define this in your `values.yaml`: @@ -247,9 +247,9 @@ prometheus: - enable-feature=native-histograms ``` -After updating values, it might be required to restart the Grafana Agent so it picks up the new configuration: +After updating values, it might be required to restart the Alloy so it picks up the new configuration: ```bash -kubectl -n coder-observability rollout restart daemonset/grafana-agent +kubectl -n coder-observability rollout restart daemonset/alloy ``` ⚠️ **Important**: Classic and native histograms cannot be aggregated together. @@ -268,11 +268,11 @@ If you switch from classic to native histograms, dashboards may need to account * Native histograms are exposed directly under the metric name. * Example: query `coderd_workspace_creation_duration_seconds` in http://localhost:9090/graph. -3) Check Grafana Agent (if remote write is enabled): +3) Check Alloy (if remote write is enabled): To confirm, run: ```bash - kubectl -n coder-observability port-forward svc/grafana-agent 3030:80 + kubectl -n coder-observability port-forward svc/alloy 3030:12345 ``` Then open http://localhost:3030: * scrape configurations defined in `prometheus.scrape.cadvisor`, should have `enable_protobuf_negotiation: true` @@ -284,8 +284,8 @@ If you switch from classic to native histograms, dashboards may need to account | Repository | Name | Version | |------------|------|---------| +| https://grafana.github.io/helm-charts | alloy | ~1.13.1 | | https://grafana.github.io/helm-charts | grafana | ~v7.3.7 | -| https://grafana.github.io/helm-charts | grafana-agent(grafana-agent) | ~0.37.0 | | https://grafana.github.io/helm-charts | loki | ~v6.7.3 | | https://grafana.github.io/helm-charts | pyroscope | ~v1.14.1 | | https://grafana.github.io/helm-charts | tempo | ~v1.23.0 | @@ -296,7 +296,7 @@ Each subchart can be disabled by setting the `enabled` field to `false`. | Subchart | Setting | |-----------------|-------------------------| | `grafana` | `grafana.enabled` | -| `grafana-agent` | `grafana-agent.enabled` | +| `alloy` | `alloy.enabled` | | `loki` | `loki.enabled` | | `prometheus` | `prometheus.enabled` | @@ -311,6 +311,24 @@ values which are defined [here](https://github.com/grafana/helm-charts/tree/main | Key | Type | Default | Description | |-----|------|---------|-------------| +| alloy.alloy.clustering.enabled | bool | `true` | | +| alloy.alloy.configMap.create | bool | `false` | | +| alloy.alloy.configMap.key | string | `"config.river"` | | +| alloy.alloy.configMap.name | string | `"collector-config"` | | +| alloy.alloy.extraArgs[0] | string | `"--disable-reporting=true"` | | +| alloy.alloy.mounts.dockercontainers | bool | `true` | | +| alloy.alloy.mounts.varlog | bool | `true` | | +| alloy.commonRelabellings | string | `"rule {\n source_labels = [\"__meta_kubernetes_namespace\"]\n target_label = \"namespace\"\n}\nrule {\n source_labels = [\"__meta_kubernetes_pod_name\"]\n target_label = \"pod\"\n}\n// coalesce the following labels and pick the first value; we'll use this to define the \"job\" label\nrule {\n source_labels = [\"__meta_kubernetes_pod_label_app_kubernetes_io_component\", \"app\", \"__meta_kubernetes_pod_container_name\"]\n separator = \"/\"\n target_label = \"__meta_app\"\n action = \"replace\"\n regex = \"^/*([^/]+?)(?:/.*)?$\" // split by the delimiter if it exists, we only want the first one\n replacement = \"${1}\"\n}\nrule {\n source_labels = [\"__meta_kubernetes_namespace\", \"__meta_kubernetes_pod_label_app_kubernetes_io_name\", \"__meta_app\"]\n separator = \"/\"\n target_label = \"job\"\n}\nrule {\n source_labels = [\"__meta_kubernetes_pod_container_name\"]\n target_label = \"container\"\n}\nrule {\n regex = \"__meta_kubernetes_pod_label_(statefulset_kubernetes_io_pod_name|controller_revision_hash)\"\n action = \"labeldrop\"\n}\nrule {\n regex = \"pod_template_generation\"\n action = \"labeldrop\"\n}\nrule {\n source_labels = [\"__meta_kubernetes_pod_phase\"]\n regex = \"Pending|Succeeded|Failed|Completed\"\n action = \"drop\"\n}\nrule {\n source_labels = [\"__meta_kubernetes_pod_node_name\"]\n action = \"replace\"\n target_label = \"node\"\n}\nrule {\n action = \"labelmap\"\n regex = \"__meta_kubernetes_pod_annotation_prometheus_io_param_(.+)\"\n replacement = \"__param_$1\"\n}"` | | +| alloy.controller.podAnnotations."prometheus.io/scrape" | string | `"true"` | | +| alloy.controller.type | string | `"daemonset"` | | +| alloy.crds.create | bool | `false` | | +| alloy.discovery | string | `"// Discover k8s nodes\ndiscovery.kubernetes \"nodes\" {\n role = \"node\"\n}\n\n// Discover k8s pods\ndiscovery.kubernetes \"pods\" {\n role = \"pod\"\n selectors {\n role = \"pod\"\n }\n}"` | | +| alloy.enabled | bool | `true` | | +| alloy.extraBlocks | string | `""` | | +| alloy.fullnameOverride | string | `"alloy"` | | +| alloy.podLogsRelabelRules | string | `""` | | +| alloy.podMetricsRelabelRules | string | `""` | | +| alloy.withOTLPReceiver | bool | `false` | | | global.alerts.enabled | bool | `true` | enable or disable alerting | | global.alerts.kind | string | `"configmap"` | the container resource kind in which alerts should be created; valid values are "prometheusrule" or "configmap" | | global.coder.alerts | object | `{"coderd":{"groups":{"CPU":{"delay":"10m","enabled":true,"period":"10m","thresholds":{"critical":0.9,"warning":0.8}},"IneligiblePrebuilds":{"delay":"10m","enabled":true,"thresholds":{"notify":1}},"Memory":{"delay":"10m","enabled":true,"thresholds":{"critical":0.9,"warning":0.8}},"Replicas":{"delay":"5m","enabled":true,"thresholds":{"critical":1,"notify":3,"warning":2}},"Restarts":{"delay":"1m","enabled":true,"period":"10m","thresholds":{"critical":3,"notify":1,"warning":2}},"UnprovisionedPrebuiltWorkspaces":{"delay":"10m","enabled":true,"thresholds":{"warn":1}},"WorkspaceBuildFailures":{"delay":"10m","enabled":true,"period":"10m","thresholds":{"critical":10,"notify":2,"warning":5}}}},"enterprise":{"groups":{"Licences":{"delay":"1m","enabled":true,"thresholds":{"critical":1,"warning":0.9}}}},"provisionerd":{"groups":{"Replicas":{"delay":"5m","enabled":true,"thresholds":{"critical":1,"notify":3,"warning":2}}}}}` | alerts for the various aspects of Coder | @@ -338,25 +356,6 @@ values which are defined [here](https://github.com/grafana/helm-charts/tree/main | global.telemetry.profiling.scrape_interval | string | `"60s"` | how often the collector will scrape pprof endpoints | | global.telemetry.profiling.scrape_timeout | string | `"70s"` | how long a request will be allowed to wait before being canceled, must be larger than scrape_interval | | global.zone | string | `"svc"` | | -| grafana-agent.agent.clustering.enabled | bool | `true` | | -| grafana-agent.agent.configMap.create | bool | `false` | | -| grafana-agent.agent.configMap.key | string | `"config.river"` | | -| grafana-agent.agent.configMap.name | string | `"collector-config"` | | -| grafana-agent.agent.extraArgs[0] | string | `"--disable-reporting=true"` | | -| grafana-agent.agent.mode | string | `"flow"` | | -| grafana-agent.agent.mounts.dockercontainers | bool | `true` | | -| grafana-agent.agent.mounts.varlog | bool | `true` | | -| grafana-agent.commonRelabellings | string | `"rule {\n source_labels = [\"__meta_kubernetes_namespace\"]\n target_label = \"namespace\"\n}\nrule {\n source_labels = [\"__meta_kubernetes_pod_name\"]\n target_label = \"pod\"\n}\n// coalesce the following labels and pick the first value; we'll use this to define the \"job\" label\nrule {\n source_labels = [\"__meta_kubernetes_pod_label_app_kubernetes_io_component\", \"app\", \"__meta_kubernetes_pod_container_name\"]\n separator = \"/\"\n target_label = \"__meta_app\"\n action = \"replace\"\n regex = \"^/*([^/]+?)(?:/.*)?$\" // split by the delimiter if it exists, we only want the first one\n replacement = \"${1}\"\n}\nrule {\n source_labels = [\"__meta_kubernetes_namespace\", \"__meta_kubernetes_pod_label_app_kubernetes_io_name\", \"__meta_app\"]\n separator = \"/\"\n target_label = \"job\"\n}\nrule {\n source_labels = [\"__meta_kubernetes_pod_container_name\"]\n target_label = \"container\"\n}\nrule {\n regex = \"__meta_kubernetes_pod_label_(statefulset_kubernetes_io_pod_name|controller_revision_hash)\"\n action = \"labeldrop\"\n}\nrule {\n regex = \"pod_template_generation\"\n action = \"labeldrop\"\n}\nrule {\n source_labels = [\"__meta_kubernetes_pod_phase\"]\n regex = \"Pending|Succeeded|Failed|Completed\"\n action = \"drop\"\n}\nrule {\n source_labels = [\"__meta_kubernetes_pod_node_name\"]\n action = \"replace\"\n target_label = \"node\"\n}\nrule {\n action = \"labelmap\"\n regex = \"__meta_kubernetes_pod_annotation_prometheus_io_param_(.+)\"\n replacement = \"__param_$1\"\n}"` | | -| grafana-agent.controller.podAnnotations."prometheus.io/scrape" | string | `"true"` | | -| grafana-agent.controller.type | string | `"daemonset"` | | -| grafana-agent.crds.create | bool | `false` | | -| grafana-agent.discovery | string | `"// Discover k8s nodes\ndiscovery.kubernetes \"nodes\" {\n role = \"node\"\n}\n\n// Discover k8s pods\ndiscovery.kubernetes \"pods\" {\n role = \"pod\"\n selectors {\n role = \"pod\"\n }\n}"` | | -| grafana-agent.enabled | bool | `true` | | -| grafana-agent.extraBlocks | string | `""` | | -| grafana-agent.fullnameOverride | string | `"grafana-agent"` | | -| grafana-agent.podLogsRelabelRules | string | `""` | | -| grafana-agent.podMetricsRelabelRules | string | `""` | | -| grafana-agent.withOTLPReceiver | bool | `false` | | | grafana."grafana.ini"."auth.anonymous".enabled | bool | `true` | | | grafana."grafana.ini"."auth.anonymous".org_name | string | `"Main Org."` | | | grafana."grafana.ini"."auth.anonymous".org_role | string | `"Admin"` | | diff --git a/TESTING_KIND.md b/TESTING_KIND.md index e1c9786..ac56c81 100644 --- a/TESTING_KIND.md +++ b/TESTING_KIND.md @@ -128,4 +128,4 @@ To view the monitoring services, you can port forward their UI's. - Grafana: `kubectl -n coder-observability port-forward svc/grafana 3000:80` - Prometheus: `kubectl -n coder-observability port-forward svc/prometheus 3001:80` - Pyroscope: `kubectl port-forward svc/pyroscope 3002:4040` -- Grafana Agent: `kubectl port-forward svc/grafana-agent 3003:80` \ No newline at end of file +- Alloy: `kubectl port-forward svc/alloy 3003:12345` \ No newline at end of file diff --git a/coder-observability/Chart.lock b/coder-observability/Chart.lock index e815036..e7da8d2 100644 --- a/coder-observability/Chart.lock +++ b/coder-observability/Chart.lock @@ -14,8 +14,8 @@ dependencies: - name: tempo repository: https://grafana.github.io/helm-charts version: 1.23.3 -- name: grafana-agent +- name: alloy repository: https://grafana.github.io/helm-charts - version: 0.37.0 -digest: sha256:7e048e449462145b6336890f02048555d6002430cf7b8aa3d6c17bf73035b1ec -generated: "2026-09-21T20:39:23.727258319Z" + version: 1.13.1 +digest: sha256:400c10a8e5014f05941bdfb900c6a4e95fd5b6547815115b57356a74d1d2fded +generated: "2026-10-12T11:05:32.006264-04:00" diff --git a/coder-observability/Chart.yaml b/coder-observability/Chart.yaml index 1df2afe..a2cee15 100644 --- a/coder-observability/Chart.yaml +++ b/coder-observability/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: coder-observability description: Gain insights into your Coder deployment type: application -version: 0.7.4 +version: 0.7.5 dependencies: - name: pyroscope condition: pyroscope.enabled @@ -24,11 +24,10 @@ dependencies: condition: tempo.enabled repository: https://grafana.github.io/helm-charts version: '~v1.23.0' - - name: grafana-agent - alias: grafana-agent - condition: grafana-agent.enabled + - name: alloy + condition: alloy.enabled repository: https://grafana.github.io/helm-charts - version: '~0.37.0' + version: '~1.13.1' maintainers: - name: Coder Technologies, Inc. url: https://github.com/coder/observability/issues diff --git a/coder-observability/templates/_collector-config.tpl b/coder-observability/templates/_collector-config.tpl index 1aabde5..6a347bf 100644 --- a/coder-observability/templates/_collector-config.tpl +++ b/coder-observability/templates/_collector-config.tpl @@ -1,5 +1,5 @@ {{- define "collector-config" -}} -{{ $agent := (index .Values "grafana-agent") }} +{{ $agent := (index .Values "alloy") }} {{ $agent.logging }} {{ $agent.discovery }} diff --git a/coder-observability/templates/_helpers.tpl b/coder-observability/templates/_helpers.tpl index b98f876..85b6a53 100644 --- a/coder-observability/templates/_helpers.tpl +++ b/coder-observability/templates/_helpers.tpl @@ -121,8 +121,8 @@ https://github.com/coder/observability/blob/main/coder-observability/runbooks/{{ {{- define "prometheus-job" -}} {{- printf "%s/%s/%s" .Release.Namespace .Values.prometheus.server.fullnameOverride .Values.prometheus.server.name -}} {{- end }} {{/* Loki job label */}} {{- define "loki-job" -}} {{- printf "%s/%s" .Release.Namespace .Values.loki.fullnameOverride -}} {{- end }} -{{/* Grafana Agent job label */}} -{{- define "grafana-agent-job" -}} {{- printf "%s/%s/%s" .Release.Namespace (index .Values "grafana-agent").fullnameOverride "grafana-agent" -}} {{- end }} +{{/* Alloy job label */}} +{{- define "alloy-job" -}} {{- printf "%s/%s/%s" .Release.Namespace (index .Values "alloy").fullnameOverride "alloy" -}} {{- end }} {{- define "dashboard-range" -}} {{ .Values.global.dashboards.timerange }} {{- end }} {{- define "dashboard-refresh" -}} {{ .Values.global.dashboards.refresh }} {{- end }} diff --git a/coder-observability/templates/configmap-collector.yaml b/coder-observability/templates/configmap-collector.yaml index d5135ae..477593a 100644 --- a/coder-observability/templates/configmap-collector.yaml +++ b/coder-observability/templates/configmap-collector.yaml @@ -1,9 +1,9 @@ -{{- if (index .Values "grafana-agent").enabled }} +{{- if (index .Values "alloy").enabled }} --- kind: ConfigMap apiVersion: v1 metadata: - name: {{ (index .Values "grafana-agent").agent.configMap.name }} + name: {{ (index .Values "alloy").alloy.configMap.name }} namespace: {{ .Release.Namespace }} data: config.river: |- {{- include "collector-config" . | trim | nindent 4 }} diff --git a/coder-observability/templates/dashboards/_dashboards_status.json.tpl b/coder-observability/templates/dashboards/_dashboards_status.json.tpl index 9ddbd09..e60c69a 100644 --- a/coder-observability/templates/dashboards/_dashboards_status.json.tpl +++ b/coder-observability/templates/dashboards/_dashboards_status.json.tpl @@ -1407,14 +1407,14 @@ "uid": "prometheus" }, "editorMode": "code", - "expr": "min(up{job=\"{{- include "grafana-agent-job" . -}}\"})", + "expr": "min(up{job=\"{{- include "alloy-job" . -}}\"})", "instant": true, "legendFormat": "__auto", "range": false, "refId": "A" } ], - "title": "Grafana Agent", + "title": "Alloy", "type": "stat" }, { @@ -1759,14 +1759,14 @@ }, "editorMode": "code", "exemplar": false, - "expr": "min(agent_config_last_load_successful{job=\"{{- include "grafana-agent-job" . -}}\"})", + "expr": "min(alloy_config_last_load_successful{job=\"{{- include "alloy-job" . -}}\"})", "instant": true, "legendFormat": "__auto", "range": false, "refId": "A" } ], - "title": "Grafana Agent Config", + "title": "Alloy Config", "type": "stat" }, { diff --git a/coder-observability/values.yaml b/coder-observability/values.yaml index deefce5..834739a 100644 --- a/coder-observability/values.yaml +++ b/coder-observability/values.yaml @@ -192,11 +192,10 @@ sqlExporter: enabled: true image: "burningalchemist/sql_exporter" -grafana-agent: +alloy: enabled: true - fullnameOverride: grafana-agent - agent: - mode: flow + fullnameOverride: alloy + alloy: configMap: name: collector-config key: config.river diff --git a/compiled/resources.yaml b/compiled/resources.yaml index ad508b4..59b50dd 100644 --- a/compiled/resources.yaml +++ b/compiled/resources.yaml @@ -35,16 +35,19 @@ spec: app.kubernetes.io/component: memcached-results-cache maxUnavailable: 1 --- -# Source: coder-observability/charts/grafana-agent/templates/serviceaccount.yaml +# Source: coder-observability/charts/alloy/templates/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount +automountServiceAccountToken: true metadata: - name: grafana-agent + name: alloy namespace: coder-observability labels: - app.kubernetes.io/name: grafana-agent + app.kubernetes.io/name: alloy app.kubernetes.io/instance: coder-observability app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: rbac --- # Source: coder-observability/charts/grafana/templates/serviceaccount.yaml apiVersion: v1 @@ -7295,14 +7298,14 @@ data: "uid": "prometheus" }, "editorMode": "code", - "expr": "min(up{job=\"coder-observability/grafana-agent/grafana-agent\"})", + "expr": "min(up{job=\"coder-observability/alloy/alloy\"})", "instant": true, "legendFormat": "__auto", "range": false, "refId": "A" } ], - "title": "Grafana Agent", + "title": "Alloy", "type": "stat" }, { @@ -7647,14 +7650,14 @@ data: }, "editorMode": "code", "exemplar": false, - "expr": "min(agent_config_last_load_successful{job=\"coder-observability/grafana-agent/grafana-agent\"})", + "expr": "min(alloy_config_last_load_successful{job=\"coder-observability/alloy/alloy\"})", "instant": true, "legendFormat": "__auto", "range": false, "refId": "A" } ], - "title": "Grafana Agent Config", + "title": "Alloy Config", "type": "stat" }, { @@ -10965,35 +10968,32 @@ spec: requests: storage: "10Gi" --- -# Source: coder-observability/charts/grafana-agent/templates/rbac.yaml +# Source: coder-observability/charts/alloy/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: grafana-agent + name: alloy labels: - app.kubernetes.io/name: grafana-agent + app.kubernetes.io/name: alloy app.kubernetes.io/instance: coder-observability app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: rbac rules: - # Rules which allow discovery.kubernetes to function. - apiGroups: - "" - - "discovery.k8s.io" - - "networking.k8s.io" + - discovery.k8s.io + - networking.k8s.io resources: - endpoints - endpointslices - ingresses - - nodes - - nodes/proxy - - nodes/metrics - pods - services verbs: - get - list - watch - # Rules which allow loki.source.kubernetes and loki.source.podlogs to work. - apiGroups: - "" resources: @@ -11005,36 +11005,40 @@ rules: - list - watch - apiGroups: - - "monitoring.grafana.com" + - monitoring.grafana.com resources: - podlogs verbs: - get - list - watch - # Rules which allow mimir.rules.kubernetes to work. - - apiGroups: ["monitoring.coreos.com"] + - apiGroups: + - monitoring.coreos.com resources: - prometheusrules verbs: - get - list - watch - - nonResourceURLs: - - /metrics + - apiGroups: + - monitoring.coreos.com + resources: + - alertmanagerconfigs verbs: - get - # Rules for prometheus.kubernetes.* - - apiGroups: ["monitoring.coreos.com"] + - list + - watch + - apiGroups: + - monitoring.coreos.com resources: - podmonitors - servicemonitors - probes + - scrapeconfigs verbs: - get - list - watch - # Rules which allow eventhandler to work. - apiGroups: - "" resources: @@ -11043,22 +11047,52 @@ rules: - get - list - watch - # needed for remote.kubernetes.* - - apiGroups: [""] + - apiGroups: + - "" resources: - - "configmaps" - - "secrets" + - configmaps + - secrets verbs: - get - list - watch - # needed for otelcol.processor.k8sattributes - - apiGroups: ["apps"] - resources: ["replicasets"] - verbs: ["get", "list", "watch"] - - apiGroups: ["extensions"] - resources: ["replicasets"] - verbs: ["get", "list", "watch"] + - apiGroups: + - apps + - extensions + resources: + - replicasets + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - nodes/pods + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - nodes/metrics + verbs: + - get + - list + - watch + - nonResourceURLs: + - /metrics + verbs: + - get --- # Source: coder-observability/charts/grafana/templates/clusterrole.yaml kind: ClusterRole @@ -11259,22 +11293,24 @@ rules: verbs: - get --- -# Source: coder-observability/charts/grafana-agent/templates/rbac.yaml +# Source: coder-observability/charts/alloy/templates/rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: grafana-agent + name: alloy labels: - app.kubernetes.io/name: grafana-agent + app.kubernetes.io/name: alloy app.kubernetes.io/instance: coder-observability app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: rbac roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: grafana-agent + name: alloy subjects: - kind: ServiceAccount - name: grafana-agent + name: alloy namespace: coder-observability --- # Source: coder-observability/charts/grafana/templates/clusterrolebinding.yaml @@ -11389,20 +11425,24 @@ subjects: name: grafana namespace: coder-observability --- -# Source: coder-observability/charts/grafana-agent/templates/cluster_service.yaml +# Source: coder-observability/charts/alloy/templates/cluster_service.yaml apiVersion: v1 kind: Service metadata: - name: grafana-agent-cluster + name: alloy-cluster + namespace: coder-observability labels: - app.kubernetes.io/name: grafana-agent + app.kubernetes.io/name: alloy app.kubernetes.io/instance: coder-observability app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: networking spec: type: ClusterIP clusterIP: 'None' + publishNotReadyAddresses: true selector: - app.kubernetes.io/name: grafana-agent + app.kubernetes.io/name: alloy app.kubernetes.io/instance: coder-observability ports: # Do not include the -metrics suffix in the port name, otherwise metrics @@ -11412,29 +11452,32 @@ spec: # This service should only be used for clustering, and not metric # collection. - name: http - port: 80 - targetPort: 80 + port: 12345 + targetPort: 12345 protocol: "TCP" --- -# Source: coder-observability/charts/grafana-agent/templates/service.yaml +# Source: coder-observability/charts/alloy/templates/service.yaml apiVersion: v1 kind: Service metadata: - name: grafana-agent + name: alloy + namespace: coder-observability labels: - app.kubernetes.io/name: grafana-agent + app.kubernetes.io/name: alloy app.kubernetes.io/instance: coder-observability app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy + app.kubernetes.io/component: networking spec: type: ClusterIP selector: - app.kubernetes.io/name: grafana-agent + app.kubernetes.io/name: alloy app.kubernetes.io/instance: coder-observability internalTrafficPolicy: Cluster ports: - name: http-metrics - port: 80 - targetPort: 80 + port: 12345 + targetPort: 12345 protocol: "TCP" --- # Source: coder-observability/charts/grafana/templates/service.yaml @@ -12008,65 +12051,70 @@ spec: selector: app: runbook-viewer --- -# Source: coder-observability/charts/grafana-agent/templates/controllers/daemonset.yaml +# Source: coder-observability/charts/alloy/templates/controllers/daemonset.yaml apiVersion: apps/v1 kind: DaemonSet metadata: - name: grafana-agent + name: alloy + namespace: coder-observability labels: - app.kubernetes.io/name: grafana-agent + app.kubernetes.io/name: alloy app.kubernetes.io/instance: coder-observability app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: alloy spec: minReadySeconds: 10 selector: matchLabels: - app.kubernetes.io/name: grafana-agent + app.kubernetes.io/name: alloy app.kubernetes.io/instance: coder-observability template: metadata: annotations: - kubectl.kubernetes.io/default-container: grafana-agent + kubectl.kubernetes.io/default-container: alloy prometheus.io/scrape: "true" labels: - app.kubernetes.io/name: grafana-agent + app.kubernetes.io/name: alloy app.kubernetes.io/instance: coder-observability spec: - serviceAccountName: grafana-agent + serviceAccountName: alloy containers: - - name: grafana-agent + - name: alloy imagePullPolicy: IfNotPresent args: - run - - /etc/agent/config.river - - --storage.path=/tmp/agent - - --server.http.listen-addr=0.0.0.0:80 + - /etc/alloy/config.river + - --storage.path=/tmp/alloy + - --server.http.listen-addr=0.0.0.0:12345 - --server.http.ui-path-prefix=/ - --cluster.enabled=true - - --cluster.join-addresses=grafana-agent-cluster + - --cluster.join-addresses=alloy-cluster + - --stability.level=generally-available - --disable-reporting=true env: - - name: AGENT_MODE - value: flow - - name: AGENT_DEPLOY_MODE + - name: ALLOY_DEPLOY_MODE value: "helm" - name: HOSTNAME valueFrom: fieldRef: fieldPath: spec.nodeName + - name: K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName ports: - - containerPort: 80 + - containerPort: 12345 name: http-metrics readinessProbe: httpGet: path: /-/ready - port: 80 + port: 12345 scheme: HTTP initialDelaySeconds: 10 timeoutSeconds: 1 volumeMounts: - name: config - mountPath: /etc/agent + mountPath: /etc/alloy - name: varlog mountPath: /var/log readOnly: true @@ -12074,16 +12122,28 @@ spec: mountPath: /var/lib/docker/containers readOnly: true - name: config-reloader + imagePullPolicy: IfNotPresent args: - - --volume-dir=/etc/agent - - --webhook-url=http://localhost:80/-/reload + - --watched-dir=/etc/alloy + - --reload-url=http://localhost:12345/-/reload volumeMounts: - name: config - mountPath: /etc/agent + mountPath: /etc/alloy resources: requests: - cpu: 1m - memory: 5Mi + cpu: 10m + memory: 50Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault dnsPolicy: ClusterFirst volumes: - name: config