From 7fe50233ae4017387550bfe3adca2a95090d5bf1 Mon Sep 17 00:00:00 2001 From: Pierre KELBERT Date: Fri, 3 Nov 2023 18:00:55 +0100 Subject: [PATCH] config-reloader: change to non-root user (#4235) --- CHANGELOG.md | 64 +++++++++++---------- pkg/operator/resources_pod_template.go | 8 ++- pkg/operator/resources_pod_template_test.go | 27 ++++++++- 3 files changed, 65 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01f8efc42043..9fbef786b1b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,40 @@ Main (unreleased) - `otelcol.processor.filter` - filters OTLP telemetry data using OpenTelemetry Transformation Language (OTTL). (@hainenber) +### Enhancements + +- The `loki.write` WAL now has snappy compression enabled by default. (@thepalbi) + +- Allow converting labels to structured metadata with Loki's structured_metadata stage. (@gonzalesraul) + +- Improved performance of `pyroscope.scrape` component when working with a large number of targets. (@cyriltovena) + +- Added support for comma-separated list of fields in `source` option and a + new `separator` option in `drop` stage of `loki.process`. (@thampiotr) + +- The `loki.source.docker` component now allows connecting to Docker daemons + over HTTP(S) and setting up TLS credentials. (@tpaschalis) + +- Added an `add_metric_suffixes` option to `otelcol.exporter.prometheus` in flow mode, + which configures whether to add type and unit suffixes to metrics names. (@mar4uk) + +- Added an `exclude_event_message` option to `loki.source.windowsevent` in flow mode, + which excludes the human-friendly event message from Windows event logs. (@ptodev) + +- Improve detection of rolled log files in `loki.source.kubernetes` and + `loki.source.podlogs` (@slim-bean). + +- Support clustering in `loki.source.kubernetes` (@slim-bean). + +- Support clustering in `loki.source.podlogs` (@rfratto). + +- Make component list sortable in web UI. (@hainenber) + +- Adds new metrics (`mssql_server_total_memory_bytes`, `mssql_server_target_memory_bytes`, + and `mssql_available_commit_memory_bytes`) for `mssql` integration. + +- Grafana Agent Operator: `config-reloader` container no longer runs as root. + (@rootmout) ### Bugfixes @@ -101,37 +135,7 @@ Main (unreleased) - Fix a bug where reloading the configuration of a `loki.write` component lead to a panic. (@tpaschalis) -### Enhancements - -- The `loki.write` WAL now has snappy compression enabled by default. (@thepalbi) - -- Allow converting labels to structured metadata with Loki's structured_metadata stage. (@gonzalesraul) - -- Improved performance of `pyroscope.scrape` component when working with a large number of targets. (@cyriltovena) - -- Added support for comma-separated list of fields in `source` option and a - new `separator` option in `drop` stage of `loki.process`. (@thampiotr) - -- The `loki.source.docker` component now allows connecting to Docker daemons - over HTTP(S) and setting up TLS credentials. (@tpaschalis) -- Added an `add_metric_suffixes` option to `otelcol.exporter.prometheus` in flow mode, - which configures whether to add type and unit suffixes to metrics names. (@mar4uk) - -- Added an `exclude_event_message` option to `loki.source.windowsevent` in flow mode, - which excludes the human-friendly event message from Windows event logs. (@ptodev) - -- Improve detection of rolled log files in `loki.source.kubernetes` and - `loki.source.podlogs` (@slim-bean). - -- Support clustering in `loki.source.kubernetes` (@slim-bean). - -- Support clustering in `loki.source.podlogs` (@rfratto). - -- Make component list sortable in web UI. (@hainenber) - -- Adds new metrics (`mssql_server_total_memory_bytes`, `mssql_server_target_memory_bytes`, - and `mssql_available_commit_memory_bytes`) for `mssql` integration. v0.37.3 (2023-10-26) ----------------- diff --git a/pkg/operator/resources_pod_template.go b/pkg/operator/resources_pod_template.go index cd4d8aee714b..c826ea6ea980 100644 --- a/pkg/operator/resources_pod_template.go +++ b/pkg/operator/resources_pod_template.go @@ -207,6 +207,8 @@ func generatePodTemplate( imagePathConfigReloader = *d.Agent.Spec.ConfigReloaderImage } + boolFalse := false + boolTrue := true operatorContainers := []core_v1.Container{ { Name: "config-reloader", @@ -214,7 +216,11 @@ func generatePodTemplate( VolumeMounts: volumeMounts, Env: envVars, SecurityContext: &core_v1.SecurityContext{ - RunAsUser: pointer.Int64(0), + AllowPrivilegeEscalation: &boolFalse, + ReadOnlyRootFilesystem: &boolTrue, + Capabilities: &core_v1.Capabilities{ + Drop: []core_v1.Capability{"ALL"}, + }, }, Args: []string{ "--config-file=/var/lib/grafana-agent/config-in/agent.yml", diff --git a/pkg/operator/resources_pod_template_test.go b/pkg/operator/resources_pod_template_test.go index 3f229c8313da..eb855820cc9d 100644 --- a/pkg/operator/resources_pod_template_test.go +++ b/pkg/operator/resources_pod_template_test.go @@ -98,6 +98,12 @@ func Test_generatePodTemplate(t *testing.T) { assert.False(t, tmpl.Spec.Containers[i].SecurityContext.Privileged != nil && *tmpl.Spec.Containers[i].SecurityContext.Privileged, "privileged is not required. Fargate cannot schedule privileged containers.") + assert.False(t, tmpl.Spec.Containers[i].SecurityContext.RunAsUser != nil && + *tmpl.Spec.Containers[i].SecurityContext.RunAsUser == int64(0), + "force the container to run as root is not required.") + assert.False(t, tmpl.Spec.Containers[i].SecurityContext.AllowPrivilegeEscalation != nil && + *tmpl.Spec.Containers[i].SecurityContext.AllowPrivilegeEscalation, + "allow privilege escalation is not required.") } }) @@ -110,9 +116,24 @@ func Test_generatePodTemplate(t *testing.T) { tmpl, _, err := generatePodTemplate(cfg, "agent", deploy, podTemplateOptions{Privileged: true}) require.NoError(t, err) - assert.True(t, tmpl.Spec.Containers[1].SecurityContext.Privileged != nil && - *tmpl.Spec.Containers[1].SecurityContext.Privileged, - "privileged is needed if pod options say so.") + for i := range tmpl.Spec.Containers { + // only grafana-agent container is supposed to be privileged + if tmpl.Spec.Containers[i].Name == "grafana-agent" { + assert.True(t, tmpl.Spec.Containers[i].SecurityContext.Privileged != nil && + *tmpl.Spec.Containers[i].SecurityContext.Privileged, + "privileged is needed for grafana-agent if pod options say so.") + } else { + assert.False(t, tmpl.Spec.Containers[i].SecurityContext.Privileged != nil && + *tmpl.Spec.Containers[i].SecurityContext.Privileged, + "privileged is not required for other containers.") + assert.False(t, tmpl.Spec.Containers[i].SecurityContext.RunAsUser != nil && + *tmpl.Spec.Containers[i].SecurityContext.RunAsUser == int64(0), + "force the container to run as root is not required for other containers.") + assert.False(t, tmpl.Spec.Containers[i].SecurityContext.AllowPrivilegeEscalation != nil && + *tmpl.Spec.Containers[i].SecurityContext.AllowPrivilegeEscalation, + "allow privilege escalation is not required for other containers.") + } + } }) t.Run("runtimeclassname set if passed in", func(t *testing.T) {