diff --git a/examples/kustomization/base/tenant.yaml b/examples/kustomization/base/tenant.yaml index 33c4fc5ddb2..adc80d6d064 100644 --- a/examples/kustomization/base/tenant.yaml +++ b/examples/kustomization/base/tenant.yaml @@ -194,6 +194,11 @@ spec: runAsGroup: 1000 runAsNonRoot: true fsGroup: 1000 + ## Configure container security context + containerSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + runAsNonRoot: true ## Enable automatic Kubernetes based certificate generation and signing as explained in ## https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster requestAutoCert: true diff --git a/examples/kustomization/tenant-lite/tenant.yaml b/examples/kustomization/tenant-lite/tenant.yaml index 67fd068db5e..2d58e1ecce9 100644 --- a/examples/kustomization/tenant-lite/tenant.yaml +++ b/examples/kustomization/tenant-lite/tenant.yaml @@ -24,3 +24,7 @@ spec: resources: requests: storage: 2Gi + containerSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + runAsNonRoot: true diff --git a/helm/operator/templates/console-deployment.yaml b/helm/operator/templates/console-deployment.yaml index 5287db593c6..20c08f9a546 100644 --- a/helm/operator/templates/console-deployment.yaml +++ b/helm/operator/templates/console-deployment.yaml @@ -63,6 +63,10 @@ spec: {{- with .Values.console.volumeMounts }} {{- toYaml . | nindent 12 }} {{- end }} + securityContext: + {{- with .Values.console.containerSecurityContext }} + {{- toYaml . | nindent 12 }} + {{- end }} volumes: {{- with .Values.console.volumes }} {{- toYaml . | nindent 8 }} diff --git a/helm/operator/templates/minio.min.io_tenants.yaml b/helm/operator/templates/minio.min.io_tenants.yaml index 851378b3d0d..d260fbdfc1d 100644 --- a/helm/operator/templates/minio.min.io_tenants.yaml +++ b/helm/operator/templates/minio.min.io_tenants.yaml @@ -7647,6 +7647,67 @@ spec: additionalProperties: type: string type: object + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object labels: additionalProperties: type: string diff --git a/helm/operator/templates/operator-deployment.yaml b/helm/operator/templates/operator-deployment.yaml index 9ea151f493c..f3c227b6f5c 100644 --- a/helm/operator/templates/operator-deployment.yaml +++ b/helm/operator/templates/operator-deployment.yaml @@ -49,7 +49,11 @@ spec: {{ toYaml . | nindent 10 }} {{- end }} resources: - {{- toYaml .Values.operator.resources | nindent 12 }} + {{- toYaml .Values.operator.resources | nindent 12 }} + securityContext: + {{- with .Values.operator.containerSecurityContext }} + {{- toYaml . | nindent 12 }} + {{- end }} {{- with .Values.operator.initContainers }} initContainers: {{- toYaml . | nindent 8 }} diff --git a/helm/operator/values.yaml b/helm/operator/values.yaml index affa550895e..8ee24ef02cc 100644 --- a/helm/operator/values.yaml +++ b/helm/operator/values.yaml @@ -23,6 +23,10 @@ operator: runAsGroup: 1000 runAsNonRoot: true fsGroup: 1000 + containerSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + runAsNonRoot: true nodeSelector: { } affinity: podAntiAffinity: @@ -58,6 +62,9 @@ console: securityContext: runAsUser: 1000 runAsNonRoot: true + containerSecurityContext: + runAsUser: 1000 + runAsNonRoot: true ingress: enabled: false ingressClassName: "" diff --git a/helm/tenant/templates/tenant.yaml b/helm/tenant/templates/tenant.yaml index b4675ad205b..a55f5f7d8e8 100644 --- a/helm/tenant/templates/tenant.yaml +++ b/helm/tenant/templates/tenant.yaml @@ -74,6 +74,10 @@ spec: securityContext: {{- toYaml . | nindent 8 }} {{- end }} + {{- with (dig "containerSecurityContext" (dict) .) }} + containerSecurityContext: + {{- toYaml . | nindent 8 }} + {{- end }} {{- with (dig "topologySpreadConstraints" (list) .) }} topologySpreadConstraints: {{- toYaml . | nindent 8 }} diff --git a/helm/tenant/values.yaml b/helm/tenant/values.yaml index 3fd0e62c485..7401e6f47e5 100644 --- a/helm/tenant/values.yaml +++ b/helm/tenant/values.yaml @@ -56,7 +56,16 @@ tenant: ## Configure resource requests and limits for MinIO containers resources: { } ## Configure security context - securityContext: { } + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + runAsNonRoot: true + ## Configure container security context + containerSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + runAsNonRoot: true ## Configure topology constraints topologySpreadConstraints: [ ] ## Configure Runtime Class diff --git a/pkg/apis/minio.min.io/v2/types.go b/pkg/apis/minio.min.io/v2/types.go index f6ee24fe43c..2d76be08998 100644 --- a/pkg/apis/minio.min.io/v2/types.go +++ b/pkg/apis/minio.min.io/v2/types.go @@ -628,10 +628,18 @@ type Pool struct { // // * `runAsUser` + // - // * `seLinuxOptions` + - // // +optional SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"` + // Specify the https://kubernetes.io/docs/tasks/configure-pod-container/security-context/[Security Context] of containers in the pool. The Operator supports only the following container security fields: + + // + // * `runAsGroup` + + // + // * `runAsNonRoot` + + // + // * `runAsUser` + + // + // +optional + ContainerSecurityContext *corev1.SecurityContext `json:"containerSecurityContext,omitempty"` // *Optional* + // // Specify custom labels and annotations to append to the Pool. diff --git a/pkg/resources/statefulsets/minio-statefulset.go b/pkg/resources/statefulsets/minio-statefulset.go index 25cb6a339f3..dad255736b0 100644 --- a/pkg/resources/statefulsets/minio-statefulset.go +++ b/pkg/resources/statefulsets/minio-statefulset.go @@ -344,6 +344,7 @@ func poolMinioServerContainer(t *miniov2.Tenant, wsSecret *v1.Secret, skipEnvVar LivenessProbe: t.Spec.Liveness, ReadinessProbe: t.Spec.Readiness, StartupProbe: t.Spec.Startup, + SecurityContext: poolContainerSecurityContext(pool), } } @@ -403,6 +404,30 @@ func poolSecurityContext(pool *miniov2.Pool, status *miniov2.PoolStatus) *v1.Pod return &securityContext } +// Builds the security context for containers in a Pool +func poolContainerSecurityContext(pool *miniov2.Pool) *v1.SecurityContext { + runAsNonRoot := true + var runAsUser int64 = 1000 + var runAsGroup int64 = 1000 + // Default to Pod values + if pool.SecurityContext != nil { + runAsNonRoot = *pool.SecurityContext.RunAsNonRoot + runAsUser = *pool.SecurityContext.RunAsUser + runAsGroup = *pool.SecurityContext.RunAsGroup + } + + containerSecurityContext := corev1.SecurityContext{ + RunAsNonRoot: &runAsNonRoot, + RunAsUser: &runAsUser, + RunAsGroup: &runAsGroup, + } + + if pool != nil && pool.ContainerSecurityContext != nil { + containerSecurityContext = *pool.ContainerSecurityContext + } + return &containerSecurityContext +} + // NewPool creates a new StatefulSet for the given Cluster. func NewPool(t *miniov2.Tenant, wsSecret *v1.Secret, skipEnvVars map[string][]byte, pool *miniov2.Pool, poolStatus *miniov2.PoolStatus, serviceName, hostsTemplate, operatorVersion string, operatorTLS bool, operatorCATLS bool) *appsv1.StatefulSet { var podVolumes []corev1.Volume diff --git a/resources/base/crds/minio.min.io_tenants.yaml b/resources/base/crds/minio.min.io_tenants.yaml index 1f3b1e5e421..e448afa869a 100644 --- a/resources/base/crds/minio.min.io_tenants.yaml +++ b/resources/base/crds/minio.min.io_tenants.yaml @@ -7647,6 +7647,67 @@ spec: additionalProperties: type: string type: object + containerSecurityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object labels: additionalProperties: type: string diff --git a/testing/deploy-tenant-upgrade.sh b/testing/deploy-tenant-upgrade.sh index ddda6d8dbb4..7d79f737efc 100755 --- a/testing/deploy-tenant-upgrade.sh +++ b/testing/deploy-tenant-upgrade.sh @@ -135,13 +135,21 @@ function main() { setup_kind - if [ -n "$lower_version" ] + error=$( { + if [ -n "$lower_version" ] + then + # Test specific version of operator + install_operator_version $lower_version + else + # Test latest release + install_operator_version + fi + } 2>&1 ) + + echo "$error" + if [ -n "$error" ] then - # Test specific version of operator - install_operator_version $lower_version - else - # Test latest release - install_operator_version + install_operator fi install_tenant