Skip to content

Commit b852a15

Browse files
committed
chore: unprivileged windows by default
1 parent 39feae6 commit b852a15

9 files changed

Lines changed: 155 additions & 46 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99

1010
### enhancement
1111
- Add handling for fine-grained kubectl permissions @kondracek-nr [#1389](https://github.com/newrelic/nri-kubernetes/pull/1389)
12+
- Introduce HostProcess Windows containers and "privileged" mode support to collect host metrics on Windows nodes. Inherits global or chart-specific "privileged" setting by default, but also allows users to override this for their Windows nodes - see values.yaml. @kondracek-nr [#1361](https://github.com/newrelic/nri-kubernetes/pull/1361)
1213

1314
## v3.53.2 - 2026-02-09
1415

@@ -29,7 +30,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2930
### 🚀 Enhancements
3031
- Add kubelet initialization retry logic to handle certificate provisioning delays in managed Kubernetes environments (EKS/GKE). New config parameters `kubelet.config.initTimeout` (default: 180s) and `kubelet.config.initBackoff` (default: 5s) control retry behavior. Set `initTimeout: 0s` to disable retries and preserve legacy behavior. @NRhzhao [#1372](https://github.com/newrelic/nri-kubernetes/pull/1372)
3132
- Add pod priority and priorityClassName telemetry
32-
- Introduce HostProcess Windows containers and "privileged" mode support to collect host metrics on Windows nodes. Inherits global or chart-specific "privileged" setting by default, but also allows users to override this for their Windows nodes - see values.yaml. @kondracek-nr [#1361](https://github.com/newrelic/nri-kubernetes/pull/1361)
3333

3434
### ⛓️ Dependencies
3535
- Updated github.com/sirupsen/logrus to v1.9.4 - [Changelog 🔗](https://github.com/sirupsen/logrus/releases/tag/v1.9.4)

charts/newrelic-infrastructure/templates/NOTES.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,29 @@ plane pods by setting `controlPlane.hostNetwork: true`. Alternatively, you can d
3131
`controlPlane.enabled: false`.
3232
{{- end }}
3333

34+
{{- if and .Values.enableWindows (include "nriKubernetes.windows.privileged" .) }}
35+
Warning:
36+
========
37+
38+
Windows privileged mode is enabled (windows.privileged: true). The Windows kubelet DaemonSet will run as
39+
HostProcess containers, which execute directly on the Windows host with elevated privileges.
40+
41+
HostProcess containers:
42+
{{- if .Values.enableProcessMetrics }}
43+
- Kubelet scraper runs as NT AUTHORITY\Local service
44+
- Agent runs as NT AUTHORITY\SYSTEM (required for enableProcessMetrics: true)
45+
{{- else }}
46+
- Both containers run as NT AUTHORITY\Local service
47+
{{- end }}
48+
- Have full access to the host filesystem via CONTAINER_SANDBOX_MOUNT_POINT
49+
- Require hostNetwork: true (pods use the host's network namespace)
50+
- Are supported on Windows Server 2019 and later
51+
52+
This mode provides full monitoring capabilities including {{ if .Values.enableProcessMetrics }}process metrics and {{ end }}network statistics, but requires
53+
administrative privileges on Windows nodes. If you need to run in a more restricted environment, set
54+
`windows.privileged: false` to use standard container isolation.
55+
{{- end }}
56+
3457
{{- if and (include "newrelic.fargate" .) .Values.kubelet.affinity }}
3558
Warning:
3659
========

charts/newrelic-infrastructure/templates/kubelet/_agent-config_helper.tpl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ Auto-enable when enableProcessMetrics is true AND enableWindows is true, since W
2222
containers are inherently privileged and partial process visibility is less useful.
2323
Users can still override via kubelet.agentConfig.enable_elevated_process_priv if needed.
2424
*/}}
25-
{{- if (get .Values "enableElevatedProcessPrivilege" | kindIs "bool") }}
26-
enable_elevated_process_priv: {{ .Values.enableElevatedProcessPrivilege }}
27-
{{- else if and (get .Values "enableProcessMetrics") (get .Values "enableWindows") }}
25+
{{- if and (get .Values "enableProcessMetrics") (get .Values "enableWindows") }}
2826
enable_elevated_process_priv: true
2927
{{- end }}
3028
{{- end -}}

charts/newrelic-infrastructure/templates/kubelet/daemonset-windows.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,12 @@ spec:
144144
windowsOptions:
145145
{{- if include "nriKubernetes.windows.privileged" $ }}
146146
hostProcess: true
147+
{{- if $.Values.enableProcessMetrics }}
147148
runAsUserName: "NT AUTHORITY\\SYSTEM"
148149
{{- else }}
150+
runAsUserName: "NT AUTHORITY\\Local service"
151+
{{- end }}
152+
{{- else }}
149153
hostProcess: false
150154
runAsUserName: "ContainerUser"
151155
{{- end }}

charts/newrelic-infrastructure/tests/elevated_process_privilege_test.yaml

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -41,32 +41,6 @@ tests:
4141
path: data["newrelic-infra.yml"]
4242
pattern: "enable_elevated_process_priv: true"
4343

44-
- it: should respect explicit enableElevatedProcessPrivilege true setting
45-
set:
46-
cluster: test-cluster
47-
licenseKey: test-key
48-
kubelet.enabled: true
49-
enableWindows: true
50-
enableProcessMetrics: false
51-
enableElevatedProcessPrivilege: true
52-
asserts:
53-
- matchRegex:
54-
path: data["newrelic-infra.yml"]
55-
pattern: "enable_elevated_process_priv: true"
56-
57-
- it: should respect explicit enableElevatedProcessPrivilege false setting
58-
set:
59-
cluster: test-cluster
60-
licenseKey: test-key
61-
kubelet.enabled: true
62-
enableWindows: true
63-
enableProcessMetrics: true
64-
enableElevatedProcessPrivilege: false
65-
asserts:
66-
- matchRegex:
67-
path: data["newrelic-infra.yml"]
68-
pattern: "enable_elevated_process_priv: false"
69-
7044
- it: should handle enableProcessMetrics as boolean true
7145
set:
7246
cluster: test-cluster

charts/newrelic-infrastructure/tests/hostNetwork_test.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@ tests:
3232
path: spec.template.spec.hostNetwork
3333
value: false
3434
template: templates/kubelet/daemonset.yaml
35-
- equal:
35+
- isNull:
3636
path: spec.template.spec.hostNetwork
37-
value: true # Windows uses hostNetwork when privileged: true (default)
38-
template: templates/kubelet/daemonset-windows.yaml
37+
template: templates/kubelet/daemonset-windows.yaml # Windows defaults to unprivileged mode (windows.privileged: false)
3938

4039

4140
- it: hostNetwork is false if nothing is set

charts/newrelic-infrastructure/tests/securityContext_test.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,30 @@ tests:
237237
documentIndex: 1
238238
template: templates/kubelet/daemonset-windows.yaml
239239

240+
- it: Linux should default to privileged while Windows defaults to unprivileged
241+
set:
242+
licenseKey: test
243+
cluster: test
244+
enableWindows: true
245+
# Note: privileged defaults to true, windows.privileged defaults to false
246+
asserts:
247+
# Linux kubelet agent container should run as root (privileged mode)
248+
- equal:
249+
path: spec.template.spec.containers[1].securityContext.runAsUser
250+
value: 0
251+
template: templates/kubelet/daemonset.yaml
252+
# Windows containers should be unprivileged by default
253+
- equal:
254+
path: spec.template.spec.containers[0].securityContext.windowsOptions.hostProcess
255+
value: false
256+
documentIndex: 0
257+
template: templates/kubelet/daemonset-windows.yaml
258+
- equal:
259+
path: spec.template.spec.containers[1].securityContext.windowsOptions.hostProcess
260+
value: false
261+
documentIndex: 0
262+
template: templates/kubelet/daemonset-windows.yaml
263+
240264
- it: securityContext of linux containers not overwritten by windows defaults
241265
set:
242266
licenseKey: test

charts/newrelic-infrastructure/tests/windows_hostprocess_test.yaml

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ tests:
1717
kubelet.enabled: true
1818
enableWindows: true
1919
privileged: true
20+
windows:
21+
privileged: true
2022
asserts:
2123
- equal:
2224
path: spec.template.spec.containers[0].securityContext.windowsOptions.hostProcess
@@ -27,13 +29,16 @@ tests:
2729
value: true
2830
template: templates/kubelet/daemonset-windows.yaml
2931

30-
- it: should set correct user accounts in privileged mode
32+
- it: should set correct user accounts in privileged mode with enableProcessMetrics
3133
set:
3234
licenseKey: test
3335
cluster: test
3436
kubelet.enabled: true
3537
enableWindows: true
3638
privileged: true
39+
enableProcessMetrics: true
40+
windows:
41+
privileged: true
3742
asserts:
3843
- equal:
3944
path: spec.template.spec.containers[0].securityContext.windowsOptions.runAsUserName
@@ -44,13 +49,34 @@ tests:
4449
value: "NT AUTHORITY\\SYSTEM"
4550
template: templates/kubelet/daemonset-windows.yaml
4651

52+
- it: should use Local service for agent when privileged without enableProcessMetrics
53+
set:
54+
licenseKey: test
55+
cluster: test
56+
kubelet.enabled: true
57+
enableWindows: true
58+
privileged: true
59+
windows:
60+
privileged: true
61+
asserts:
62+
- equal:
63+
path: spec.template.spec.containers[0].securityContext.windowsOptions.runAsUserName
64+
value: "NT AUTHORITY\\Local service"
65+
template: templates/kubelet/daemonset-windows.yaml
66+
- equal:
67+
path: spec.template.spec.containers[1].securityContext.windowsOptions.runAsUserName
68+
value: "NT AUTHORITY\\Local service"
69+
template: templates/kubelet/daemonset-windows.yaml
70+
4771
- it: should add PowerShell command with CONTAINER_SANDBOX_MOUNT_POINT for kubelet in privileged mode
4872
set:
4973
licenseKey: test
5074
cluster: test
5175
kubelet.enabled: true
5276
enableWindows: true
5377
privileged: true
78+
windows:
79+
privileged: true
5480
asserts:
5581
- equal:
5682
path: spec.template.spec.containers[0].command[0]
@@ -72,6 +98,8 @@ tests:
7298
kubelet.enabled: true
7399
enableWindows: true
74100
privileged: true
101+
windows:
102+
privileged: true
75103
asserts:
76104
- equal:
77105
path: spec.template.spec.containers[1].command[0]
@@ -93,6 +121,8 @@ tests:
93121
kubelet.enabled: true
94122
enableWindows: true
95123
privileged: true
124+
windows:
125+
privileged: true
96126
asserts:
97127
- equal:
98128
path: spec.template.spec.hostNetwork
@@ -106,6 +136,8 @@ tests:
106136
kubelet.enabled: true
107137
enableWindows: true
108138
privileged: true
139+
windows:
140+
privileged: true
109141
asserts:
110142
- equal:
111143
path: metadata.labels.mode
@@ -123,6 +155,8 @@ tests:
123155
kubelet.enabled: true
124156
enableWindows: true
125157
privileged: true
158+
windows:
159+
privileged: true
126160
asserts:
127161
- notContains:
128162
path: spec.template.spec.containers[1].env
@@ -137,6 +171,8 @@ tests:
137171
kubelet.enabled: true
138172
enableWindows: true
139173
privileged: true
174+
windows:
175+
privileged: true
140176
asserts:
141177
- notContains:
142178
path: spec.template.spec.containers[1].env
@@ -265,6 +301,67 @@ tests:
265301
fieldPath: "status.hostIP"
266302
template: templates/kubelet/daemonset-windows.yaml
267303

304+
# Default behavior tests
305+
- it: should use unprivileged mode for Windows by default (windows.privileged=false)
306+
set:
307+
licenseKey: test
308+
cluster: test
309+
kubelet.enabled: true
310+
enableWindows: true
311+
documentIndex: 0
312+
asserts:
313+
- equal:
314+
path: spec.template.spec.containers[0].securityContext.windowsOptions.hostProcess
315+
value: false
316+
template: templates/kubelet/daemonset-windows.yaml
317+
- equal:
318+
path: spec.template.spec.containers[1].securityContext.windowsOptions.hostProcess
319+
value: false
320+
template: templates/kubelet/daemonset-windows.yaml
321+
- isNull:
322+
path: spec.template.spec.hostNetwork
323+
template: templates/kubelet/daemonset-windows.yaml
324+
- equal:
325+
path: metadata.labels.mode
326+
value: unprivileged
327+
template: templates/kubelet/daemonset-windows.yaml
328+
- equal:
329+
path: spec.template.metadata.labels.mode
330+
value: unprivileged
331+
template: templates/kubelet/daemonset-windows.yaml
332+
333+
- it: should use ContainerUser for both containers by default
334+
set:
335+
licenseKey: test
336+
cluster: test
337+
kubelet.enabled: true
338+
enableWindows: true
339+
documentIndex: 0
340+
asserts:
341+
- equal:
342+
path: spec.template.spec.containers[0].securityContext.windowsOptions.runAsUserName
343+
value: ContainerUser
344+
template: templates/kubelet/daemonset-windows.yaml
345+
- equal:
346+
path: spec.template.spec.containers[1].securityContext.windowsOptions.runAsUserName
347+
value: ContainerUser
348+
template: templates/kubelet/daemonset-windows.yaml
349+
350+
- it: should set NRIA_OVERRIDE_HOST_ROOT to empty by default for Windows
351+
set:
352+
licenseKey: test
353+
cluster: test
354+
kubelet.enabled: true
355+
enableWindows: true
356+
documentIndex: 0
357+
asserts:
358+
- contains:
359+
path: spec.template.spec.containers[1].env
360+
content:
361+
name: NRIA_OVERRIDE_HOST_ROOT
362+
value: ""
363+
template: templates/kubelet/daemonset-windows.yaml
364+
268365
# Windows-specific privileged override tests
269366
- it: should respect windows.privileged=false override when global privileged=true
270367
set:

charts/newrelic-infrastructure/values.yaml

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ windows:
9090
# When null, inherits from global 'privileged' setting.
9191
# Set to false to disable HostProcess mode on Windows while keeping Linux privileged.
9292
# HostProcess containers run directly on the Windows host (not in a container) and require hostNetwork: true.
93-
# @default -- Inherits from `privileged` setting
94-
privileged:
93+
# @default -- `false`
94+
privileged: false
9595

9696
# -- Config that applies to all instances of the solution: kubelet, ksm, control plane and sidecars.
9797
# @default -- See `values.yaml`
@@ -665,16 +665,6 @@ integrations: {}
665665
# @default -- `false`
666666
enableProcessMetrics:
667667

668-
# -- (bool) Enable elevated process privileges on Windows for enhanced process visibility.
669-
# When enabled on Windows, the agent requests SeDebugPrivilege which allows querying all system processes.
670-
# Only applies to Windows nodes. On Linux, this setting is ignored.
671-
# Automatically enabled when both enableProcessMetrics and enableWindows are true, since Windows HostProcess
672-
# containers are inherently privileged and complete process visibility is desired for monitoring.
673-
# Can be explicitly set to false via this setting or kubelet.agentConfig.enable_elevated_process_priv to override.
674-
# ref: https://docs.newrelic.com/docs/infrastructure/install-infrastructure-agent/configuration/infrastructure-agent-configuration-settings/#enable-elevated-process-priv
675-
# @default -- Auto-enabled when `enableProcessMetrics: true` and `enableWindows: true`
676-
enableElevatedProcessPrivilege:
677-
678668
# Prefix nodes display name with cluster to reduce chances of collisions
679669
# prefixDisplayNameWithCluster: false
680670

0 commit comments

Comments
 (0)