diff --git a/docs/operator-user-guide.md b/docs/operator-user-guide.md index 7a29b06..6b56f0e 100644 --- a/docs/operator-user-guide.md +++ b/docs/operator-user-guide.md @@ -552,8 +552,10 @@ default, generated workloads set `runAsNonRoot: true`, use the Linux capabilities. These defaults satisfy the corresponding Kubernetes Pod Security `restricted` controls. Explicit overrides can relax them and may then be rejected by cluster admission policy. For legacy compatibility, an explicit -`runAsUser: 0` without an explicit `runAsNonRoot` derives `runAsNonRoot: false`; -that configuration cannot run in a `restricted` namespace. +`runAsUser: 0` with `runAsNonRoot: false` remains supported and emits an +Operator warning; omitting `runAsNonRoot` with UID 0 derives the same value. +Migrate these workloads to a non-zero UID; root workloads cannot run in a +`restricted` namespace. On OpenShift, use explicit empty objects at Pool level to delegate the runtime identity and container security settings to the namespace SCC, following the diff --git a/docs/operator-user-guide.zh-CN.md b/docs/operator-user-guide.zh-CN.md index d544771..426cf7b 100644 --- a/docs/operator-user-guide.zh-CN.md +++ b/docs/operator-user-guide.zh-CN.md @@ -522,9 +522,10 @@ spec: Tenant 级字段,Tenant 级字段再覆盖 Operator 默认值。Operator 默认设置 `runAsNonRoot: true`、`RuntimeDefault` seccomp、禁止权限提升并丢弃全部 Linux capabilities,满足 Kubernetes Pod Security `restricted` 对应要求。显式覆盖可以 -放宽这些默认值,因此可能被集群准入策略拒绝。为兼容存量配置,如果显式配置 -`runAsUser: 0`、但没有显式配置 `runAsNonRoot`,Operator 会推导 -`runAsNonRoot: false`;该配置不能用于 `restricted` namespace。 +放宽这些默认值,因此可能被集群准入策略拒绝。为兼容存量配置,显式配置 +`runAsUser: 0` 和 `runAsNonRoot: false` 时仍允许运行,但 Operator 会输出警告; +UID 0 场景未设置 `runAsNonRoot` 时也会推导为 `false`。建议迁移到非零 UID; +root 工作负载不能用于 `restricted` namespace。 在 OpenShift 上,应在 Pool 级使用显式空对象,把运行身份和容器安全设置交给 namespace SCC;该契约与 MinIO Operator 保持一致: diff --git a/src/console/handlers/security_context.rs b/src/console/handlers/security_context.rs index 554b98f..5335df1 100644 --- a/src/console/handlers/security_context.rs +++ b/src/console/handlers/security_context.rs @@ -305,6 +305,29 @@ mod tests { )); } + #[test] + fn legacy_root_update_remains_accepted() { + let mut tenant = crate::tests::create_test_tenant(None, None); + let changed = apply_validated_security_context_update( + &mut tenant, + &UpdateSecurityContextRequest { + run_as_user: PatchField::Value(0), + run_as_group: PatchField::Missing, + fs_group: PatchField::Missing, + run_as_non_root: PatchField::Value(false), + }, + ) + .expect("legacy root identity should remain compatible"); + + assert!(changed); + let context = tenant + .spec + .security_context + .expect("security context should be persisted"); + assert_eq!(context.run_as_user, Some(0)); + assert_eq!(context.run_as_non_root, Some(false)); + } + #[test] fn delegated_context_rejects_lossy_console_updates() { let mut tenant = crate::tests::create_test_tenant(None, None); diff --git a/src/types/v1alpha1/tenant/workloads.rs b/src/types/v1alpha1/tenant/workloads.rs index 250246a..0b8a15b 100755 --- a/src/types/v1alpha1/tenant/workloads.rs +++ b/src/types/v1alpha1/tenant/workloads.rs @@ -835,14 +835,23 @@ impl Tenant { .run_as_non_root .or(security.pod.run_as_non_root); - if effective_run_as_user == Some(0) && effective_run_as_non_root == Some(true) { - return Err(types::error::Error::InvalidWorkloadSecurityProfile { - name: self.name(), - message: format!( - "pool '{}' resolves runAsUser to UID 0 while runAsNonRoot is explicitly true; use a non-zero UID or explicitly set the effective runAsNonRoot value to false", - pool.name - ), - }); + if effective_run_as_user == Some(0) { + if effective_run_as_non_root == Some(true) { + return Err(types::error::Error::InvalidWorkloadSecurityProfile { + name: self.name(), + message: format!( + "pool '{}' resolves runAsUser to UID 0 while runAsNonRoot is explicitly true; use a non-zero UID or explicitly set the effective runAsNonRoot value to false", + pool.name + ), + }); + } + + tracing::warn!( + tenant = %self.name(), + pool = %pool.name, + run_as_user = 0, + "RustFS workload is configured to run as root; migrate runAsUser to a non-zero UID" + ); } Ok(())