You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ge...@apache.org on 2025/01/10 19:08:21 UTC

(solr-operator) branch main updated: Allow users to configure Solr container's SecurityContext (#743)

This is an automated email from the ASF dual-hosted git repository.

gerlowskija pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr-operator.git


The following commit(s) were added to refs/heads/main by this push:
     new 9f3109e  Allow users to configure Solr container's SecurityContext  (#743)
9f3109e is described below

commit 9f3109e9ffcefcf70fc27dddbe2d973581b41dcb
Author: Jason Gerlowski <ge...@apache.org>
AuthorDate: Fri Jan 10 14:08:16 2025 -0500

    Allow users to configure Solr container's SecurityContext  (#743)
---
 api/v1beta1/common_types.go                        |   4 +
 api/v1beta1/zz_generated.deepcopy.go               |   5 +
 config/crd/bases/solr.apache.org_solrclouds.yaml   | 168 +++++++++++
 .../solr.apache.org_solrprometheusexporters.yaml   | 168 +++++++++++
 controllers/solrcloud_controller_test.go           |  18 +-
 controllers/util/common.go                         |   6 +
 controllers/util/prometheus_exporter_util.go       |   6 +
 controllers/util/solr_util.go                      |   6 +
 helm/solr-operator/Chart.yaml                      |   7 +
 helm/solr-operator/crds/crds.yaml                  | 336 +++++++++++++++++++++
 helm/solr/README.md                                |   1 +
 helm/solr/templates/_custom_option_helpers.tpl     |   4 +
 helm/solr/values.yaml                              |   1 +
 13 files changed, 729 insertions(+), 1 deletion(-)

