Skip to content

Commit a631362

Browse files
[k8s] embed hints inputs in agent container image (#6381)
* feat: embed hints inputs in elastic-agent container image * chore: disable lint overflow warnings
1 parent 3c4861c commit a631362

File tree

12 files changed

+174
-100
lines changed

12 files changed

+174
-100
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Kind can be one of:
2+
# - breaking-change: a change to previously-documented behavior
3+
# - deprecation: functionality that is being removed in a later release
4+
# - bug-fix: fixes a problem in a previous version
5+
# - enhancement: extends functionality but does not break or fix existing behavior
6+
# - feature: new functionality
7+
# - known-issue: problems that we are aware of in a given version
8+
# - security: impacts on the security of a product or a user’s deployment.
9+
# - upgrade: important information for someone upgrading from a prior version
10+
# - other: does not fit into any of the other categories
11+
kind: enhancement
12+
13+
# Change summary; a 80ish characters long description of the change.
14+
summary: Embed hints-based inputs in the Elastic Agent container image.
15+
16+
# Long description; in case the summary is not enough to describe the change
17+
# this field accommodates a description without length limits.
18+
# NOTE: This field will be rendered only for breaking-change and known-issue kinds at the moment.
19+
description: This change includes the addition of hints-based inputs directly within the Elastic Agent container image, enabling streamlined configurations for input discovery when deployed in containerized environments.
20+
21+
# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc.
22+
component: elastic-agent
23+
24+
# PR URL; optional; the PR number that added the changeset.
25+
# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added.
26+
# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number.
27+
# Please provide it if you are adding a fragment for a different PR.
28+
pr: https://github.com/elastic/elastic-agent/pull/6381
29+
30+
# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of).
31+
# If not present is automatically filled by the tooling with the issue linked to the PR number.
32+
issue: https://github.com/elastic/elastic-agent/issues/5661

deploy/helm/elastic-agent/examples/kubernetes-hints-autodiscover/rendered/manifest.yaml

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,36 +1142,13 @@ spec:
11421142
- mountPath: /hostfs/var/lib
11431143
name: var-lib
11441144
readOnly: true
1145-
- mountPath: /usr/share/elastic-agent/state/inputs.d
1146-
name: external-inputs
11471145
- mountPath: /usr/share/elastic-agent/state
11481146
name: agent-data
11491147
- mountPath: /etc/elastic-agent/agent.yml
11501148
name: config
11511149
readOnly: true
11521150
subPath: agent.yml
11531151
dnsPolicy: ClusterFirstWithHostNet
1154-
initContainers:
1155-
- args:
1156-
- -c
1157-
- mkdir -p /etc/elastic-agent/inputs.d && mkdir -p /etc/elastic-agent/inputs.d
1158-
&& wget -O - https://github.com/elastic/elastic-agent/archive/v9.0.0.tar.gz
1159-
| tar xz -C /etc/elastic-agent/inputs.d --strip=5 "elastic-agent-9.0.0/deploy/kubernetes/elastic-agent-standalone/templates.d"
1160-
command:
1161-
- sh
1162-
image: busybox:1.36.1
1163-
name: k8s-templates-downloader
1164-
securityContext:
1165-
allowPrivilegeEscalation: false
1166-
capabilities:
1167-
drop:
1168-
- ALL
1169-
privileged: false
1170-
runAsGroup: 1000
1171-
runAsUser: 1000
1172-
volumeMounts:
1173-
- mountPath: /etc/elastic-agent/inputs.d
1174-
name: external-inputs
11751152
nodeSelector:
11761153
kubernetes.io/os: linux
11771154
serviceAccountName: agent-pernode-example
@@ -1194,8 +1171,6 @@ spec:
11941171
- hostPath:
11951172
path: /var/lib
11961173
name: var-lib
1197-
- emptyDir: {}
1198-
name: external-inputs
11991174
- hostPath:
12001175
path: /etc/elastic-agent/default/agent-pernode-example/state
12011176
type: DirectoryOrCreate

deploy/helm/elastic-agent/examples/multiple-integrations/rendered/manifest.yaml

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,36 +1158,13 @@ spec:
11581158
- mountPath: /hostfs/var/lib
11591159
name: var-lib
11601160
readOnly: true
1161-
- mountPath: /usr/share/elastic-agent/state/inputs.d
1162-
name: external-inputs
11631161
- mountPath: /usr/share/elastic-agent/state
11641162
name: agent-data
11651163
- mountPath: /etc/elastic-agent/agent.yml
11661164
name: config
11671165
readOnly: true
11681166
subPath: agent.yml
11691167
dnsPolicy: ClusterFirstWithHostNet
1170-
initContainers:
1171-
- args:
1172-
- -c
1173-
- mkdir -p /etc/elastic-agent/inputs.d && mkdir -p /etc/elastic-agent/inputs.d
1174-
&& wget -O - https://github.com/elastic/elastic-agent/archive/v9.0.0.tar.gz
1175-
| tar xz -C /etc/elastic-agent/inputs.d --strip=5 "elastic-agent-9.0.0/deploy/kubernetes/elastic-agent-standalone/templates.d"
1176-
command:
1177-
- sh
1178-
image: busybox:1.36.1
1179-
name: k8s-templates-downloader
1180-
securityContext:
1181-
allowPrivilegeEscalation: false
1182-
capabilities:
1183-
drop:
1184-
- ALL
1185-
privileged: false
1186-
runAsGroup: 1000
1187-
runAsUser: 1000
1188-
volumeMounts:
1189-
- mountPath: /etc/elastic-agent/inputs.d
1190-
name: external-inputs
11911168
nodeSelector:
11921169
kubernetes.io/os: linux
11931170
serviceAccountName: agent-pernode-example
@@ -1210,8 +1187,6 @@ spec:
12101187
- hostPath:
12111188
path: /var/lib
12121189
name: var-lib
1213-
- emptyDir: {}
1214-
name: external-inputs
12151190
- hostPath:
12161191
path: /etc/elastic-agent/default/agent-pernode-example/state
12171192
type: DirectoryOrCreate

deploy/helm/elastic-agent/templates/integrations/_kubernetes/_kubernetes.tpl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
{{- include "elasticagent.kubernetes.config.state.statefulsets.init" $ -}}
1818
{{- include "elasticagent.kubernetes.config.state.storageclasses.init" $ -}}
1919
{{- include "elasticagent.kubernetes.config.kube_controller.init" $ -}}
20-
{{- include "elasticagent.kubernetes.config.hints.init" $ -}}
2120
{{- include "elasticagent.kubernetes.config.audit_logs.init" $ -}}
2221
{{- include "elasticagent.kubernetes.config.container_logs.init" $ -}}
2322
{{- include "elasticagent.kubernetes.config.kubelet.containers.init" $ -}}
@@ -28,4 +27,4 @@
2827
{{- include "elasticagent.kubernetes.config.kube_proxy.init" $ -}}
2928
{{- include "elasticagent.kubernetes.config.kube_scheduler.init" $ -}}
3029
{{- end -}}
31-
{{- end -}}
30+
{{- end -}}
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,2 @@
11
{{- define "elasticagent.kubernetes.config.hints.init" -}}
2-
{{- if eq $.Values.kubernetes.hints.enabled true -}}
3-
{{- $preset := $.Values.agent.presets.perNode -}}
4-
{{- include "elasticagent.preset.applyOnce" (list $ $preset "elasticagent.kubernetes.pernode.preset") -}}
5-
{{- end -}}
62
{{- end -}}

deploy/helm/elastic-agent/templates/integrations/_kubernetes/_preset_pernode.tpl

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
{{- include "elasticagent.preset.mutate.volumes" (list $ $.Values.agent.presets.perNode "elasticagent.kubernetes.pernode.preset.volumes") -}}
44
{{- include "elasticagent.preset.mutate.outputs.byname" (list $ $.Values.agent.presets.perNode $.Values.kubernetes.output)}}
55
{{- if eq $.Values.kubernetes.hints.enabled true -}}
6-
{{- include "elasticagent.preset.mutate.initcontainers" (list $ $.Values.agent.presets.perNode "elasticagent.kubernetes.pernode.preset.initcontainers") -}}
76
{{- include "elasticagent.preset.mutate.providers.kubernetes.hints" (list $ $.Values.agent.presets.perNode "elasticagent.kubernetes.pernode.preset.providers.kubernetes.hints") -}}
87
{{- end -}}
98
{{- if or (eq $.Values.kubernetes.scheduler.enabled true) (eq $.Values.kubernetes.controller_manager.enabled true) -}}
@@ -37,10 +36,6 @@ extraVolumeMounts:
3736
- name: var-lib
3837
mountPath: /hostfs/var/lib
3938
readOnly: true
40-
{{- if eq $.Values.kubernetes.hints.enabled true }}
41-
- name: external-inputs
42-
mountPath: /usr/share/elastic-agent/state/inputs.d
43-
{{- end }}
4439
{{- end -}}
4540

4641
{{- define "elasticagent.kubernetes.pernode.preset.volumes" -}}
@@ -63,34 +58,6 @@ extraVolumes:
6358
- name: var-lib
6459
hostPath:
6560
path: /var/lib
66-
{{- if eq $.Values.kubernetes.hints.enabled true }}
67-
- name: external-inputs
68-
emptyDir: {}
69-
{{- end }}
70-
{{- end -}}
71-
72-
{{- define "elasticagent.kubernetes.pernode.preset.initcontainers" -}}
73-
initContainers:
74-
- name: k8s-templates-downloader
75-
image: busybox:1.36.1
76-
securityContext:
77-
allowPrivilegeEscalation: false
78-
privileged: false
79-
runAsUser: 1000
80-
runAsGroup: 1000
81-
capabilities:
82-
drop:
83-
- ALL
84-
command: [ 'sh' ]
85-
args:
86-
- -c
87-
- >-
88-
mkdir -p /etc/elastic-agent/inputs.d &&
89-
mkdir -p /etc/elastic-agent/inputs.d &&
90-
wget -O - https://github.com/elastic/elastic-agent/archive/v{{$.Values.agent.version}}.tar.gz | tar xz -C /etc/elastic-agent/inputs.d --strip=5 "elastic-agent-{{$.Values.agent.version}}/deploy/kubernetes/elastic-agent-standalone/templates.d"
91-
volumeMounts:
92-
- name: external-inputs
93-
mountPath: /etc/elastic-agent/inputs.d
9461
{{- end -}}
9562

9663
{{- define "elasticagent.kubernetes.pernode.preset.providers.kubernetes.hints" -}}

dev-tools/packaging/package_test.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,15 @@ const (
4949
)
5050

5151
var (
52-
excludedPathsPattern = regexp.MustCompile(`node_modules`)
53-
configFilePattern = regexp.MustCompile(`.*beat\.spec.yml$|.*beat\.yml$|apm-server\.yml|elastic-agent\.yml$$`)
54-
manifestFilePattern = regexp.MustCompile(`manifest.yml`)
55-
modulesDirPattern = regexp.MustCompile(`module/.+`)
56-
modulesDDirPattern = regexp.MustCompile(`modules.d/$`)
57-
modulesDFilePattern = regexp.MustCompile(`modules.d/.+`)
58-
monitorsDFilePattern = regexp.MustCompile(`monitors.d/.+`)
59-
systemdUnitFilePattern = regexp.MustCompile(`/lib/systemd/system/.*\.service`)
52+
excludedPathsPattern = regexp.MustCompile(`node_modules`)
53+
configFilePattern = regexp.MustCompile(`.*beat\.spec.yml$|.*beat\.yml$|apm-server\.yml|elastic-agent\.yml$$`)
54+
manifestFilePattern = regexp.MustCompile(`manifest.yml`)
55+
modulesDirPattern = regexp.MustCompile(`module/.+`)
56+
modulesDDirPattern = regexp.MustCompile(`modules.d/$`)
57+
modulesDFilePattern = regexp.MustCompile(`modules.d/.+`)
58+
monitorsDFilePattern = regexp.MustCompile(`monitors.d/.+`)
59+
systemdUnitFilePattern = regexp.MustCompile(`/lib/systemd/system/.*\.service`)
60+
hintsInputsDFilePattern = regexp.MustCompile(`usr/share/elastic-agent/hints.inputs.d/.*\.yml`)
6061

6162
licenseFiles = []string{"LICENSE.txt", "NOTICE.txt"}
6263
)
@@ -297,6 +298,7 @@ func checkDocker(t *testing.T, file string) {
297298
checkManifestPermissionsWithMode(t, p, os.FileMode(0644))
298299
checkModulesPresent(t, "", p)
299300
checkModulesDPresent(t, "", p)
301+
checkHintsInputsD(t, "hints.inputs.d", hintsInputsDFilePattern, p)
300302
checkLicensesPresent(t, "licenses/", p)
301303
}
302304

@@ -447,6 +449,21 @@ func checkMonitorsDPresent(t *testing.T, prefix string, p *packageFile) {
447449
}
448450
}
449451

