Add configurable securityContext and dnsConfig for the operator Deployment - #2843
Add configurable securityContext and dnsConfig for the operator Deployment#2843dundysm wants to merge 4 commits into
Conversation
…yment The gpu-operator Deployment currently leaves pod and container securityContext empty. Default to a restricted profile matching the image USER 1000, mount an emptyDir at /tmp for a read-only root filesystem, and allow dnsConfig via values. Fixes NVIDIA#2533 Signed-off-by: Dundy Pasupuleti <pasupuletidundy@gmail.com>
8509025 to
e29dd96
Compare
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: QUIET Plan: Enterprise Run ID: 📒 Files selected for processing (4)
💤 Files with no reviewable changes (4)
Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review. 📝 WalkthroughWalkthroughThe Helm chart adds restricted security defaults for GPU Operator workloads. The operator Deployment and hook Job templates conditionally apply pod-level and container-level security settings. The templates also support optional DNS policy and DNS configuration. Priority: ➖ Normal Merge Risk: 🔵 Low · up to The new DNS configuration may not be consistently configurable through chart values, which could leave deployments unable to apply the intended DNS settings. Resolve the values-to-template contract before merge. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (1)
deployments/gpu-operator/templates/operator.yaml-40-43 (1)
40-43: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winKeep the
dnsConfigkey and template reference in sync.This branch reads
.Values.operator.dnsConfig, butdeployments/gpu-operator/values.yamlcontains only the commented# dnsConfig: {}. Add an activednsConfig: {}entry invalues.yaml, or remove this branch, so the supported chart values match the template.As per path instructions, a template reference must have a matching values.yaml key.
Source: Path instructions
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: QUIET
Plan: Enterprise
Run ID: b7992171-3df3-4684-ba35-243b9ab70b8c
📒 Files selected for processing (2)
deployments/gpu-operator/templates/operator.yamldeployments/gpu-operator/values.yaml
Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review.
restricted-readonly uses MustRunAsRange. A hardcoded UID 1000 fails namespaces whose allocated range does not include 1000. The image USER 1000:1000 still applies on vanilla Kubernetes. Signed-off-by: Dundy Pasupuleti <pasupuletidundy@gmail.com>
Add discoverable dnsPolicy and dnsConfig values keys, and make dnsPolicy configurable so ClusterFirst remains the default. Apply the same restricted pod and container securityContext used by the operator Deployment to the Helm hook Jobs that run the operator image. Operand DaemonSets are unchanged; they still need host privileges. Signed-off-by: Dundy Pasupuleti <pasupuletidundy@gmail.com>
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@rajathagasthya picking this up from #2533, including Restricted defaults for the operator Deployment and the Helm hook Jobs that run the same image. No pinned UID, so OpenShift This is my first PR here, so copy-pr-bot is blocking CI. If the approach looks right, would you mind an |
|
Thanks @dundysm! Will take a look at this PR soon. |
|
/ok-to-test 0046331 |
|
@coderabbitai review |
|
| {{- toYaml . | nindent 12 }} | ||
| {{- end }} | ||
| volumeMounts: | ||
| - name: tmp |
There was a problem hiding this comment.
you're right, dropping it. i'd added it as insurance for readOnlyRootFilesystem: true, but checking properly: the operator Deployment is already annotated with openshift.io/scc: restricted-readonly (values.yaml), and that SCC sets readOnlyRootFilesystem: true, so it has been running with a read-only root filesystem on OpenShift without a writable /tmp.
manage-crds and cleanup-gpuclusters only read manifests from /opt/gpu-operator and apply them through the API server, no temp writes in either cmd or in crdutil.
removed the emptyDir and the mounts from all four templates in faf30f8. readOnlyRootFilesystem: true stays on the container securityContext.
| - name: cleanup-crd | ||
| image: {{ include "gpu-operator.fullimage" . }} | ||
| imagePullPolicy: {{ .Values.operator.imagePullPolicy }} | ||
| {{- with .Values.operator.containerSecurityContext }} |
There was a problem hiding this comment.
Is a containerSecurityContext really needed? Shouldn't the pod Security Context suffice? I am not sure what the advantages are with being able to customise the container-level security context.
There was a problem hiding this comment.
on whether it's needed: allowPrivilegeEscalation, readOnlyRootFilesystem, and capabilities exist only on v1.SecurityContext; they aren't fields on v1.PodSecurityContext, so pod-level can't express them at any version. pss restricted requires the first two per-container, so the pod block alone can't get us admitted into a restricted namespace. pod-level here carries only runAsNonRoot and seccompProfile, which do accept pod-level.
on customisability: that's a fair challenge. i exposed it because helm create convention splits pod vs container securityContext, and because relaxing readOnlyRootFilesystem or adding back a capability is the kind of thing a downstream consumer hits on odd runtimes.
but, i take the point that clusterpolicy.spec.daemonsets only exposes podSecurityContext, so a container-level knob is new surface for this project. happy to hardcode the three restricted values and drop operator.containerSecurityContext from values.yaml if you'd prefer less api surface, the fields still have to live at container level either way.
The emptyDir was added as insurance for readOnlyRootFilesystem, but it is not needed. The operator Deployment is already annotated with openshift.io/scc: restricted-readonly, and that SCC sets readOnlyRootFilesystem: true, so the Deployment has run with a read-only root filesystem on OpenShift without a writable /tmp. manage-crds and cleanup-gpuclusters read manifests from /opt/gpu-operator and apply them through the API server; neither they nor crdutil create temporary files. The container securityContext still sets readOnlyRootFilesystem to true. Signed-off-by: Dundy <dundysm@gmail.com>
9395f3a to
faf30f8
Compare
|
@coderabbitai review the updates |
|
✅ Action performedReview finished.
|
Description
The
gpu-operatorDeployment currently has no pod or containersecurityContext, so it runs with the cluster default (often unrestricted). This PR makessecurityContext,containerSecurityContext,dnsConfig, anddnsPolicyconfigurable through Helm values and sets restricted defaults that still work on vanilla Kubernetes and OpenShift.This also covers the Helm hook Jobs that run the same operator image (
upgrade-crd,cleanup-crd,cleanup-gpucluster). Those were previously empty like the Deployment.Not in this PR: operand DaemonSets (driver, device plugin, toolkit, MIG, and so on). Those are created later by the operator, not by this chart, and they need host privileges. ClusterPolicy already has
spec.daemonsets.podSecurityContextfor that path.Defaults:
runAsNonRoot: true,seccompProfile: RuntimeDefaultallowPrivilegeEscalation: false,readOnlyRootFilesystem: true,capabilities.drop: [ALL]dnsPolicy: ""(cluster default ClusterFirst) anddnsConfig: {}No writable
/tmpis added. The Deployment is already annotated withopenshift.io/scc: restricted-readonly, and that SCC setsreadOnlyRootFilesystem: true, so it has been running read-only on OpenShift without one. Neithermanage-crdsnorcleanup-gpuclusterscreates temporary files.UID/GID/
fsGroupare not pinned. The operator image already usesUSER 1000:1000, so vanilla Kubernetes still runs non-root. OpenShiftrestricted-readonlySCC usesMustRunAsRange; a hardcoded UID fails namespaces whose allocated range does not include that ID. Pin a UID withoperator.securityContext.runAsUserif you need one.Fixes #2533
Checklist
make lint)make validate-generated-assets)make validate-modules)Testing
Helm-only change (no Go, CRD, or generated-asset edits). Ran against this branch:
helm lint deployments/gpu-operator/— pass (only pre-existing warning: chart versionv1.0.0-develis not SemVerV2)helm templatewith chart defaults — operator Deployment gets the restricted pod/containersecurityContext;dnsPolicy/dnsConfigare omitted. Hook Jobs checked withoperator.cleanupCRD=truesincecleanupCRDdefaults tofalsehelm templatewithoperator.dnsPolicy=Noneandoperator.dnsConfig.nameservers=[8.8.8.8]— both render on the Deployment and hook Jobshelm templatewithoperator.securityContext=nullandoperator.containerSecurityContext=null— those fields are omittedhelm templatewithoperator.securityContext.runAsUser=1000— explicit UID still overridesdocker/Dockerfileends withUSER 1000:1000/tmpemptyDir in faf30f8, diffed the full rendered output against the previous commit — the only change is the removedvolumeMounts/volumesblocks on the four workloads; document count and everything else are identicalDid not apply this to a live GPU cluster.
make lint/ generated-assets / modules are unchanged because this PR does not touch Go code or generated files.