From 805237a8da32ae653b022065276b90b34410e981 Mon Sep 17 00:00:00 2001 From: lyndon-li <98304688+Lyndon-Li@users.noreply.github.com> Date: Thu, 17 Jul 2025 11:54:42 +0800 Subject: [PATCH] issue 8185: allow to disable node-agent host path (#9068) Signed-off-by: Lyndon-Li --- changelogs/unreleased/9068-Lyndon-Li | 1 + pkg/cmd/cli/install/install.go | 4 ++ pkg/install/daemonset.go | 90 +++++++++++++++------------- pkg/install/daemonset_test.go | 6 ++ pkg/install/deployment.go | 7 +++ pkg/install/resources.go | 2 + 6 files changed, 70 insertions(+), 40 deletions(-) create mode 100644 changelogs/unreleased/9068-Lyndon-Li diff --git a/changelogs/unreleased/9068-Lyndon-Li b/changelogs/unreleased/9068-Lyndon-Li new file mode 100644 index 000000000..7eca57dfd --- /dev/null +++ b/changelogs/unreleased/9068-Lyndon-Li @@ -0,0 +1 @@ +Fix issue #8185, allow users to disable pod volume host path mount for node-agent \ No newline at end of file diff --git a/pkg/cmd/cli/install/install.go b/pkg/cmd/cli/install/install.go index 4c1612334..dbb1c32e1 100644 --- a/pkg/cmd/cli/install/install.go +++ b/pkg/cmd/cli/install/install.go @@ -89,6 +89,7 @@ type Options struct { RepoMaintenanceJobConfigMap string NodeAgentConfigMap string ItemBlockWorkerCount int + NodeAgentDisableHostPath bool } // BindFlags adds command line values to the options struct. @@ -134,6 +135,7 @@ func (o *Options) BindFlags(flags *pflag.FlagSet) { flags.BoolVar(&o.DefaultSnapshotMoveData, "default-snapshot-move-data", o.DefaultSnapshotMoveData, "Bool flag to configure Velero server to move data by default for all snapshots supporting data movement. Optional.") flags.BoolVar(&o.DisableInformerCache, "disable-informer-cache", o.DisableInformerCache, "Disable informer cache for Get calls on restore. With this enabled, it will speed up restore in cases where there are backup resources which already exist in the cluster, but for very large clusters this will increase velero memory usage. Default is false (don't disable). Optional.") flags.BoolVar(&o.ScheduleSkipImmediately, "schedule-skip-immediately", o.ScheduleSkipImmediately, "Skip the first scheduled backup immediately after creating a schedule. Default is false (don't skip).") + flags.BoolVar(&o.NodeAgentDisableHostPath, "node-agent-disable-host-path", o.NodeAgentDisableHostPath, "Don't mount the pod volume host path to node-agent. Optional. Pod volume host path mount is required by fs-backup but could be disabled for other backup methods.") flags.IntVar( &o.KeepLatestMaintenanceJobs, @@ -218,6 +220,7 @@ func NewInstallOptions() *Options { DefaultSnapshotMoveData: false, DisableInformerCache: false, ScheduleSkipImmediately: false, + NodeAgentDisableHostPath: false, } } @@ -292,6 +295,7 @@ func (o *Options) AsVeleroOptions() (*install.VeleroOptions, error) { RepoMaintenanceJobConfigMap: o.RepoMaintenanceJobConfigMap, NodeAgentConfigMap: o.NodeAgentConfigMap, ItemBlockWorkerCount: o.ItemBlockWorkerCount, + NodeAgentDisableHostPath: o.NodeAgentDisableHostPath, }, nil } diff --git a/pkg/install/daemonset.go b/pkg/install/daemonset.go index 7eaa2a094..0a8e7570a 100644 --- a/pkg/install/daemonset.go +++ b/pkg/install/daemonset.go @@ -63,6 +63,54 @@ func DaemonSet(namespace string, opts ...podTemplateOption) *appsv1api.DaemonSet dsName = "node-agent-windows" } + volumes := []corev1api.Volume{} + volumeMounts := []corev1api.VolumeMount{} + if !c.nodeAgentDisableHostPath { + volumes = append(volumes, []corev1api.Volume{ + { + Name: "host-pods", + VolumeSource: corev1api.VolumeSource{ + HostPath: &corev1api.HostPathVolumeSource{ + Path: "/var/lib/kubelet/pods", + }, + }, + }, + { + Name: "host-plugins", + VolumeSource: corev1api.VolumeSource{ + HostPath: &corev1api.HostPathVolumeSource{ + Path: "/var/lib/kubelet/plugins", + }, + }, + }, + }...) + + volumeMounts = append(volumeMounts, []corev1api.VolumeMount{ + { + Name: nodeagent.HostPodVolumeMount, + MountPath: nodeagent.HostPodVolumeMountPath(), + MountPropagation: &mountPropagationMode, + }, + { + Name: "host-plugins", + MountPath: "/var/lib/kubelet/plugins", + MountPropagation: &mountPropagationMode, + }, + }...) + } + + volumes = append(volumes, corev1api.Volume{ + Name: "scratch", + VolumeSource: corev1api.VolumeSource{ + EmptyDir: new(corev1api.EmptyDirVolumeSource), + }, + }) + + volumeMounts = append(volumeMounts, corev1api.VolumeMount{ + Name: "scratch", + MountPath: "/scratch", + }) + daemonSet := &appsv1api.DaemonSet{ ObjectMeta: objectMeta(namespace, dsName), TypeMeta: metav1.TypeMeta{ @@ -88,30 +136,7 @@ func DaemonSet(namespace string, opts ...podTemplateOption) *appsv1api.DaemonSet SecurityContext: &corev1api.PodSecurityContext{ RunAsUser: &userID, }, - Volumes: []corev1api.Volume{ - { - Name: "host-pods", - VolumeSource: corev1api.VolumeSource{ - HostPath: &corev1api.HostPathVolumeSource{ - Path: "/var/lib/kubelet/pods", - }, - }, - }, - { - Name: "host-plugins", - VolumeSource: corev1api.VolumeSource{ - HostPath: &corev1api.HostPathVolumeSource{ - Path: "/var/lib/kubelet/plugins", - }, - }, - }, - { - Name: "scratch", - VolumeSource: corev1api.VolumeSource{ - EmptyDir: new(corev1api.EmptyDirVolumeSource), - }, - }, - }, + Volumes: volumes, Containers: []corev1api.Container{ { Name: dsName, @@ -125,22 +150,7 @@ func DaemonSet(namespace string, opts ...podTemplateOption) *appsv1api.DaemonSet SecurityContext: &corev1api.SecurityContext{ Privileged: &c.privilegedNodeAgent, }, - VolumeMounts: []corev1api.VolumeMount{ - { - Name: nodeagent.HostPodVolumeMount, - MountPath: nodeagent.HostPodVolumeMountPath(), - MountPropagation: &mountPropagationMode, - }, - { - Name: "host-plugins", - MountPath: "/var/lib/kubelet/plugins", - MountPropagation: &mountPropagationMode, - }, - { - Name: "scratch", - MountPath: "/scratch", - }, - }, + VolumeMounts: volumeMounts, Env: []corev1api.EnvVar{ { Name: "NODE_NAME", diff --git a/pkg/install/daemonset_test.go b/pkg/install/daemonset_test.go index de91feb28..bc5b22fcc 100644 --- a/pkg/install/daemonset_test.go +++ b/pkg/install/daemonset_test.go @@ -38,6 +38,8 @@ func TestDaemonSet(t *testing.T) { assert.Equal(t, "linux", string(ds.Spec.Template.Spec.OS.Name)) assert.Equal(t, corev1api.PodSecurityContext{RunAsUser: &userID}, *ds.Spec.Template.Spec.SecurityContext) assert.Equal(t, corev1api.SecurityContext{Privileged: &boolFalse}, *ds.Spec.Template.Spec.Containers[0].SecurityContext) + assert.Len(t, ds.Spec.Template.Spec.Volumes, 3) + assert.Len(t, ds.Spec.Template.Spec.Containers[0].VolumeMounts, 3) ds = DaemonSet("velero", WithPrivilegedNodeAgent(true)) assert.Equal(t, corev1api.SecurityContext{Privileged: &boolTrue}, *ds.Spec.Template.Spec.Containers[0].SecurityContext) @@ -61,6 +63,10 @@ func TestDaemonSet(t *testing.T) { ds = DaemonSet("velero", WithServiceAccountName("test-sa")) assert.Equal(t, "test-sa", ds.Spec.Template.Spec.ServiceAccountName) + ds = DaemonSet("velero", WithNodeAgentDisableHostPath(true)) + assert.Len(t, ds.Spec.Template.Spec.Volumes, 1) + assert.Len(t, ds.Spec.Template.Spec.Containers[0].VolumeMounts, 1) + ds = DaemonSet("velero", WithForWindows()) assert.Equal(t, "node-agent-windows", ds.Spec.Template.Spec.Containers[0].Name) assert.Equal(t, "velero", ds.ObjectMeta.Namespace) diff --git a/pkg/install/deployment.go b/pkg/install/deployment.go index 335265718..36ac8fdf6 100644 --- a/pkg/install/deployment.go +++ b/pkg/install/deployment.go @@ -59,6 +59,7 @@ type podTemplateConfig struct { nodeAgentConfigMap string itemBlockWorkerCount int forWindows bool + nodeAgentDisableHostPath bool } func WithImage(image string) podTemplateOption { @@ -226,6 +227,12 @@ func WithForWindows() podTemplateOption { } } +func WithNodeAgentDisableHostPath(disable bool) podTemplateOption { + return func(c *podTemplateConfig) { + c.nodeAgentDisableHostPath = disable + } +} + func Deployment(namespace string, opts ...podTemplateOption) *appsv1api.Deployment { // TODO: Add support for server args c := &podTemplateConfig{ diff --git a/pkg/install/resources.go b/pkg/install/resources.go index 21466f21f..b4ea43a76 100644 --- a/pkg/install/resources.go +++ b/pkg/install/resources.go @@ -269,6 +269,7 @@ type VeleroOptions struct { RepoMaintenanceJobConfigMap string NodeAgentConfigMap string ItemBlockWorkerCount int + NodeAgentDisableHostPath bool } func AllCRDs() *unstructured.UnstructuredList { @@ -404,6 +405,7 @@ func AllResources(o *VeleroOptions) *unstructured.UnstructuredList { WithResources(o.NodeAgentPodResources), WithSecret(secretPresent), WithServiceAccountName(serviceAccountName), + WithNodeAgentDisableHostPath(o.NodeAgentDisableHostPath), } if len(o.Features) > 0 { dsOpts = append(dsOpts, WithFeatures(o.Features))