Skip to content

Add fqdn - #5108

Closed
AlterHoodie wants to merge 1 commit into
ray-project:masterfrom
AlterHoodie:add-fqdn
Closed

Add fqdn#5108
AlterHoodie wants to merge 1 commit into
ray-project:masterfrom
AlterHoodie:add-fqdn

Conversation

@AlterHoodie

Copy link
Copy Markdown
Contributor

Why are these changes needed?

Ray worker Pods are only addressable by Pod IP today, and that IP changes whenever a Pod is recreated. This PR sets worker hostname / subdomain from replica (and host - for multihost) indices and always creates the RayCluster headless Service so each worker gets a stable Pod FQDN that can survive recreates.

Hostname/subdomain assignment still sits behind RayMultiHostIndexing, since that is where replica indices are assigned. Creating the headless Service is no longer limited to multi-host groups (NumOfHosts > 1).

That stretches the meaning of RayMultiHostIndexing. Looking for guidance on whether to:

  1. Add a separate feature flag for worker FQDNs / always-on headless Service alongside RayMultiHostIndexing, or
  2. Keep this approach: headless Service by default for all worker groups, hostname/subdomain still tied to RayMultiHostIndexing (default on).

Note: The multi_host e2e test has been extended to support FQDN verification , depending on above decision will split into its own e2e test.

Related issue number

Closes #5000