452+
func checkHintsInputsD(t *testing.T, name string, r *regexp.Regexp, p *packageFile) {
453+
t.Run(fmt.Sprintf("%s %s contents", p.Name, name), func(t *testing.T) {
454+
total := 0
455+
for _, entry := range p.Contents {
456+
if r.MatchString(entry.File) {
457+
total++
458+
}
459+
}
460+
461+
if total == 0 {
462+
t.Errorf("no hints inputs found under %s", name)
463+
}
464+
})
465+
}
466+
450467
func checkModules(t *testing.T, name, prefix string, r *regexp.Regexp, p *packageFile) {
451468
t.Run(fmt.Sprintf("%s %s contents", p.Name, name), func(t *testing.T) {
452469
minExpectedModules := *minModules
@@ -711,7 +728,7 @@ func readTarContents(tarName string, data io.Reader) (*packageFile, error) {
711728
File: header.Name,
712729
UID: header.Uid,
713730
GID: header.Gid,
714-
Mode: os.FileMode(header.Mode),
731+
Mode: os.FileMode(header.Mode), //nolint:gosec // Reason: header.Mode should never overflow from int64 -> uint32
715732
}
716733
}
717734

dev-tools/packaging/packages.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ shared:
274274
content: >
275275
{{ commit }}
276276
mode: 0644
277+
'hints.inputs.d':
278+
source: '{{ repo.RootDir }}/deploy/kubernetes/elastic-agent-standalone/templates.d'
279+
mode: 0755
277280

278281
# cloud build to beats-ci repository
279282
- &agent_docker_cloud_spec

internal/pkg/agent/application/application.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/elastic/elastic-agent/internal/pkg/agent/storage"
2424
"github.com/elastic/elastic-agent/internal/pkg/capabilities"
2525
"github.com/elastic/elastic-agent/internal/pkg/composable"
26+
"github.com/elastic/elastic-agent/internal/pkg/composable/providers/kubernetes"
2627
"github.com/elastic/elastic-agent/internal/pkg/config"
2728
otelmanager "github.com/elastic/elastic-agent/internal/pkg/otel/manager"
2829
"github.com/elastic/elastic-agent/internal/pkg/release"
@@ -135,7 +136,12 @@ func New(
135136
log.Info("Parsed configuration and determined agent is managed locally")
136137

137138
loader := config.NewLoader(log, paths.ExternalInputs())
138-
discover := config.Discoverer(pathConfigFile, cfg.Settings.Path, paths.ExternalInputs())
139+
rawCfgMap, err := rawConfig.ToMapStr()
140+
if err != nil {
141+
return nil, nil, nil, fmt.Errorf("failed to transform agent configuration into a map: %w", err)
142+
}
143+
discover := config.Discoverer(pathConfigFile, cfg.Settings.Path, paths.ExternalInputs(),
144+
kubernetes.GetHintsInputConfigPath(log, rawCfgMap))
139145
if !cfg.Settings.Reload.Enabled {
140146
log.Debug("Reloading of configuration is off")
141147
configMgr = newOnce(log, discover, loader)

internal/pkg/composable/providers/kubernetes/config.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@
55
package kubernetes
66

77
import (
8+
"errors"
89
"time"
910

1011
"github.com/elastic/elastic-agent-autodiscover/kubernetes"
1112
"github.com/elastic/elastic-agent-autodiscover/kubernetes/metadata"
1213
"github.com/elastic/elastic-agent-libs/logp"
14+
"github.com/elastic/elastic-agent/pkg/core/logger"
15+
"github.com/elastic/elastic-agent/pkg/utils"
1316
)
1417

18+
const hintsInputsPathPattern = "/usr/share/elastic-agent/hints.inputs.d/*.yml"
19+
1520
// Config for kubernetes provider
1621
type Config struct {
1722
Scope string `config:"scope"`
@@ -57,6 +62,22 @@ type Enabled struct {
5762
Enabled bool `config:"enabled"`
5863
}
5964

65+
func GetHintsInputConfigPath(log *logger.Logger, agentCfg map[string]interface{}) string {
66+
hintsVal, err := utils.GetNestedMap(agentCfg, "providers", "kubernetes", "hints", "enabled")
67+
if err != nil {
68+
if errors.Is(err, utils.ErrKeyNotFound) {
69+
return ""
70+
}
71+
log.Errorf("error at reading providers.kubernetes.hints.enabled from config: %v", err)
72+
return ""
73+
}
74+
hintsEnabled, ok := hintsVal.(bool)
75+
if !ok || !hintsEnabled {
76+
return ""
77+
}
78+
return hintsInputsPathPattern
79+
}
80+
6081
// InitDefaults initializes the default values for the config.
6182
func (c *Config) InitDefaults() {
6283
c.CleanupTimeout = 60 * time.Second

0 commit comments

Comments
 (0)