diff --git a/charts/k3k/templates/crds/k3k.io_clusters.yaml b/charts/k3k/templates/crds/k3k.io_clusters.yaml
index 23dd186d..e4d7d394 100644
--- a/charts/k3k/templates/crds/k3k.io_clusters.yaml
+++ b/charts/k3k/templates/crds/k3k.io_clusters.yaml
@@ -1276,6 +1276,13 @@ spec:
x-kubernetes-validations:
- message: ingress, loadbalancer and nodePort are mutually exclusive; only one can be set
rule: '[has(self.ingress), has(self.loadBalancer), has(self.nodePort)].filter(x, x).size() <= 1'
+ hostUsers:
+ description: |-
+ HostUsers sets the user namespace for server and agent pods.
+ If set to true or not present, the pod will be run in the host user namespace.
+ When set to false, a new userns is created for the pod.
+ This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.
+ type: boolean
mirrorHostNodes:
description: |-
MirrorHostNodes controls whether node objects from the host cluster
@@ -3815,6 +3822,13 @@ spec:
x-kubernetes-list-type: atomic
type: object
type: object
+ hostUsers:
+ description: |-
+ HostUsers sets the user namespace for server and agent pods.
+ If set to true or not present, the pod will be run in the host user namespace.
+ When set to false, a new userns is created for the pod.
+ This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.
+ type: boolean
name:
description: name is the name of the VirtualClusterPolicy currently applied to this cluster.
minLength: 1
diff --git a/charts/k3k/templates/crds/k3k.io_virtualclusterpolicies.yaml b/charts/k3k/templates/crds/k3k.io_virtualclusterpolicies.yaml
index 90acf3ae..a056411b 100644
--- a/charts/k3k/templates/crds/k3k.io_virtualclusterpolicies.yaml
+++ b/charts/k3k/templates/crds/k3k.io_virtualclusterpolicies.yaml
@@ -1820,6 +1820,13 @@ spec:
disableNetworkPolicy:
description: DisableNetworkPolicy indicates whether to disable the creation of a default network policy for cluster isolation.
type: boolean
+ hostUsers:
+ description: |-
+ HostUsers sets the user namespace for server and agent pods.
+ If set to true or not present, the pod will be run in the host user namespace.
+ When set to false, a new userns is created for the pod.
+ This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.
+ type: boolean
limit:
description: |-
Limit specifies the LimitRange that will be applied to all pods within the VirtualClusterPolicy
diff --git a/docs/crds/crds.adoc b/docs/crds/crds.adoc
index 6f99077d..37b3bc0d 100644
--- a/docs/crds/crds.adoc
+++ b/docs/crds/crds.adoc
@@ -70,6 +70,10 @@ This includes both node affinity and pod affinity/anti-affinity rules. + | |
to the agent and server pods of the cluster in virtual or shared mode. + | |
| *`securityContext`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#securitycontext-v1-core[$$SecurityContext$$]__ | RuntimeClassName specifies alternative runtime class for the +
agent and server pods of the cluster in virtual or shared mode. + | |
+| *`hostUsers`* __boolean__ | HostUsers sets the user namespace for server and agent pods. +
+If set to true or not present, the pod will be run in the host user namespace. +
+When set to false, a new userns is created for the pod. +
+This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + | |
|===
@@ -226,6 +230,10 @@ to the agent and server pods of the cluster in virtual or shared mode. +
This option will override the SecurityContext set by default for virtual mode. + | |
| *`runtimeClassName`* __string__ | RuntimeClassName specifies alternative runtime class for the +
agent and server pods of the cluster in virtual or shared mode. + | |
+| *`hostUsers`* __boolean__ | HostUsers sets the user namespace for server and agent pods. +
+If set to true or not present, the pod will be run in the host user namespace. +
+When set to false, a new userns is created for the pod. +
+This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + | |
|===
@@ -790,6 +798,10 @@ This includes both node affinity and pod affinity/anti-affinity rules. + | |
to the agent and server pods of the cluster in virtual or shared mode. + | |
| *`securityContext`* __link:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#securitycontext-v1-core[$$SecurityContext$$]__ | RuntimeClassName specifies alternative runtime class for the +
agent and server pods of the cluster in virtual or shared mode. + | |
+| *`hostUsers`* __boolean__ | HostUsers sets the user namespace for server and agent pods. +
+If set to true or not present, the pod will be run in the host user namespace. +
+When set to false, a new userns is created for the pod. +
+This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. + | |
|===
diff --git a/docs/crds/crds.md b/docs/crds/crds.md
index c2bf8446..d81c6227 100644
--- a/docs/crds/crds.md
+++ b/docs/crds/crds.md
@@ -53,6 +53,7 @@ _Appears in:_
| `sync` _[SyncConfig](#syncconfig)_ | sync is the SyncConfig enforced by the active VirtualClusterPolicy. | | |
| `runtimeClassName` _string_ | SecurityContext specifies custom SecurityContext to be added
to the agent and server pods of the cluster in virtual or shared mode. | | |
| `securityContext` _[SecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#securitycontext-v1-core)_ | RuntimeClassName specifies alternative runtime class for the
agent and server pods of the cluster in virtual or shared mode. | | |
+| `hostUsers` _boolean_ | HostUsers sets the user namespace for server and agent pods.
If set to true or not present, the pod will be run in the host user namespace.
When set to false, a new userns is created for the pod.
This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. | | |
#### Cluster
@@ -164,6 +165,7 @@ _Appears in:_
| `secretMounts` _[SecretMount](#secretmount) array_ | SecretMounts specifies a list of secrets to mount into server and agent pods.
Each entry defines a secret and its mount path within the pods. | | |
| `securityContext` _[SecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#securitycontext-v1-core)_ | SecurityContext specifies custom SecurityContext to be added
to the agent and server pods of the cluster in virtual or shared mode.
This option will override the SecurityContext set by default for virtual mode. | | |
| `runtimeClassName` _string_ | RuntimeClassName specifies alternative runtime class for the
agent and server pods of the cluster in virtual or shared mode. | | |
+| `hostUsers` _boolean_ | HostUsers sets the user namespace for server and agent pods.
If set to true or not present, the pod will be run in the host user namespace.
When set to false, a new userns is created for the pod.
This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. | | |
#### ClusterStatus
@@ -592,6 +594,7 @@ _Appears in:_
| `sync` _[SyncConfig](#syncconfig)_ | Sync specifies the resources types that will be synced from virtual cluster to host cluster. | \{ \} | |
| `runtimeClassName` _string_ | SecurityContext specifies custom SecurityContext to be added
to the agent and server pods of the cluster in virtual or shared mode. | | |
| `securityContext` _[SecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.31/#securitycontext-v1-core)_ | RuntimeClassName specifies alternative runtime class for the
agent and server pods of the cluster in virtual or shared mode. | | |
+| `hostUsers` _boolean_ | HostUsers sets the user namespace for server and agent pods.
If set to true or not present, the pod will be run in the host user namespace.
When set to false, a new userns is created for the pod.
This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature. | | |
#### VirtualClusterPolicyStatus
diff --git a/pkg/apis/k3k.io/v1beta1/types.go b/pkg/apis/k3k.io/v1beta1/types.go
index c71de418..f8264a7c 100644
--- a/pkg/apis/k3k.io/v1beta1/types.go
+++ b/pkg/apis/k3k.io/v1beta1/types.go
@@ -216,6 +216,14 @@ type ClusterSpec struct {
//
// +optional
RuntimeClassName *string `json:"runtimeClassName,omitempty"`
+
+ // HostUsers sets the user namespace for server and agent pods.
+ // If set to true or not present, the pod will be run in the host user namespace.
+ // When set to false, a new userns is created for the pod.
+ // This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.
+ //
+ // +optional
+ HostUsers *bool `json:"hostUsers,omitempty"`
}
// SecretMount defines a secret to be mounted into server or agent pods,
@@ -660,6 +668,14 @@ type AppliedPolicy struct {
//
// +optional
SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`
+
+ // HostUsers sets the user namespace for server and agent pods.
+ // If set to true or not present, the pod will be run in the host user namespace.
+ // When set to false, a new userns is created for the pod.
+ // This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.
+ //
+ // +optional
+ HostUsers *bool `json:"hostUsers,omitempty"`
}
// ClusterPhase is a high-level summary of the cluster's current lifecycle state.
@@ -779,6 +795,14 @@ type VirtualClusterPolicySpec struct {
//
// +optional
SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`
+
+ // HostUsers sets the user namespace for server and agent pods.
+ // If set to true or not present, the pod will be run in the host user namespace.
+ // When set to false, a new userns is created for the pod.
+ // This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.
+ //
+ // +optional
+ HostUsers *bool `json:"hostUsers,omitempty"`
}
// PodSecurityAdmissionLevel is the policy level applied to the pods in the namespace.
diff --git a/pkg/apis/k3k.io/v1beta1/zz_generated.deepcopy.go b/pkg/apis/k3k.io/v1beta1/zz_generated.deepcopy.go
index 5389c9a0..4cc77f7d 100644
--- a/pkg/apis/k3k.io/v1beta1/zz_generated.deepcopy.go
+++ b/pkg/apis/k3k.io/v1beta1/zz_generated.deepcopy.go
@@ -65,6 +65,11 @@ func (in *AppliedPolicy) DeepCopyInto(out *AppliedPolicy) {
*out = new(v1.SecurityContext)
(*in).DeepCopyInto(*out)
}
+ if in.HostUsers != nil {
+ in, out := &in.HostUsers, &out.HostUsers
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppliedPolicy.
@@ -252,6 +257,11 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
*out = new(string)
**out = **in
}
+ if in.HostUsers != nil {
+ in, out := &in.HostUsers, &out.HostUsers
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec.
@@ -776,6 +786,11 @@ func (in *VirtualClusterPolicySpec) DeepCopyInto(out *VirtualClusterPolicySpec)
*out = new(v1.SecurityContext)
(*in).DeepCopyInto(*out)
}
+ if in.HostUsers != nil {
+ in, out := &in.HostUsers, &out.HostUsers
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualClusterPolicySpec.
diff --git a/pkg/controller/cluster/agent/shared.go b/pkg/controller/cluster/agent/shared.go
index 74b8880d..0a515b54 100644
--- a/pkg/controller/cluster/agent/shared.go
+++ b/pkg/controller/cluster/agent/shared.go
@@ -254,6 +254,14 @@ func (s *SharedAgent) podSpec(ctx context.Context) corev1.PodSpec {
podSpec.RuntimeClassName = runtimeClassName
+ hostUsers := s.cluster.Spec.HostUsers
+ if s.cluster.Status.Policy != nil && s.cluster.Status.Policy.HostUsers != nil {
+ log.V(1).Info("Using hostUsers from policy", "policyName", s.cluster.Status.PolicyName, "clusterName", s.cluster.Name)
+ hostUsers = s.cluster.Status.Policy.HostUsers
+ }
+
+ podSpec.HostUsers = hostUsers
+
return podSpec
}
diff --git a/pkg/controller/cluster/agent/virtual.go b/pkg/controller/cluster/agent/virtual.go
index 48980f0c..ce302156 100644
--- a/pkg/controller/cluster/agent/virtual.go
+++ b/pkg/controller/cluster/agent/virtual.go
@@ -291,5 +291,13 @@ func (v *VirtualAgent) podSpec(ctx context.Context, image, name string) corev1.P
podSpec.RuntimeClassName = runtimeClassName
+ hostUsers := v.cluster.Spec.HostUsers
+ if v.cluster.Status.Policy != nil && v.cluster.Status.Policy.HostUsers != nil {
+ log.V(1).Info("Using hostUsers from policy", "policyName", v.cluster.Status.PolicyName, "clusterName", v.cluster.Name)
+ hostUsers = v.cluster.Status.Policy.HostUsers
+ }
+
+ podSpec.HostUsers = hostUsers
+
return podSpec
}
diff --git a/pkg/controller/cluster/server/server.go b/pkg/controller/cluster/server/server.go
index 49815aab..e0d59dbe 100644
--- a/pkg/controller/cluster/server/server.go
+++ b/pkg/controller/cluster/server/server.go
@@ -264,6 +264,14 @@ func (s *Server) podSpec(ctx context.Context, image, name string, persistent boo
podSpec.RuntimeClassName = runtimeClassName
+ hostUsers := s.cluster.Spec.HostUsers
+ if s.cluster.Status.Policy != nil && s.cluster.Status.Policy.HostUsers != nil {
+ log.V(1).Info("Using hostUsers from policy", "policyName", s.cluster.Status.PolicyName, "clusterName", s.cluster.Name)
+ hostUsers = s.cluster.Status.Policy.HostUsers
+ }
+
+ podSpec.HostUsers = hostUsers
+
// specify resource limits if specified for the servers.
if s.cluster.Spec.ServerLimit != nil {
podSpec.Containers[0].Resources = corev1.ResourceRequirements{
diff --git a/pkg/controller/policy/policy.go b/pkg/controller/policy/policy.go
index c315ee62..c504f589 100644
--- a/pkg/controller/policy/policy.go
+++ b/pkg/controller/policy/policy.go
@@ -497,6 +497,7 @@ func (c *VirtualClusterPolicyReconciler) reconcileClusters(ctx context.Context,
AgentAffinity: policy.Spec.DefaultAgentAffinity,
SecurityContext: policy.Spec.SecurityContext,
RuntimeClassName: policy.Spec.RuntimeClassName,
+ HostUsers: policy.Spec.HostUsers,
}
if !reflect.DeepEqual(origStatus, &cluster.Status) {