Checks

  • I've made sure the tests are passing.
  • Testing Strategy
    • Unit tests
    • Manual tests
    • This PR is not tested :(

Manual test instructions

  1. Build/deploy operator with this change (./hack/local_deploy.sh or equivalent) and ensure RayMultiHostIndexing=true.
  2. Apply a sample cluster:
    kubectl apply -f ray-operator/config/samples/ray-cluster.sample.yaml
  3. Confirm worker hostname/subdomain and headless Service:
    kubectl get svc | grep headless
    kubectl get pods -l ray.io/node-type=worker -o custom-columns=\
    NAME:.metadata.name,HOSTNAME:.spec.hostname,SUBDOMAIN:.spec.subdomain,IP:.status.podIP
  4. DNS lookup:
    kubectl run dnscheck --rm --restart=Never --image=busybox:1.36 --attach -- \
      nslookup workergroup-0.raycluster-kuberay-headless.default.svc.cluster.local
  5. Delete the worker Pod and confirm the replacement keeps the same hostname/FQDN with a new IP/UID.
  6. Unit tests:
    cd ray-operator
    go test ./controllers/ray/common/ -run TestDeafultWorkerPodTemplateWithReplicaGrpAndIndex -count=1
    go test ./controllers/ray/ -run TestReconcileHeadlessService -count=1
  7. E2E (operator image must include this change):
    cd ray-operator
    go test -timeout 30m -v ./test/e2e -run TestRayClusterSingleHostMultiSlice
    go test -timeout 60m -v ./test/e2e -run TestRayClusterMultiHostMultiSlice

Comment thread ray-operator/controllers/ray/common/pod.go

@win5923 win5923 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @AlterHoodie, I think it would be better to add a separate feature flag/field for worker FQDNs, since users may not use the RayMultiHostIndexing feature flag.

There is also a similar PR to support mTLS with stable, resolvable FQDNs.
#5191

@AlterHoodie

Copy link
Copy Markdown
Contributor Author

Hey @win5923, thanks for the pointer to #5191, went through it to understand the overlap.

Two questions on scope before I proceed:

  1. Scope of the new flag/field. Should it cover only the DNS naming piece (stable hostname/subdomain plus headless Service, what this PR does today), or should it also cover [Feature] Support per-pod FQDNs & inject to Ray node ip #5191's --node-ip-address override (registering Ray nodes under the FQDN instead of the pod IP)? I'd lean towards keeping them independent since the node registration piece has autoscaler v1 compatibility implications, but want to confirm that matches your thinking.

  2. DNS1123 handling for groupName. groupName can legally contain uppercase or underscores as a K8s label, but pod.Spec.Hostname must be a valid DNS1123 label, and [Feature] Support per-pod FQDNs & inject to Ray node ip #5191 has the same issue. I'm planning to enforce that groupName be DNS1123 compliant when this feature is enabled, similar to how ray-operator/controllers/ray/utils/validation.go already does for NetworkPolicy. I'll update validation.go so the check runs once regardless of which feature (or both) requires it, rather than duplicating it.

@win5923

win5923 commented Aug 25, 2026

Copy link
Copy Markdown
Member

Scope of the new flag/field. Should it cover only the DNS naming piece (stable hostname/subdomain plus headless Service, what this PR does today), or should it also cover #5191 --node-ip-address override (registering Ray nodes under the FQDN instead of the pod IP)? I'd lean towards keeping them independent since the node registration piece has autoscaler v1 compatibility implications, but want to confirm that matches your thinking.

Yes, that's a separate use case. Users may only need stable FQDNs for their Ray Pods as stable identities for TLS certificates, but Ray itself would also need to register and advertise those FQDNs instead of Pod IPs.

Another use case is Istio. Today, KubeRay workers are primarily addressable by their Pod IPs, and KubeRay does not create a stable per-pod DNS identity for worker Pods by default. This is a mismatch with how Istio's service discovery and identity model works: Istio relies on Kubernetes Services and their endpoints to discover workloads and associate network traffic with stable workload identities. But this is not related to Ray itslef.

In #5191, users can choose whether their RayCluster should register Ray nodes using the Pod FQDN instead of the Pod IP. This allows the FQDN to be used not only as a Kubernetes/DNS identity, but also as the address advertised by Ray itself.

It maintains backward compatibility, so users who are still using Autoscaler v1 won't be affected when choosing the DNSOnly mode.

DNS1123 handling for groupName. groupName can legally contain uppercase or underscores as a K8s label, but pod.Spec.Hostname must be a valid DNS1123 label, and #5191 has the same issue. I'm planning to enforce that groupName be DNS1123 compliant when this feature is enabled, similar to how ray-operator/controllers/ray/utils/validation.go already does for NetworkPolicy. I'll update validation.go so the check runs once regardless of which feature (or both) requires it, rather than duplicating it.

I think we can keep the current behavior now, and address this in another PR.

@win5923

win5923 commented Aug 25, 2026

Copy link
Copy Markdown
Member

Hi @AlterHoodie, I think #5191 overlaps with yours. Would you like to pick up another issue instead? I can find some issues for you, feel free to reach out to me on the Ray Slack.

@AlterHoodie

Copy link
Copy Markdown
Contributor Author

Hey @win5923, was just finishing up with the PR. Will push the changes in sometime, if you guys haven't decided on how to make the FQDN stable yet and if my implementation feels appropriate, please do use it as reference.

…d FQDNs

Assign replica/host indices so hostname+subdomain can stay unique, including
multi-host groups when indexing is off, via NeedsWorkerIndices.
@AlterHoodie

Copy link
Copy Markdown
Contributor Author

The operator feature gate RayClusterWorkerFQDN (alpha, default off) gives each worker Pod a stable FQDN by setting hostname and subdomain and creating the headless Service {cluster}-headless. Single host names are {group}-{replicaIndex}. Multi host names are {group}-{replicaIndex}-{hostIndex}. Replica and host numbers are not in the YAML. reconcilePods assigns them: if numOfHosts is greater than 1 and NeedsWorkerIndices() is true it uses reconcileMultiHostWorkerGroup (inner loop is host index), otherwise the old per Pod loop with hostIndex always 0. Stamping is in DefaultWorkerPodTemplate. The headless Service is created when FQDN is on or when numOfHosts is greater than 1 (the old multi host peer DNS behavior).

NeedsWorkerIndices() is RayMultiHostIndexing or RayClusterWorkerFQDN. That coupling is a bit awkward. FQDN needs unique replica and host numbers so hostnames do not collide. For a multi host group that means taking the slice reconcile path and writing slice labels even when RayMultiHostIndexing is off. Indexing itself is only labels and atomic slices, not DNS. Turning FQDN on with indexing off therefore changes how multi host groups are reconciled, not only whether hostname is set.

Also on a side note, Curious whether this is the right approach or there is a cleaner split. For example keeping slice reconcile strictly behind RayMultiHostIndexing and having FQDN assign hostnames some other way, or documenting that FQDN for numOfHosts greater than 1 expects indexing.

Unit coverage is in pod_test.go and TestReconcileHeadlessService, including FQDN off with indexing still on. E2E is raycluster_worker_fqdn_test.go (single host, recreate, scale). Haven't thoroughly tested

@AlterHoodie

Copy link
Copy Markdown
Contributor Author

Closing, since this is a duplicate of #5191

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 24cb74d. Configure here.

}

isRayMultiHostIndexing := worker.NumOfHosts > 1 && features.Enabled(features.RayMultiHostIndexing)
isRayMultiHostIndexing := worker.NumOfHosts > 1 && features.NeedsWorkerIndices()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FQDN orphans existing multi-host pods

Medium Severity

With RayClusterWorkerFQDN on and RayMultiHostIndexing off, NeedsWorkerIndices routes NumOfHosts > 1 groups into reconcileMultiHostWorkerGroup. That path only tracks Pods that already have ray.io/worker-group-replica-name. Existing unlabeled multi-host workers from the legacy path are ignored while a full new replica set is created, leaving the cluster over-provisioned with orphaned Pods.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 24cb74d. Configure here.

@win5923

win5923 commented Aug 26, 2026

Copy link
Copy Markdown
Member

Hey @win5923, was just finishing up with the PR. Will push the changes in sometime, if you guys haven't decided on how to make the FQDN stable yet and if my implementation feels appropriate, please do use it as reference.

Sure, after the ray summit i will talk to the kuberay maintainer which approach is better.
Thanks for you contribution!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Support Pod FQDNs via pod.spec.hostname

2 participants