apache / solr-operator

Official Kubernetes operator for Apache Solr
https://solr.apache.org/operator
Apache License 2.0
242 stars 112 forks source link

Run solr-operator and solr helm chart on openshift get error "would violate PodSecurity "restricted:v1.24"" #671

Open aaronsuns opened 6 months ago

aaronsuns commented 6 months ago

When try to run solr-operator and solr helm chart on openshift get the following error regarding podSecurity, the question is where to change that podSecurity?

2024-01-02T09:23:51Z    INFO    Setting default settings for SolrCloud  {"controller": "solrcloud", "controllerGroup": "solr.apache.org", "controllerKind": "SolrCloud", "SolrCloud": {"name":"solr","namespace":"vizone-dev"}, "namespace": "vizone-dev", "name": "solr", "reconcileID": "30cc6979-4cbf-404b-99c9-d4b955569eba"}
2024-01-02T09:23:51Z    INFO    Creating Zookeeer Cluster   {"controller": "solrcloud", "controllerGroup": "solr.apache.org", "controllerKind": "SolrCloud", "SolrCloud": {"name":"solr","namespace":"vizone-dev"}, "namespace": "vizone-dev", "name": "solr", "reconcileID": "3f8781bc-dd1d-4693-a07d-3432d18b5941", "zookeeperCluster": "solr-solrcloud-zookeeper"}
2024-01-02T09:23:51Z    INFO    Creating Common Service {"controller": "solrcloud", "controllerGroup": "solr.apache.org", "controllerKind": "SolrCloud", "SolrCloud": {"name":"solr","namespace":"vizone-dev"}, "namespace": "vizone-dev", "name": "solr", "reconcileID": "3f8781bc-dd1d-4693-a07d-3432d18b5941", "service": "solr-solrcloud-common"}
2024-01-02T09:23:51Z    INFO    Creating Headless Service   {"controller": "solrcloud", "controllerGroup": "solr.apache.org", "controllerKind": "SolrCloud", "SolrCloud": {"name":"solr","namespace":"vizone-dev"}, "namespace": "vizone-dev", "name": "solr", "reconcileID": "3f8781bc-dd1d-4693-a07d-3432d18b5941", "service": "solr-solrcloud-headless"}
2024-01-02T09:23:51Z    INFO    Creating ConfigMap  {"controller": "solrcloud", "controllerGroup": "solr.apache.org", "controllerKind": "SolrCloud", "SolrCloud": {"name":"solr","namespace":"vizone-dev"}, "namespace": "vizone-dev", "name": "solr", "reconcileID": "3f8781bc-dd1d-4693-a07d-3432d18b5941", "configMap": "solr-solrcloud-configmap"}
2024-01-02T09:23:51Z    INFO    Creating StatefulSet    {"controller": "solrcloud", "controllerGroup": "solr.apache.org", "controllerKind": "SolrCloud", "SolrCloud": {"name":"solr","namespace":"vizone-dev"}, "namespace": "vizone-dev", "name": "solr", "reconcileID": "3f8781bc-dd1d-4693-a07d-3432d18b5941", "statefulSet": "solr-solrcloud"}
2024-01-02T09:23:51Z    INFO    KubeAPIWarningLogger    would violate PodSecurity "restricted:v1.24": allowPrivilegeEscalation != false (containers "cp-solr-xml", "solrcloud-node" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (containers "cp-solr-xml", "solrcloud-node" must set securityContext.capabilities.drop=["ALL"])

Tried to change the security context via solr helm values.yaml like this :

podOptions:
  podSecurityContext:
    runAsNonRoot: true

But could not set allowPrivilegeEscalation and capabilities there, they are on container lever security context.

in CustomSolrKubeOptions, perhaps not only expose podOptions.PodSecurityContext, also expose container SecurityContext somehow, the AllowPrivilegeEscalation is defined on that level.

type CustomSolrKubeOptions struct {
    // SolrPodOptions defines the custom options for solrCloud pods.
    // +optional
    PodOptions *PodOptions `json:"podOptions,omitempty"`

    // Additional options for container security context
    // +optional
    ContainerSecurityContext *corev1.SecurityContext `json:"containerSecurityContext,omitempty"`
}

in corev1:

// SecurityContext holds security configuration that will be applied to a container.
// Some fields are present in both SecurityContext and PodSecurityContext.  When both
// are set, the values in SecurityContext take precedence.
type SecurityContext struct {
...
    AllowPrivilegeEscalation *bool `json:"allowPrivilegeEscalation,omitempty" protobuf:"varint,7,opt,name=allowPrivilegeEscalation"`
aaronsuns commented 5 months ago

It looks like related with this issue: https://github.com/apache/solr-operator/issues/489

aaronsuns commented 5 months ago

Here is the quick hack to add those container securityContext

diff --git a/controllers/util/solr_util.go b/controllers/util/solr_util.go
index 0c7f098..47fde76 100644
--- a/controllers/util/solr_util.go
+++ b/controllers/util/solr_util.go
@@ -446,6 +446,7 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus *solr.SolrCl
                initContainers = append(initContainers, customPodOptions.InitContainers...)
        }

+       AllowPrivilegeEscalationValue := false
        containers := []corev1.Container{
                {
                        Name:            SolrNodeContainer,
@@ -489,6 +490,14 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus *solr.SolrCl
                                PostStart: postStart,
                                PreStop:   preStop,
                        },
+
+                       // Add the SecurityContext with hardcoded options
+                       SecurityContext: &corev1.SecurityContext{
+                               AllowPrivilegeEscalation: &AllowPrivilegeEscalationValue,
+                               Capabilities: &corev1.Capabilities{
+                                       Drop: []corev1.Capability{"ALL"},
+                               },
+                       },
                },
        }