diff --git a/api/v1beta1/common_types.go b/api/v1beta1/common_types.go
index 6f921a4..2200224 100644
--- a/api/v1beta1/common_types.go
+++ b/api/v1beta1/common_types.go
@@ -73,6 +73,10 @@ type PodOptions struct {
 	// +optional
 	PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext,omitempty"`
 
+	// ContainerSecurityContext the container-level security context used by the pod's primary container
+	// +optional
+	ContainerSecurityContext *corev1.SecurityContext `json:"containerSecurityContext,omitempty"`
+
 	// Additional environment variables to pass to the default container.
 	// +optional
 	EnvVariables []corev1.EnvVar `json:"envVars,omitempty"`
diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go
index 87e030f..d48f048 100644
--- a/api/v1beta1/zz_generated.deepcopy.go
+++ b/api/v1beta1/zz_generated.deepcopy.go
@@ -439,6 +439,11 @@ func (in *PodOptions) DeepCopyInto(out *PodOptions) {
 		*out = new(v1.PodSecurityContext)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.ContainerSecurityContext != nil {
+		in, out := &in.ContainerSecurityContext, &out.ContainerSecurityContext
+		*out = new(v1.SecurityContext)
+		(*in).DeepCopyInto(*out)
+	}
 	if in.EnvVariables != nil {
 		in, out := &in.EnvVariables, &out.EnvVariables
 		*out = make([]v1.EnvVar, len(*in))
diff --git a/config/crd/bases/solr.apache.org_solrclouds.yaml b/config/crd/bases/solr.apache.org_solrclouds.yaml
index 17feeab..38abb60 100644
--- a/config/crd/bases/solr.apache.org_solrclouds.yaml
+++ b/config/crd/bases/solr.apache.org_solrclouds.yaml
@@ -2816,6 +2816,174 @@ spec:
                           type: string
                         description: Annotations to be added for pods.
                         type: object
+                      containerSecurityContext:
+                        description: ContainerSecurityContext the container-level
+                          security context used by the pod's primary container
+                        properties:
+                          allowPrivilegeEscalation:
+                            description: |-
+                              AllowPrivilegeEscalation controls whether a process can gain more
+                              privileges than its parent process. This bool directly controls if
+                              the no_new_privs flag will be set on the container process.
+                              AllowPrivilegeEscalation is true always when the container is:
+                              1) run as Privileged
+                              2) has CAP_SYS_ADMIN
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          capabilities:
+                            description: |-
+                              The capabilities to add/drop when running containers.
+                              Defaults to the default set of capabilities granted by the container runtime.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              add:
+                                description: Added capabilities
+                                items:
+                                  description: Capability represent POSIX capabilities
+                                    type
+                                  type: string
+                                type: array
+                              drop:
+                                description: Removed capabilities
+                                items:
+                                  description: Capability represent POSIX capabilities
+                                    type
+                                  type: string
+                                type: array
+                            type: object
+                          privileged:
+                            description: |-
+                              Run container in privileged mode.
+                              Processes in privileged containers are essentially equivalent to root on the host.
+                              Defaults to false.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          procMount:
+                            description: |-
+                              procMount denotes the type of proc mount to use for the containers.
+                              The default is DefaultProcMount which uses the container runtime defaults for
+                              readonly paths and masked paths.
+                              This requires the ProcMountType feature flag to be enabled.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: string
+                          readOnlyRootFilesystem:
+                            description: |-
+                              Whether this container has a read-only root filesystem.
+                              Default is false.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          runAsGroup:
+                            description: |-
+                              The GID to run the entrypoint of the container process.
+                              Uses runtime default if unset.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            format: int64
+                            type: integer
+                          runAsNonRoot:
+                            description: |-
+                              Indicates that the container must run as a non-root user.
+                              If true, the Kubelet will validate the image at runtime to ensure that it
+                              does not run as UID 0 (root) and fail to start the container if it does.
+                              If unset or false, no such validation will be performed.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                            type: boolean
+                          runAsUser:
+                            description: |-
+                              The UID to run the entrypoint of the container process.
+                              Defaults to user specified in image metadata if unspecified.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            format: int64
+                            type: integer
+                          seLinuxOptions:
+                            description: |-
+                              The SELinux context to be applied to the container.
+                              If unspecified, the container runtime will allocate a random SELinux context for each
+                              container.  May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              level:
+                                description: Level is SELinux level label that applies
+                                  to the container.
+                                type: string
+                              role:
+                                description: Role is a SELinux role label that applies
+                                  to the container.
+                                type: string
+                              type:
+                                description: Type is a SELinux type label that applies
+                                  to the container.
+                                type: string
+                              user:
+                                description: User is a SELinux user label that applies
+                                  to the container.
+                                type: string
+                            type: object
+                          seccompProfile:
+                            description: |-
+                              The seccomp options to use by this container. If seccomp options are
+                              provided at both the pod & container level, the container options
+                              override the pod options.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              localhostProfile:
+                                description: |-
+                                  localhostProfile indicates a profile defined in a file on the node should be used.
+                                  The profile must be preconfigured on the node to work.
+                                  Must be a descending path, relative to the kubelet's configured seccomp profile location.
+                                  Must be set if type is "Localhost". Must NOT be set for any other type.
+                                type: string
+                              type:
+                                description: |-
+                                  type indicates which kind of seccomp profile will be applied.
+                                  Valid options are:
+
+
+                                  Localhost - a profile defined in a file on the node should be used.
+                                  RuntimeDefault - the container runtime default profile should be used.
+                                  Unconfined - no profile should be applied.
+                                type: string
+                            required:
+                            - type
+                            type: object
+                          windowsOptions:
+                            description: |-
+                              The Windows specific settings applied to all containers.
+                              If unspecified, the options from the PodSecurityContext will be used.
+                              If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is linux.
+                            properties:
+                              gmsaCredentialSpec:
+                                description: |-
+                                  GMSACredentialSpec is where the GMSA admission webhook
+                                  (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the
+                                  GMSA credential spec named by the GMSACredentialSpecName field.
+                                type: string
+                              gmsaCredentialSpecName:
+                                description: GMSACredentialSpecName is the name of
+                                  the GMSA credential spec to use.
+                                type: string
+                              hostProcess:
+                                description: |-
+                                  HostProcess determines if a container should be run as a 'Host Process' container.
+                                  All of a Pod's containers must have the same effective HostProcess value
+                                  (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+                                  In addition, if HostProcess is true then HostNetwork must also be set to true.
+                                type: boolean
+                              runAsUserName:
+                                description: |-
+                                  The UserName in Windows to run the entrypoint of the container process.
+                                  Defaults to the user specified in image metadata if unspecified.
+                                  May also be set in PodSecurityContext. If set in both SecurityContext and
+                                  PodSecurityContext, the value specified in SecurityContext takes precedence.
+                                type: string
+                            type: object
+                        type: object
                       defaultInitContainerResources:
                         description: DefaultInitContainerResources are the resource
                           requirements for the default init container(s) created by
diff --git a/config/crd/bases/solr.apache.org_solrprometheusexporters.yaml b/config/crd/bases/solr.apache.org_solrprometheusexporters.yaml
index 808140d..cb658a1 100644
--- a/config/crd/bases/solr.apache.org_solrprometheusexporters.yaml
+++ b/config/crd/bases/solr.apache.org_solrprometheusexporters.yaml
@@ -907,6 +907,174 @@ spec:
                           type: string
                         description: Annotations to be added for pods.
                         type: object
+                      containerSecurityContext:
+                        description: ContainerSecurityContext the container-level
+                          security context used by the pod's primary container
+                        properties:
+                          allowPrivilegeEscalation:
+                            description: |-
+                              AllowPrivilegeEscalation controls whether a process can gain more
+                              privileges than its parent process. This bool directly controls if
+                              the no_new_privs flag will be set on the container process.
+                              AllowPrivilegeEscalation is true always when the container is:
+                              1) run as Privileged
+                              2) has CAP_SYS_ADMIN
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          capabilities:
+                            description: |-
+                              The capabilities to add/drop when running containers.
+                              Defaults to the default set of capabilities granted by the container runtime.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              add:
+                                description: Added capabilities
+                                items:
+                                  description: Capability represent POSIX capabilities
+                                    type
+                                  type: string
+                                type: array
+                              drop:
+                                description: Removed capabilities
+                                items:
+                                  description: Capability represent POSIX capabilities
+                                    type
+                                  type: string
+                                type: array
+                            type: object
+                          privileged:
+                            description: |-
+                              Run container in privileged mode.
+                              Processes in privileged containers are essentially equivalent to root on the host.
+                              Defaults to false.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          procMount:
+                            description: |-
+                              procMount denotes the type of proc mount to use for the containers.
+                              The default is DefaultProcMount which uses the container runtime defaults for
+                              readonly paths and masked paths.
+                              This requires the ProcMountType feature flag to be enabled.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: string
+                          readOnlyRootFilesystem:
+                            description: |-
+                              Whether this container has a read-only root filesystem.
+                              Default is false.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          runAsGroup:
+                            description: |-
+                              The GID to run the entrypoint of the container process.
+                              Uses runtime default if unset.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            format: int64
+                            type: integer
+                          runAsNonRoot:
+                            description: |-
+                              Indicates that the container must run as a non-root user.
+                              If true, the Kubelet will validate the image at runtime to ensure that it
+                              does not run as UID 0 (root) and fail to start the container if it does.
+                              If unset or false, no such validation will be performed.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                            type: boolean
+                          runAsUser:
+                            description: |-
+                              The UID to run the entrypoint of the container process.
+                              Defaults to user specified in image metadata if unspecified.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            format: int64
+                            type: integer
+                          seLinuxOptions:
+                            description: |-
+                              The SELinux context to be applied to the container.
+                              If unspecified, the container runtime will allocate a random SELinux context for each
+                              container.  May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              level:
+                                description: Level is SELinux level label that applies
+                                  to the container.
+                                type: string
+                              role:
+                                description: Role is a SELinux role label that applies
+                                  to the container.
+                                type: string
+                              type:
+                                description: Type is a SELinux type label that applies
+                                  to the container.
+                                type: string
+                              user:
+                                description: User is a SELinux user label that applies
+                                  to the container.
+                                type: string
+                            type: object
+                          seccompProfile:
+                            description: |-
+                              The seccomp options to use by this container. If seccomp options are
+                              provided at both the pod & container level, the container options
+                              override the pod options.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              localhostProfile:
+                                description: |-
+                                  localhostProfile indicates a profile defined in a file on the node should be used.
+                                  The profile must be preconfigured on the node to work.
+                                  Must be a descending path, relative to the kubelet's configured seccomp profile location.
+                                  Must be set if type is "Localhost". Must NOT be set for any other type.
+                                type: string
+                              type:
+                                description: |-
+                                  type indicates which kind of seccomp profile will be applied.
+                                  Valid options are:
+
+
+                                  Localhost - a profile defined in a file on the node should be used.
+                                  RuntimeDefault - the container runtime default profile should be used.
+                                  Unconfined - no profile should be applied.
+                                type: string
+                            required:
+                            - type
+                            type: object
+                          windowsOptions:
+                            description: |-
+                              The Windows specific settings applied to all containers.
+                              If unspecified, the options from the PodSecurityContext will be used.
+                              If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is linux.
+                            properties:
+                              gmsaCredentialSpec:
+                                description: |-
+                                  GMSACredentialSpec is where the GMSA admission webhook
+                                  (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the
+                                  GMSA credential spec named by the GMSACredentialSpecName field.
+                                type: string
+                              gmsaCredentialSpecName:
+                                description: GMSACredentialSpecName is the name of
+                                  the GMSA credential spec to use.
+                                type: string
+                              hostProcess:
+                                description: |-
+                                  HostProcess determines if a container should be run as a 'Host Process' container.
+                                  All of a Pod's containers must have the same effective HostProcess value
+                                  (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+                                  In addition, if HostProcess is true then HostNetwork must also be set to true.
+                                type: boolean
+                              runAsUserName:
+                                description: |-
+                                  The UserName in Windows to run the entrypoint of the container process.
+                                  Defaults to the user specified in image metadata if unspecified.
+                                  May also be set in PodSecurityContext. If set in both SecurityContext and
+                                  PodSecurityContext, the value specified in SecurityContext takes precedence.
+                                type: string
+                            type: object
+                        type: object
                       defaultInitContainerResources:
                         description: DefaultInitContainerResources are the resource
                           requirements for the default init container(s) created by
diff --git a/controllers/solrcloud_controller_test.go b/controllers/solrcloud_controller_test.go
index c1dbc11..1bd01ff 100644
--- a/controllers/solrcloud_controller_test.go
+++ b/controllers/solrcloud_controller_test.go
@@ -30,6 +30,7 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/intstr"
+	pointer "k8s.io/utils/pointer"
 	"strconv"
 	"strings"
 )
@@ -141,6 +142,7 @@ var _ = FDescribe("SolrCloud controller - General", func() {
 			Expect(statefulSet.Spec.Template.Spec.Affinity).To(Equal(testAffinity), "Affinity is not the same as the one provided in podOptions")
 			Expect(statefulSet.Spec.Template.Spec.Containers[0].Resources.Limits).To(Equal(testResources.Limits), "Resources.Limits is not the same as the one provided in podOptions")
 			Expect(statefulSet.Spec.Template.Spec.Containers[0].Resources.Requests).To(Equal(testResources.Requests), "Resources.Requests is not the same as the one provided in podOptions")
+			Expect(statefulSet.Spec.Template.Spec.Containers[0].SecurityContext).To(BeNil(), "SecurityContext is not the expected default value, 'nil'")
 			extraVolumes[0].DefaultContainerMount.Name = extraVolumes[0].Name
 			Expect(statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts).To(HaveLen(len(extraVolumes)+1), "Container has wrong number of volumeMounts")
 			Expect(statefulSet.Spec.Template.Spec.Containers[0].VolumeMounts[1]).To(Equal(*extraVolumes[0].DefaultContainerMount), "Additional Volume from podOptions not mounted into container properly.")
@@ -216,7 +218,15 @@ var _ = FDescribe("SolrCloud controller - General", func() {
 						TopologySpreadConstraints:     testTopologySpreadConstraints,
 						DefaultInitContainerResources: testResources2,
 						InitContainers:                extraContainers1,
-						ShareProcessNamespace:         testShareProcessNamespace,
+						ContainerSecurityContext: &corev1.SecurityContext{
+							RunAsNonRoot:           newBoolPtr(true),
+							ReadOnlyRootFilesystem: newBoolPtr(true),
+							RunAsUser:              pointer.Int64(123),
+							Capabilities: &corev1.Capabilities{
+								Add: []corev1.Capability{"someCapability"},
+							},
+						},
+						ShareProcessNamespace: testShareProcessNamespace,
 					},
 					StatefulSetOptions: &solrv1beta1.StatefulSetOptions{
 						Annotations:         testSSAnnotations,
@@ -278,6 +288,12 @@ var _ = FDescribe("SolrCloud controller - General", func() {
 			Expect(statefulSet.Spec.Template.Spec.Containers[0].StartupProbe, testProbeStartup, "Incorrect Startup Probe")
 			Expect(statefulSet.Spec.Template.Spec.Containers[0].Lifecycle).To(Equal(testLifecycle), "Incorrect container lifecycle")
 			Expect(statefulSet.Spec.Template.Spec.Containers[0].Resources).To(Equal(testResources), "Incorrect container resources")
+			Expect(statefulSet.Spec.Template.Spec.Containers[0].SecurityContext).To(Not(BeNil()))
+			Expect(statefulSet.Spec.Template.Spec.Containers[0].SecurityContext.RunAsNonRoot).To(PointTo(BeTrue()))
+			Expect(statefulSet.Spec.Template.Spec.Containers[0].SecurityContext.ReadOnlyRootFilesystem).To(PointTo(BeTrue()))
+			Expect(statefulSet.Spec.Template.Spec.Containers[0].SecurityContext.RunAsUser).To(PointTo(Equal(int64(123))))
+			Expect(statefulSet.Spec.Template.Spec.Containers[0].SecurityContext.Capabilities.Add).To(HaveLen(1))
+			Expect(statefulSet.Spec.Template.Spec.Containers[0].SecurityContext.Capabilities.Add[0]).To(Equal(corev1.Capability("someCapability")))
 			Expect(statefulSet.Spec.Template.Spec.InitContainers[0].Resources).To(Equal(testResources2), "Incorrect initContainer[0] resources")
 			Expect(statefulSet.Spec.Template.Spec.InitContainers[1].Resources).To(Equal(testResources2), "Incorrect initContainer[1] resources")
 			Expect(statefulSet.Spec.Template.Spec.InitContainers[2].Resources).ToNot(Equal(testResources2), "Incorrect initContainer[2] resources, should not use the default override")
diff --git a/controllers/util/common.go b/controllers/util/common.go
index 3eca00b..64bf654 100644
--- a/controllers/util/common.go
+++ b/controllers/util/common.go
@@ -618,6 +618,12 @@ func CopyPodContainers(fromPtr, toPtr *[]corev1.Container, basePath string, logg
 				logger.Info("Update required because field changed", "field", containerBasePath+"TerminationMessagePolicy", "from", to[i].TerminationMessagePolicy, "to", from[i].TerminationMessagePolicy)
 				to[i].TerminationMessagePolicy = from[i].TerminationMessagePolicy
 			}
+
+			if !DeepEqualWithNils(to[i].SecurityContext, from[i].SecurityContext) {
+				requireUpdate = true
+				logger.Info("Update required because field changed", "field", containerBasePath+"SecurityContext", "from", to[i].SecurityContext, "to", from[i].SecurityContext)
+				to[i].SecurityContext = from[i].SecurityContext
+			}
 		}
 	}
 	return requireUpdate
diff --git a/controllers/util/prometheus_exporter_util.go b/controllers/util/prometheus_exporter_util.go
index 1792e88..f8ef4a7 100644
--- a/controllers/util/prometheus_exporter_util.go
+++ b/controllers/util/prometheus_exporter_util.go
@@ -213,6 +213,11 @@ func GenerateSolrPrometheusExporterDeployment(solrPrometheusExporter *solr.SolrP
 		},
 	}
 
+	var containerSecurityContext *corev1.SecurityContext
+	if customPodOptions != nil {
+		containerSecurityContext = customPodOptions.ContainerSecurityContext
+	}
+
 	containers := []corev1.Container{
 		{
 			Name:            SolrPrometheusExporterContainer,
@@ -245,6 +250,7 @@ func GenerateSolrPrometheusExporterDeployment(solrPrometheusExporter *solr.SolrP
 				SuccessThreshold: 1,
 				FailureThreshold: 3,
 			},
+			SecurityContext: containerSecurityContext,
 		},
 	}
 
diff --git a/controllers/util/solr_util.go b/controllers/util/solr_util.go
index 64b9ba1..db4c408 100644
--- a/controllers/util/solr_util.go
+++ b/controllers/util/solr_util.go
@@ -455,6 +455,11 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus *solr.SolrCl
 		initContainers = append(initContainers, customPodOptions.InitContainers...)
 	}
 
+	var containerSecurityContext *corev1.SecurityContext
+	if customPodOptions != nil {
+		containerSecurityContext = customPodOptions.ContainerSecurityContext
+	}
+
 	containers := []corev1.Container{
 		{
 			Name:            SolrNodeContainer,
@@ -498,6 +503,7 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus *solr.SolrCl
 				PostStart: postStart,
 				PreStop:   preStop,
 			},
+			SecurityContext: containerSecurityContext,
 		},
 	}
 
diff --git a/helm/solr-operator/Chart.yaml b/helm/solr-operator/Chart.yaml
index 060ae16..2509c43 100644
--- a/helm/solr-operator/Chart.yaml
+++ b/helm/solr-operator/Chart.yaml
@@ -127,6 +127,13 @@ annotations:
           url: https://github.com/apache/solr-operator/issues/718
         - name: Github PR
           url: https://github.com/apache/solr-operator/pull/734
+    - kind: added
+      description: "SolrCloud now accepts container-level securityContext settings for Solr container."
+      links:
+        - name: Github Issue
+          url: https://github.com/apache/solr-operator/issues/489
+        - name: Github PR
+          url: https://github.com/apache/solr-operator/pull/743
   artifacthub.io/images: |
     - name: solr-operator
       image: apache/solr-operator:v0.9.0-prerelease
diff --git a/helm/solr-operator/crds/crds.yaml b/helm/solr-operator/crds/crds.yaml
index 0f807e3..c8b3cd0 100644
--- a/helm/solr-operator/crds/crds.yaml
+++ b/helm/solr-operator/crds/crds.yaml
@@ -3077,6 +3077,174 @@ spec:
                           type: string
                         description: Annotations to be added for pods.
                         type: object
+                      containerSecurityContext:
+                        description: ContainerSecurityContext the container-level
+                          security context used by the pod's primary container
+                        properties:
+                          allowPrivilegeEscalation:
+                            description: |-
+                              AllowPrivilegeEscalation controls whether a process can gain more
+                              privileges than its parent process. This bool directly controls if
+                              the no_new_privs flag will be set on the container process.
+                              AllowPrivilegeEscalation is true always when the container is:
+                              1) run as Privileged
+                              2) has CAP_SYS_ADMIN
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          capabilities:
+                            description: |-
+                              The capabilities to add/drop when running containers.
+                              Defaults to the default set of capabilities granted by the container runtime.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              add:
+                                description: Added capabilities
+                                items:
+                                  description: Capability represent POSIX capabilities
+                                    type
+                                  type: string
+                                type: array
+                              drop:
+                                description: Removed capabilities
+                                items:
+                                  description: Capability represent POSIX capabilities
+                                    type
+                                  type: string
+                                type: array
+                            type: object
+                          privileged:
+                            description: |-
+                              Run container in privileged mode.
+                              Processes in privileged containers are essentially equivalent to root on the host.
+                              Defaults to false.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          procMount:
+                            description: |-
+                              procMount denotes the type of proc mount to use for the containers.
+                              The default is DefaultProcMount which uses the container runtime defaults for
+                              readonly paths and masked paths.
+                              This requires the ProcMountType feature flag to be enabled.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: string
+                          readOnlyRootFilesystem:
+                            description: |-
+                              Whether this container has a read-only root filesystem.
+                              Default is false.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          runAsGroup:
+                            description: |-
+                              The GID to run the entrypoint of the container process.
+                              Uses runtime default if unset.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            format: int64
+                            type: integer
+                          runAsNonRoot:
+                            description: |-
+                              Indicates that the container must run as a non-root user.
+                              If true, the Kubelet will validate the image at runtime to ensure that it
+                              does not run as UID 0 (root) and fail to start the container if it does.
+                              If unset or false, no such validation will be performed.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                            type: boolean
+                          runAsUser:
+                            description: |-
+                              The UID to run the entrypoint of the container process.
+                              Defaults to user specified in image metadata if unspecified.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            format: int64
+                            type: integer
+                          seLinuxOptions:
+                            description: |-
+                              The SELinux context to be applied to the container.
+                              If unspecified, the container runtime will allocate a random SELinux context for each
+                              container.  May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              level:
+                                description: Level is SELinux level label that applies
+                                  to the container.
+                                type: string
+                              role:
+                                description: Role is a SELinux role label that applies
+                                  to the container.
+                                type: string
+                              type:
+                                description: Type is a SELinux type label that applies
+                                  to the container.
+                                type: string
+                              user:
+                                description: User is a SELinux user label that applies
+                                  to the container.
+                                type: string
+                            type: object
+                          seccompProfile:
+                            description: |-
+                              The seccomp options to use by this container. If seccomp options are
+                              provided at both the pod & container level, the container options
+                              override the pod options.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              localhostProfile:
+                                description: |-
+                                  localhostProfile indicates a profile defined in a file on the node should be used.
+                                  The profile must be preconfigured on the node to work.
+                                  Must be a descending path, relative to the kubelet's configured seccomp profile location.
+                                  Must be set if type is "Localhost". Must NOT be set for any other type.
+                                type: string
+                              type:
+                                description: |-
+                                  type indicates which kind of seccomp profile will be applied.
+                                  Valid options are:
+
+
+                                  Localhost - a profile defined in a file on the node should be used.
+                                  RuntimeDefault - the container runtime default profile should be used.
+                                  Unconfined - no profile should be applied.
+                                type: string
+                            required:
+                            - type
+                            type: object
+                          windowsOptions:
+                            description: |-
+                              The Windows specific settings applied to all containers.
+                              If unspecified, the options from the PodSecurityContext will be used.
+                              If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is linux.
+                            properties:
+                              gmsaCredentialSpec:
+                                description: |-
+                                  GMSACredentialSpec is where the GMSA admission webhook
+                                  (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the
+                                  GMSA credential spec named by the GMSACredentialSpecName field.
+                                type: string
+                              gmsaCredentialSpecName:
+                                description: GMSACredentialSpecName is the name of
+                                  the GMSA credential spec to use.
+                                type: string
+                              hostProcess:
+                                description: |-
+                                  HostProcess determines if a container should be run as a 'Host Process' container.
+                                  All of a Pod's containers must have the same effective HostProcess value
+                                  (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+                                  In addition, if HostProcess is true then HostNetwork must also be set to true.
+                                type: boolean
+                              runAsUserName:
+                                description: |-
+                                  The UserName in Windows to run the entrypoint of the container process.
+                                  Defaults to the user specified in image metadata if unspecified.
+                                  May also be set in PodSecurityContext. If set in both SecurityContext and
+                                  PodSecurityContext, the value specified in SecurityContext takes precedence.
+                                type: string
+                            type: object
+                        type: object
                       defaultInitContainerResources:
                         description: DefaultInitContainerResources are the resource
                           requirements for the default init container(s) created by
@@ -17194,6 +17362,174 @@ spec:
                           type: string
                         description: Annotations to be added for pods.
                         type: object
+                      containerSecurityContext:
+                        description: ContainerSecurityContext the container-level
+                          security context used by the pod's primary container
+                        properties:
+                          allowPrivilegeEscalation:
+                            description: |-
+                              AllowPrivilegeEscalation controls whether a process can gain more
+                              privileges than its parent process. This bool directly controls if
+                              the no_new_privs flag will be set on the container process.
+                              AllowPrivilegeEscalation is true always when the container is:
+                              1) run as Privileged
+                              2) has CAP_SYS_ADMIN
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          capabilities:
+                            description: |-
+                              The capabilities to add/drop when running containers.
+                              Defaults to the default set of capabilities granted by the container runtime.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              add:
+                                description: Added capabilities
+                                items:
+                                  description: Capability represent POSIX capabilities
+                                    type
+                                  type: string
+                                type: array
+                              drop:
+                                description: Removed capabilities
+                                items:
+                                  description: Capability represent POSIX capabilities
+                                    type
+                                  type: string
+                                type: array
+                            type: object
+                          privileged:
+                            description: |-
+                              Run container in privileged mode.
+                              Processes in privileged containers are essentially equivalent to root on the host.
+                              Defaults to false.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          procMount:
+                            description: |-
+                              procMount denotes the type of proc mount to use for the containers.
+                              The default is DefaultProcMount which uses the container runtime defaults for
+                              readonly paths and masked paths.
+                              This requires the ProcMountType feature flag to be enabled.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: string
+                          readOnlyRootFilesystem:
+                            description: |-
+                              Whether this container has a read-only root filesystem.
+                              Default is false.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            type: boolean
+                          runAsGroup:
+                            description: |-
+                              The GID to run the entrypoint of the container process.
+                              Uses runtime default if unset.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            format: int64
+                            type: integer
+                          runAsNonRoot:
+                            description: |-
+                              Indicates that the container must run as a non-root user.
+                              If true, the Kubelet will validate the image at runtime to ensure that it
+                              does not run as UID 0 (root) and fail to start the container if it does.
+                              If unset or false, no such validation will be performed.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                            type: boolean
+                          runAsUser:
+                            description: |-
+                              The UID to run the entrypoint of the container process.
+                              Defaults to user specified in image metadata if unspecified.
+                              May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            format: int64
+                            type: integer
+                          seLinuxOptions:
+                            description: |-
+                              The SELinux context to be applied to the container.
+                              If unspecified, the container runtime will allocate a random SELinux context for each
+                              container.  May also be set in PodSecurityContext.  If set in both SecurityContext and
+                              PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              level:
+                                description: Level is SELinux level label that applies
+                                  to the container.
+                                type: string
+                              role:
+                                description: Role is a SELinux role label that applies
+                                  to the container.
+                                type: string
+                              type:
+                                description: Type is a SELinux type label that applies
+                                  to the container.
+                                type: string
+                              user:
+                                description: User is a SELinux user label that applies
+                                  to the container.
+                                type: string
+                            type: object
+                          seccompProfile:
+                            description: |-
+                              The seccomp options to use by this container. If seccomp options are
+                              provided at both the pod & container level, the container options
+                              override the pod options.
+                              Note that this field cannot be set when spec.os.name is windows.
+                            properties:
+                              localhostProfile:
+                                description: |-
+                                  localhostProfile indicates a profile defined in a file on the node should be used.
+                                  The profile must be preconfigured on the node to work.
+                                  Must be a descending path, relative to the kubelet's configured seccomp profile location.
+                                  Must be set if type is "Localhost". Must NOT be set for any other type.
+                                type: string
+                              type:
+                                description: |-
+                                  type indicates which kind of seccomp profile will be applied.
+                                  Valid options are:
+
+
+                                  Localhost - a profile defined in a file on the node should be used.
+                                  RuntimeDefault - the container runtime default profile should be used.
+                                  Unconfined - no profile should be applied.
+                                type: string
+                            required:
+                            - type
+                            type: object
+                          windowsOptions:
+                            description: |-
+                              The Windows specific settings applied to all containers.
+                              If unspecified, the options from the PodSecurityContext will be used.
+                              If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.
+                              Note that this field cannot be set when spec.os.name is linux.
+                            properties:
+                              gmsaCredentialSpec:
+                                description: |-
+                                  GMSACredentialSpec is where the GMSA admission webhook
+                                  (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the
+                                  GMSA credential spec named by the GMSACredentialSpecName field.
+                                type: string
+                              gmsaCredentialSpecName:
+                                description: GMSACredentialSpecName is the name of
+                                  the GMSA credential spec to use.
+                                type: string
+                              hostProcess:
+                                description: |-
+                                  HostProcess determines if a container should be run as a 'Host Process' container.
+                                  All of a Pod's containers must have the same effective HostProcess value
+                                  (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers).
+                                  In addition, if HostProcess is true then HostNetwork must also be set to true.
+                                type: boolean
+                              runAsUserName:
+                                description: |-
+                                  The UserName in Windows to run the entrypoint of the container process.
+                                  Defaults to the user specified in image metadata if unspecified.
+                                  May also be set in PodSecurityContext. If set in both SecurityContext and
+                                  PodSecurityContext, the value specified in SecurityContext takes precedence.
+                                type: string
+                            type: object
+                        type: object
                       defaultInitContainerResources:
                         description: DefaultInitContainerResources are the resource
                           requirements for the default init container(s) created by
diff --git a/helm/solr/README.md b/helm/solr/README.md
index bbd0075..7541843 100644
--- a/helm/solr/README.md
+++ b/helm/solr/README.md
@@ -291,6 +291,7 @@ When using the helm chart, omit `customSolrKubeOptions.`
 | podOptions.initContainers | []object |  | An optional list of additional initContainers to run before the Solr container starts |
 | podOptions.envVars | []object |  | List of additional environment variables for the Solr container |
 | podOptions.podSecurityContext | object |  | Security context for the Solr pod |
+| podOptions.containerSecurityContext | object |  | Security context for the Solr container in each pod |
 | podOptions.terminationGracePeriodSeconds | int |  | Optional amount of time to wait for Solr to stop on its own, before manually killing it |
 | podOptions.livenessProbe | object |  | Custom liveness probe for the Solr container |
 | podOptions.readinessProbe | object |  | Custom readiness probe for the Solr container |
diff --git a/helm/solr/templates/_custom_option_helpers.tpl b/helm/solr/templates/_custom_option_helpers.tpl
index f0b4aba..34f7298 100644
--- a/helm/solr/templates/_custom_option_helpers.tpl
+++ b/helm/solr/templates/_custom_option_helpers.tpl
@@ -62,6 +62,10 @@ nodeSelector:
 podSecurityContext:
   {{- toYaml .Values.podOptions.podSecurityContext | nindent 2 }}
 {{ end }}
+{{- if .Values.podOptions.containerSecurityContext -}}
+containerSecurityContext:
+  {{- toYaml .Values.podOptions.containerSecurityContext | nindent 2 }}
+{{ end }}
 {{- if (or .Values.podOptions.imagePullSecrets .Values.global.imagePullSecrets) -}}
 imagePullSecrets:
   {{- toYaml (append .Values.podOptions.imagePullSecrets .Values.global.imagePullSecrets) | nindent 2 }}
diff --git a/helm/solr/values.yaml b/helm/solr/values.yaml
index 15171f1..e6addba 100644
--- a/helm/solr/values.yaml
+++ b/helm/solr/values.yaml
@@ -295,6 +295,7 @@ podOptions:
   priorityClassName: ""
   envVars: []
   podSecurityContext: {}
+  containerSecurityContext: {}
   terminationGracePeriodSeconds: null
 
   # Set Solr service account individually instead of the global "serviceAccount.name"