[Feature] Add NetworkIsolation support to RayClusters#4638
Conversation
|
Should we also add |
It might add a little too much complexity in terms of configuration. A user can define a Would it be an idea for a follow-up PR maybe pending some discussion? Given how ephemeral submitter Pods are, I feel the attack surface is relatively small as is. |
Of course! We can discuss this in follow-ups |
| // NamespaceSelector is intentionally empty (matches all namespaces) so that | ||
| // the operator pod is allowed regardless of which namespace it runs in. |
There was a problem hiding this comment.
Would it be better to limit it to the namespace where the kuberay-operator is in? Based on this rule, any pod with the label app.kubernetes.io/component: kuberay can connect to head pod
There was a problem hiding this comment.
That was the way we had it in our mid-stream, I'd just assumed we'd want a little more flexibility here. If a user deployed it in a custom namespace, they'd need to manually adjust the auto-generated network policies in this instance! I can certainly move it back to being namespace specific but it's security theatre at a certain point because if a bad actor has permissions to add that label, they'd also have no issue moving resources to a hard-coded namespace if need be. Does that make sense?
There was a problem hiding this comment.
I don't think adding this label requires high privilege?
What I was thinking is that when creating a RayCluster, user can specify labels for worker and head pod. If they set app.kubernetes.io/component: kuberay for RayClusterA, it means that pods in RayClusterA are able to access other RayClusters' head Pods on the dashboard/client ports. This may allow job submission to other RayCluster.
This is one of the case that we wanted to prevent
There was a problem hiding this comment.
Sorry I mean permissions in the context of applying the RayCluster CR at all but fair point! I'll move it back to our more conservative mid-stream approach with the operator namespace validated too! Thanks!
There was a problem hiding this comment.
I've updated it just now. Using NamespaceSelector and pulling the namespace from the service account on the pod so that the user doesn't have to deploy the operator with the POD_NAMESPACE env if they don't want to. WDYT?
machichima
left a comment
There was a problem hiding this comment.
I think there's some redundant / missing sample YAMLs
ray-cluster.network-isolation-monitoring.yaml,ray-cluster.network-isolation-complex-rules.yaml, andray-cluster.network-isolation-custom-rules.yaml- Those 3 are similar, all using denyAll + ingressRules, I think we can just keep one
- egress related YAML is not included
Maybe can just include following YAMLs:
- denyAll with ingress and egress set
- denyAllIngress with ingressrule set
- denyAllEgress with egressrule set
- custom port
WDYT?
Sounds good! I've updated the samples in line with this in the relevant commit. |
|
Hi @chipspeak, A follow-up on this comment: https://github.com/ray-project/kuberay/pull/4638/changes#r3009809497 After discussing with the team offline, we decided it’s better to remove this rule for now to keep the default behavior strict. Instead of handling this on our side, we will leave it up to the users who create the RayCluster to explicitly add the necessary IngressRules. We should also document this behavior in IngressRules docstring and the official docs. kuberay/ray-operator/apis/ray/v1/raycluster_types.go Lines 157 to 159 in 02fe0ff For example, we can mention that users can set the PodSelector to match pods with a specific label (e.g., allow-submit: true), and then apply this label to the SubmitterPodTemplate when creating a RayJob. Our reasoning is that it's much safer to shift this responsibility to the user by default. If there is significant user demand in the future, we can then revisit this. However, if we release a non-strict version now, tightening the security later will be much harder as it could break existing user applications. cc @rueian |
Cool that makes sense! Just for clarity, I assume this refers specifically to the permissive podselector rule that allowed the job submitter pod (and other pods within the same namespace) to access a pre-existing RayCluster? Are we still ok with how it works for RayJob-owned RayClusters? Where the controller detects that a RayCluster has a RayJob ownerReference and then injects an ingress rule on the head NetworkPolicy allowing the submitter pod to reach the dashboard port. |
bd3876b to
6aa8ab1
Compare
Yes! My comment is referring to head pod ingress that allows pods within the same namespace. For RayJob-owned RayClusters, the current implementation in |
Future-Outlier
left a comment
There was a problem hiding this comment.
is this used in the production env?
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
…icy controller setup Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Future-Outlier <eric901201@gmail.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
This reverts commit 26c4053.
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
…lat ingressRules/egressRules on NetworkIsolationConfig with per-role head/worker sub-structs.Since the API has not shipped yet, this avoids locking in a shared-only design that would require a backward-compatible migration later. Head and workers have fundamentally different security profiles — head needs external access (dashboard, submitter, Prometheus) while workers typically need outbound access (S3, model registries). A shared-only API forces users to over-permit workers just to allow access to the head. New API shape: networkIsolation: mode: DenyAll head: ingressRules: [...] egressRules: [...] worker: ingressRules: [...] egressRules: [...] Co-authored-by: Cursor <cursor@cursor.sh>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
Signed-off-by: Pat O'Connor <paoconno@redhat.com>
15a2156 to
f53cf82
Compare
Why are these changes needed?
KubeRay currently provides a flexible foundation for deploying Ray on Kubernetes but relies on users to manually configure critical security features. As per this proposal doc this PR is one tentpole of a larger feature set aimed at security conscious network templates.
This PR handles the automatic creation of
NetworkPoliciesforRayClustersvia a new controller in KubeRay. The controller utilises a new field in theRayClusterCR's spec,networkIsolation. This field has 3 values usable for it'smodefield:DenyAll- this default will prevent all ingress and egress with the exception of itra-cluster pod communication. This includes blocking egress needed forRayJobs. It services as a sensible starting point for any additionalingressRulesoregressRulesthat a user wishes to add. The intended approach here would be to use a webhook to add any additional rules. This should maintain an initially conservative security posture from which to build a user-specific template.DenyAllIngress- restricts all inbound traffic toRayClusterpods while leaving egress unrestricted. Intra-cluster communication and KubeRay operator access are still permitted by default. Like denyAll, any user-specified ingressRules are appended to the base policy, and RayJob submitter pods are automatically allowed when the RayCluster is owned by a RayJob. This mode is useful when Ray workloads need outbound access (e.g. pulling from external data sources or reaching cloud APIs) but should not be reachable from arbitrary pods in the namespace.DenyAllEgress- restricts all outbound traffic fromRayClusterpods while leaving ingress unrestricted. Intra-cluster communication and DNS resolution (port 53) are preserved as base rules to ensure the cluster remains functional. Any user-specified egressRules are appended alongside these defaults. This mode suits environments where inbound access to the Ray dashboard or client port should remain open but workloads should not be able to reach external services without explicit allowlisting. NOTE: For the use ofpipetc in the context of aRayJobor to useRayServethe user is required to addegressRulesfor these.In all three modes, the controller generates separate
NetworkPolicyresources for head and worker pods. The base rules always ensure inter-pod communication within the cluster is unimpeded and that the KubeRay operator can reach the head node's dashboard and client ports. As previously outlined, users can extend any mode via theingressRulesandegressRulesfields on thenetworkIsolationspec, which are appended verbatim to the generated policies.These resources are owned by the
RayCluster(or theRayJobthat owns the respectiveRayCluster) and are life-cycled accordingly to mitigate the need for user cleanup. These rules work on the expectation that good RBAC practice is maintained in your cluster.NOTE: RayClusters that are owned by RayJobs function the same as outlined above but an additional rule accounts for the RayJob submitter pod (this rule is present on all RayClusters). This rule uses the OwnerReference to validate but given this isn't present when a RayJob is submitted against a pre-existing cluster. To account for this, a new env var (which defaults to false) can be used to add a more permissive rule that will facilitate these submitter pods.
The proposal doc features additional information about the specific rules for each mode and the rational behind them.
Related issue number
Closes: 3987
Checks