Skip to content
This repository was archived by the owner on Oct 9, 2023. It is now read-only.

Commit 2afc441

Browse files
ByronHsubyhsu
andauthored
Enable pod template and Use copy to construct head/worker in ray plugin (#349)
* Enable pod template and Use copy to construct head/worker in ray plugin Signed-off-by: byhsu <byhsu@linkedin.com> * fix linit Signed-off-by: byhsu <byhsu@linkedin.com> * wip Signed-off-by: byhsu <byhsu@linkedin.com> * fix test Signed-off-by: byhsu <byhsu@linkedin.com> --------- Signed-off-by: byhsu <byhsu@linkedin.com> Co-authored-by: byhsu <byhsu@linkedin.com>
1 parent 9a2bbba commit 2afc441

1 file changed

Lines changed: 61 additions & 33 deletions

File tree

  • go/tasks/plugins/k8s/ray

go/tasks/plugins/k8s/ray/ray.go

Lines changed: 61 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99

1010
"github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/core"
1111
"github.com/flyteorg/flyteidl/gen/pb-go/flyteidl/plugins"
12-
"github.com/flyteorg/flyteplugins/go/tasks/errors"
1312
"github.com/flyteorg/flyteplugins/go/tasks/logs"
1413
"github.com/flyteorg/flyteplugins/go/tasks/pluginmachinery"
1514
pluginsCore "github.com/flyteorg/flyteplugins/go/tasks/pluginmachinery/core"
@@ -22,6 +21,7 @@ import (
2221

2322
v1 "k8s.io/api/core/v1"
2423

24+
flyteerr "github.com/flyteorg/flyteplugins/go/tasks/errors"
2525
"sigs.k8s.io/controller-runtime/pkg/client"
2626
)
2727

@@ -44,20 +44,35 @@ func (rayJobResourceHandler) GetProperties() k8s.PluginProperties {
4444
func (rayJobResourceHandler) BuildResource(ctx context.Context, taskCtx pluginsCore.TaskExecutionContext) (client.Object, error) {
4545
taskTemplate, err := taskCtx.TaskReader().Read(ctx)
4646
if err != nil {
47-
return nil, errors.Errorf(errors.BadTaskSpecification, "unable to fetch task specification [%v]", err.Error())
47+
return nil, flyteerr.Errorf(flyteerr.BadTaskSpecification, "unable to fetch task specification [%v]", err.Error())
4848
} else if taskTemplate == nil {
49-
return nil, errors.Errorf(errors.BadTaskSpecification, "nil task specification")
49+
return nil, flyteerr.Errorf(flyteerr.BadTaskSpecification, "nil task specification")
5050
}
5151

5252
rayJob := plugins.RayJob{}
5353
err = utils.UnmarshalStruct(taskTemplate.GetCustom(), &rayJob)
5454
if err != nil {
55-
return nil, errors.Errorf(errors.BadTaskSpecification, "invalid TaskSpecification [%v], Err: [%v]", taskTemplate.GetCustom(), err.Error())
55+
return nil, flyteerr.Errorf(flyteerr.BadTaskSpecification, "invalid TaskSpecification [%v], Err: [%v]", taskTemplate.GetCustom(), err.Error())
5656
}
5757

58-
container, err := flytek8s.ToK8sContainer(ctx, taskCtx)
58+
podSpec, objectMeta, primaryContainerName, err := flytek8s.ToK8sPodSpec(ctx, taskCtx)
59+
5960
if err != nil {
60-
return nil, errors.Errorf(errors.BadTaskSpecification, "Unable to create container spec: [%v]", err.Error())
61+
return nil, flyteerr.Errorf(flyteerr.BadTaskSpecification, "Unable to create pod spec: [%v]", err.Error())
62+
}
63+
64+
var container v1.Container
65+
found := false
66+
for _, c := range podSpec.Containers {
67+
if c.Name == primaryContainerName {
68+
container = c
69+
found = true
70+
break
71+
}
72+
}
73+
74+
if !found {
75+
return nil, flyteerr.Errorf(flyteerr.BadTaskSpecification, "Unable to get primary container from the pod: [%v]", err.Error())
6176
}
6277

6378
headReplicas := int32(1)
@@ -78,7 +93,7 @@ func (rayJobResourceHandler) BuildResource(ctx context.Context, taskCtx pluginsC
7893
enableIngress := true
7994
rayClusterSpec := rayv1alpha1.RayClusterSpec{
8095
HeadGroupSpec: rayv1alpha1.HeadGroupSpec{
81-
Template: buildHeadPodTemplate(container, taskCtx),
96+
Template: buildHeadPodTemplate(&container, podSpec, objectMeta, taskCtx),
8297
ServiceType: v1.ServiceType(GetConfig().ServiceType),
8398
Replicas: &headReplicas,
8499
EnableIngress: &enableIngress,
@@ -88,7 +103,7 @@ func (rayJobResourceHandler) BuildResource(ctx context.Context, taskCtx pluginsC
88103
}
89104

90105
for _, spec := range rayJob.RayCluster.WorkerGroupSpec {
91-
workerPodTemplate := buildWorkerPodTemplate(container, taskCtx)
106+
workerPodTemplate := buildWorkerPodTemplate(&container, podSpec, objectMeta, taskCtx)
92107

93108
minReplicas := spec.Replicas
94109
maxReplicas := spec.Replicas
@@ -139,18 +154,20 @@ func (rayJobResourceHandler) BuildResource(ctx context.Context, taskCtx pluginsC
139154
Kind: KindRayJob,
140155
APIVersion: rayv1alpha1.SchemeGroupVersion.String(),
141156
},
142-
Spec: jobSpec,
157+
Spec: jobSpec,
158+
ObjectMeta: *objectMeta,
143159
}
144160

145161
return &rayJobObject, nil
146162
}
147163

148-
func buildHeadPodTemplate(container *v1.Container, taskCtx pluginsCore.TaskExecutionContext) v1.PodTemplateSpec {
164+
func buildHeadPodTemplate(container *v1.Container, podSpec *v1.PodSpec, objectMeta *metav1.ObjectMeta, taskCtx pluginsCore.TaskExecutionContext) v1.PodTemplateSpec {
149165
// Some configs are copy from https://github.com/ray-project/kuberay/blob/b72e6bdcd9b8c77a9dc6b5da8560910f3a0c3ffd/apiserver/pkg/util/cluster.go#L97
150166
// They should always be the same, so we could hard code here.
151-
primaryContainer := &v1.Container{Name: "ray-head", Image: container.Image}
152-
primaryContainer.Resources = container.Resources
153-
primaryContainer.Env = []v1.EnvVar{
167+
primaryContainer := container.DeepCopy()
168+
primaryContainer.Name = "ray-head"
169+
170+
envs := []v1.EnvVar{
154171
{
155172
Name: "MY_POD_IP",
156173
ValueFrom: &v1.EnvVarSource{
@@ -160,8 +177,12 @@ func buildHeadPodTemplate(container *v1.Container, taskCtx pluginsCore.TaskExecu
160177
},
161178
},
162179
}
163-
primaryContainer.Env = append(primaryContainer.Env, container.Env...)
164-
primaryContainer.Ports = []v1.ContainerPort{
180+
181+
primaryContainer.Args = []string{}
182+
183+
primaryContainer.Env = append(primaryContainer.Env, envs...)
184+
185+
ports := []v1.ContainerPort{
165186
{
166187
Name: "redis",
167188
ContainerPort: 6379,
@@ -175,20 +196,23 @@ func buildHeadPodTemplate(container *v1.Container, taskCtx pluginsCore.TaskExecu
175196
ContainerPort: 8265,
176197
},
177198
}
178-
pod := &v1.PodSpec{
179-
Containers: []v1.Container{*primaryContainer},
180-
}
181-
flytek8s.UpdatePod(taskCtx.TaskExecutionMetadata(), []v1.ResourceRequirements{primaryContainer.Resources}, pod)
199+
200+
primaryContainer.Ports = append(primaryContainer.Ports, ports...)
201+
202+
headPodSpec := podSpec.DeepCopy()
203+
204+
headPodSpec.Containers = []v1.Container{*primaryContainer}
182205

183206
podTemplateSpec := v1.PodTemplateSpec{
184-
Spec: *pod,
207+
Spec: *headPodSpec,
208+
ObjectMeta: *objectMeta,
185209
}
186210
podTemplateSpec.SetLabels(utils.UnionMaps(podTemplateSpec.GetLabels(), utils.CopyMap(taskCtx.TaskExecutionMetadata().GetLabels())))
187211
podTemplateSpec.SetAnnotations(utils.UnionMaps(podTemplateSpec.GetAnnotations(), utils.CopyMap(taskCtx.TaskExecutionMetadata().GetAnnotations())))
188212
return podTemplateSpec
189213
}
190214

191-
func buildWorkerPodTemplate(container *v1.Container, taskCtx pluginsCore.TaskExecutionContext) v1.PodTemplateSpec {
215+
func buildWorkerPodTemplate(container *v1.Container, podSpec *v1.PodSpec, objectMetadata *metav1.ObjectMeta, taskCtx pluginsCore.TaskExecutionContext) v1.PodTemplateSpec {
192216
// Some configs are copy from https://github.com/ray-project/kuberay/blob/b72e6bdcd9b8c77a9dc6b5da8560910f3a0c3ffd/apiserver/pkg/util/cluster.go#L185
193217
// They should always be the same, so we could hard code here.
194218
initContainers := []v1.Container{
@@ -203,10 +227,12 @@ func buildWorkerPodTemplate(container *v1.Container, taskCtx pluginsCore.TaskExe
203227
Resources: container.Resources,
204228
},
205229
}
230+
primaryContainer := container.DeepCopy()
231+
primaryContainer.Name = "ray-worker"
206232

207-
primaryContainer := &v1.Container{Name: "ray-worker", Image: container.Image}
208-
primaryContainer.Resources = container.Resources
209-
primaryContainer.Env = []v1.EnvVar{
233+
primaryContainer.Args = []string{}
234+
235+
envs := []v1.EnvVar{
210236
{
211237
Name: "RAY_DISABLE_DOCKER_CPU_WARNING",
212238
Value: "1",
@@ -268,7 +294,9 @@ func buildWorkerPodTemplate(container *v1.Container, taskCtx pluginsCore.TaskExe
268294
},
269295
},
270296
}
271-
primaryContainer.Env = append(primaryContainer.Env, container.Env...)
297+
298+
primaryContainer.Env = append(primaryContainer.Env, envs...)
299+
272300
primaryContainer.Lifecycle = &v1.Lifecycle{
273301
PreStop: &v1.LifecycleHandler{
274302
Exec: &v1.ExecAction{
@@ -279,7 +307,7 @@ func buildWorkerPodTemplate(container *v1.Container, taskCtx pluginsCore.TaskExe
279307
},
280308
}
281309

282-
primaryContainer.Ports = []v1.ContainerPort{
310+
ports := []v1.ContainerPort{
283311
{
284312
Name: "redis",
285313
ContainerPort: 6379,
@@ -293,15 +321,15 @@ func buildWorkerPodTemplate(container *v1.Container, taskCtx pluginsCore.TaskExe
293321
ContainerPort: 8265,
294322
},
295323
}
324+
primaryContainer.Ports = append(primaryContainer.Ports, ports...)
296325

297-
pod := &v1.PodSpec{
298-
Containers: []v1.Container{*primaryContainer},
299-
InitContainers: initContainers,
300-
}
301-
flytek8s.UpdatePod(taskCtx.TaskExecutionMetadata(), []v1.ResourceRequirements{primaryContainer.Resources}, pod)
326+
workerPodSpec := podSpec.DeepCopy()
327+
workerPodSpec.Containers = []v1.Container{*primaryContainer}
328+
workerPodSpec.InitContainers = initContainers
302329

303330
podTemplateSpec := v1.PodTemplateSpec{
304-
Spec: *pod,
331+
Spec: *workerPodSpec,
332+
ObjectMeta: *objectMetadata,
305333
}
306334
podTemplateSpec.SetLabels(utils.UnionMaps(podTemplateSpec.GetLabels(), utils.CopyMap(taskCtx.TaskExecutionMetadata().GetLabels())))
307335
podTemplateSpec.SetAnnotations(utils.UnionMaps(podTemplateSpec.GetAnnotations(), utils.CopyMap(taskCtx.TaskExecutionMetadata().GetAnnotations())))
@@ -350,7 +378,7 @@ func (rayJobResourceHandler) GetTaskPhase(ctx context.Context, pluginContext k8s
350378
return pluginsCore.PhaseInfoNotReady(time.Now(), pluginsCore.DefaultPhaseVersion, "job is pending"), nil
351379
case rayv1alpha1.JobStatusFailed:
352380
reason := fmt.Sprintf("Failed to create Ray job: %s", rayJob.Name)
353-
return pluginsCore.PhaseInfoFailure(errors.TaskFailedWithError, reason, info), nil
381+
return pluginsCore.PhaseInfoFailure(flyteerr.TaskFailedWithError, reason, info), nil
354382
case rayv1alpha1.JobStatusSucceeded:
355383
return pluginsCore.PhaseInfoSuccess(info), nil
356384
case rayv1alpha1.JobStatusRunning:

0 commit comments

Comments
 (0)