pulp / pulp-operator

Kubernetes Operator for Pulp 3. Under active development.
https://docs.pulpproject.org/pulp_operator/
GNU General Public License v2.0
67 stars 50 forks source link

Operands should comply with the restricted pod security standards #1315

Closed magnhas closed 3 months ago

magnhas commented 3 months ago

Summary

Jobs and the web deployment should comply with the restricted pos security standards.

[root@node1 ~]# kubectl describe job pulp-reset-admin-password-qph9d
Name:             pulp-reset-admin-password-qph9d
Namespace:        pulp
...
Events:
  Type     Reason        Age                     From            Message
  ----     ------        ----                    ----            -------
  Warning  FailedCreate  5m43s (x34 over 3h23m)  job-controller  (combined from similar events): Error creating: pods "pulp-reset-admin-password-qph9d-7jfr2" is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "reset-admin-password" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "reset-admin-password" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "reset-admin-password" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "reset-admin-password" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
[root@node1 ~]# kubectl rollout restart deployment/pulp-web
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "web" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "web" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "web" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "web" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
deployment.apps/pulp-web restarted

References

git-hyagi commented 3 months ago

Hi @magnhas

Thank you for opening this issue and also contributing with the PR! :smile: I'm testing your commit in a lab environment and will update you as soon as I finish it.

Just as a note, to reproduce this error I had to:

kubectl label ns pulp pod-security.kubernetes.io/enforce=restricted
magnhas commented 3 months ago

Yes! There might also be more to this. In my setup, I used an external database and external cache. I also haven't looked closely at the backup and restore custom resources.

git-hyagi commented 3 months ago

Good catch! I was primarily focused on db and didn't consider the other components. From my tests, I'm seeing that postgres installations using the operator would break after an upgrade with the new SecurityContext:

  chmod: changing permissions of '/var/lib/postgresql/data/pgdata': Operation not permitted
  chmod: changing permissions of '/var/run/postgresql': Operation not permitted

and, for now, I don't know which would be the best approach (maybe consider this as a breaking change). Anyway, I'll open a new issue specific for database pods so we can move with this PR, and we can think about/discuss the approach for database separately.

magnhas commented 3 months ago

Yes! The key is to use runAsUser: 999. Here is a database and cache manifest that did the trick for me,

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: pulp
  labels:
    app.kubernetes.io/component: postgres
spec:
  selector:
    matchLabels:
      app.kubernetes.io/component: postgres
  replicas: 1
  template:
    metadata:
      labels:
        app.kubernetes.io/component: postgres
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: postgres
          image: postgres:13
          envFrom:
            - secretRef:
                name: postgres
          env:
            - name: POSTGRES_INITDB_ARGS
              value: --auth-host=scram-sha-256
            - name: POSTGRES_HOST_AUTH_METHOD
              value: scram-sha-256
          ports:
            - containerPort: 5432
              protocol: TCP
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: data
          securityContext:
            capabilities:
              drop:
                - ALL
            allowPrivilegeEscalation: false
            runAsUser: 999
            runAsGroup: 999
          livenessProbe:
            exec:
              command:
                - /bin/sh
                - -c
                - "pg_isready -U pulp"
            failureThreshold: 5
            initialDelaySeconds: 5
            periodSeconds: 5
            successThreshold: 1
            timeoutSeconds: 5
          readinessProbe:
            exec:
              command:
                - /bin/sh
                - -c
                - "pg_isready -U pulp"
            failureThreshold: 5
            initialDelaySeconds: 5
            periodSeconds: 5
            successThreshold: 1
            timeoutSeconds: 5
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: postgres
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/component: redis
  name: redis
  namespace: pulp
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/component: redis
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app.kubernetes.io/component: redis
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: redis
          image: redis:7
          livenessProbe:
            exec:
              command:
                - /bin/sh
                - -i
                - -c
                - redis-cli -h 127.0.0.1 -p 6379
            failureThreshold: 5
            initialDelaySeconds: 5
            periodSeconds: 5
            successThreshold: 1
            timeoutSeconds: 5
          ports:
            - containerPort: 6379
              protocol: TCP
          readinessProbe:
            exec:
              command:
                - /bin/sh
                - -i
                - -c
                - redis-cli -h 127.0.0.1 -p 6379
            failureThreshold: 5
            initialDelaySeconds: 5
            periodSeconds: 5
            successThreshold: 1
            timeoutSeconds: 5
          args:
            - redis-server
            - /etc/redis/redis.conf
          volumeMounts:
            - name: data
              mountPath: /data
            - name: conf
              mountPath: /etc/redis
              readOnly: true
          securityContext:
            capabilities:
              drop:
                - ALL
            allowPrivilegeEscalation: false
            runAsUser: 999
            runAsGroup: 999
      volumes:
        - name: data
          emptyDir: {}
        - name: conf
          secret:
            secretName: redis-conf
git-hyagi commented 3 months ago

Nice! Let me try it!