@@ -747,6 +756,8 @@ func generateSolrSetupInitContainers(solrCloud *solr.SolrCloud, solrCloudStatus
                corev1.ResourceCPU:    *DefaultSolrVolumePrepInitContainerCPU,
                corev1.ResourceMemory: *DefaultSolrVolumePrepInitContainerMemory,
        }
+
+       AllowPrivilegeEscalationValue := false
        volumePrepInitContainer := corev1.Container{
                Name:            "cp-solr-xml",
                Image:           solrCloud.Spec.BusyBoxImage.ToImageName(),
@@ -757,6 +768,13 @@ func generateSolrSetupInitContainers(solrCloud *solr.SolrCloud, solrCloudStatus
                        Requests: volumePrepResources,
                        Limits:   volumePrepResources,
                },
+               // Add the SecurityContext with hardcoded options
+               SecurityContext: &corev1.SecurityContext{
+                       AllowPrivilegeEscalation: &AllowPrivilegeEscalationValue,
+                       Capabilities: &corev1.Capabilities{
+                               Drop: []corev1.Capability{"ALL"},
+                       },
+               },
        }

        containers = append(containers, volumePrepInitContainer)

According to PSS, it's needed: https://sdk.operatorframework.io/docs/best-practices/pod-security-standards/

aaronsuns commented 5 months ago

Update: create a service account and SCC could run it on openshift without the above change in solr-operator.

# Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
  name: solr-service-account

---

# SCC
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
  name: solr-scc

priority: 10
allowPrivilegedContainer: false
runAsUser:
  type: MustRunAs
  uid: 8983
seLinuxContext:
  type: MustRunAs
fsGroup:
  type: MustRunAs
  ranges:
  - min: 8983
    max: 8983

---

# RoleBinding
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: solr-scc-binding

subjects:
- kind: ServiceAccount
  name: solr-service-account

roleRef:
  kind: Role
  name: solr-scc-role
  apiGroup: rbac.authorization.k8s.io

# Role
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: solr-scc-role

rules:
- apiGroups: ["security.openshift.io"]
  resources: ["securitycontextconstraints"]
  verbs: ["use"]
HoustonPutman commented 3 months ago

If these changes are ok to run in other environments, we could utilize that patch. Make a PR and we can go from there.

I'm glad you found a workaround without modifying the operator though.

Most of the maintainers don't run openshift, so it's hard for us to fix this ourselves. We need to rely on contributions from people running openshift.

aaronsuns commented 3 months ago

Expose container securityContext as configuration in chart values file can be the solution, so user could have full control about what they want to run, it's up to user to follow "Pod Security Standards" or not.

janhoy commented 2 months ago

My client uses Kyverno to warn or enforce various best practices. They recently added rules to warn about deployments that will not run in K8S PSA "restricted" mode: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted. I managed to apply these for solr containers and custom init containers, but not for the operator-managed init containers.

Since Solr runs well with these restrictions, I support making them standard.

On the POD level:

podSecurityContext:
  seccompProfile:
    type: RuntimeDefault

On the container level:

securityContext: 
  allowPrivilegeEscalation: false  
  capabilities:
    drop:
    - ALL

While OpenShift will require even more changes, the PSA "restricted" mode is a generic k8s thing that I support aiming for as default.