feat(helm): support restricted pod security for CRD upgrade hook Job - #3129
feat(helm): support restricted pod security for CRD upgrade hook Job#3129KHARSHAVARDHAN-eng wants to merge 2 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
🎉 Welcome to the Kubeflow Spark Operator! 🎉 Thanks for opening your first PR! We're happy to have you as part of our community 🚀 Here's what happens next:
Join the community:
Feel free to ask questions in the comments if you need any help or clarification! |
There was a problem hiding this comment.
Pulled the branch. Renders restricted-compliant, unittest 235/235, README regen looks right. USER 65534:65534 is the correct fix for the Dockerfile.
One problem though. runAsNonRoot: true with no runAsUser fails against any image built before this PR. I pulled the config blobs from ghcr:
kubectl:2.5.2 User=''
kubectl:2.5.0-rc.0 User=''
Both UID 0, and no released tag has a USER line. Kubelet rejects that with container has runAsNonRoot and image will run as root, so the Job never starts and helm upgrade fails.
Hits anyone pinning hook.image.tag, pulling through a mirror, or using their own kubectl image. Chart appVersion is still 2.5.0-rc.0, so the default points at a root image too until a new one ships.
Neither gate catches this. helm unittest only checks rendered YAML, and integration never exercises hook.upgradeCrd.
runAsUser: 65534 in the default securityContext fixes it and still passes restricted.
@danish9039 suggested runAsNonRoot alone above. I think that's backwards: runAsNonRoot alone is what breaks other images, runAsUser is what makes it portable. Unless there's a reason not to pin the UID?
Minor: --set hook.securityContext=null now drops all the hardening that used to be hardcoded. Matches how controller.securityContext works so probably intentional, just flagging it.
Set runAsUser: 65534 in the default hook.securityContext to ensure compatibility with non-root validation on all kubectl images.
|
Thanks for catching this! @sxivansx I've addressed the concern by adding runAsUser: 65534 to the default hook.securityContext, so the hook doesn't rely on the image metadata to satisfy runAsNonRoot. I've also updated the corresponding Helm unit test and chart documentation. @danish9039.. Please take a look and looking a any further feedback!!!!! |
|
Verified. Pinning Old images work too: kubectl is 0755 and the CRDs are world-readable, so 65534 can read and exec both without the image needing its own USER. LGTM from me, though I'm not a maintainer so it still needs a reviewer. |
tariq-hasan
left a comment
There was a problem hiding this comment.
Hi @KHARSHAVARDHAN-eng thanks so much for working on this and @sxivansx for guiding the review! I have added a few comments.
Also @KHARSHAVARDHAN-eng please follow these instructions to sign your commits: https://github.com/kubeflow/spark-operator/pull/3129/checks?check_run_id=99506904919.
| # -- Security context for the Helm hook Job pod. | ||
| podSecurityContext: {} | ||
|
|
||
| # -- Security context for the Helm hook Job container. | ||
| securityContext: | ||
| readOnlyRootFilesystem: true | ||
| privileged: false | ||
| allowPrivilegeEscalation: false | ||
| runAsNonRoot: true | ||
| runAsUser: 65534 | ||
| capabilities: | ||
| drop: | ||
| - ALL | ||
| seccompProfile: | ||
| type: RuntimeDefault | ||
|
|
There was a problem hiding this comment.
I can understand runAsUser was set to help enable backward-compatibility but it would end up doing more harm than good - since we are forcing all new installations to run as this user when that may not be the intention to begin with.
To align with controller and webhook let's drop runAsUser. For platform admins that do need compatibility with older images they are free to add this option as needed - we can add a note above the key for this?
| # -- Security context for the Helm hook Job pod. | |
| podSecurityContext: {} | |
| # -- Security context for the Helm hook Job container. | |
| securityContext: | |
| readOnlyRootFilesystem: true | |
| privileged: false | |
| allowPrivilegeEscalation: false | |
| runAsNonRoot: true | |
| runAsUser: 65534 | |
| capabilities: | |
| drop: | |
| - ALL | |
| seccompProfile: | |
| type: RuntimeDefault | |
| # -- Security context for the Helm hook Job pod. | |
| podSecurityContext: {} | |
| # -- Security context for the Helm hook Job container. | |
| securityContext: | |
| readOnlyRootFilesystem: true | |
| privileged: false | |
| allowPrivilegeEscalation: false | |
| runAsNonRoot: true | |
| capabilities: | |
| drop: | |
| - ALL | |
| seccompProfile: | |
| type: RuntimeDefault | |
The general principle here is regarding portability. We'd want to ship a chart that expresses security properties but without exact implementation details. In this case, imposing a concrete user identity would conflict with platform-level UID allocation such as in vendor-based platforms such as OpenShift. From that point of view it makes perfect sense to add runAsNonRoot: true and retain a default identity in the image but enable platform admins to override with appropriate UIDs or security policies as necessary.
This would then enable a clean abstraction boundary and separation of responsibilities between what the chart, image and platform individually accomplish - chart expresses security properties, image supplies the identity, platform overrides.
|
|
||
| COPY --from=builder /workspace/kubectl /usr/bin/kubectl | ||
|
|
||
| USER 65534:65534 |
There was a problem hiding this comment.
For consistency should we use 185 as UID and GID? Granted 185 exists in the controller image since that's native to the Spark image itself but I am wondering if we can retain the same identity here for consistency here as well.
Lines 58 to 72 in 761686e
| value: | ||
| runAsUser: 1000 | ||
| runAsGroup: 2000 | ||
| fsGroup: 3000 |
There was a problem hiding this comment.
Should we also add a negative test for hook.securityContext: null?
|
/ok-to-test |
|
@KHARSHAVARDHAN-eng Please add an integration test that enables |
|
@KHARSHAVARDHAN-eng Please address the review comments so we can move forward with the PR. |
Description
Fixes #3070.
This PR updates the CRD upgrade hook Job so it can run in Kubernetes namespaces enforcing the
restrictedPod Security Standard.Changes
hook.podSecurityContextandhook.securityContextvalues.runAsNonRoot: trueseccompProfile.type: RuntimeDefaultreadOnlyRootFilesystem: trueallowPrivilegeEscalation: falseprivileged: falsecapabilities.drop: [ALL]Testing
./bin/helm unittest charts/spark-operator-chart --strict --file "tests/**/*_test.yaml"git diff --checksuccessfully.