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

K8 array resource manager #120

Merged
merged 43 commits into from
Oct 13, 2020
Merged

Conversation

anandswaminathan
Copy link
Contributor

@anandswaminathan anandswaminathan commented Sep 15, 2020

Continued from #71 - Unable to push to mtoledo/k8-array-resource-manager

New changes:

  • Support for remote endpoint
  • Unit tests for resource manager and k8s array.
  • Few minor fixes and updates.
  • Remove owner refs for remote execution.
  • Removed project/namespace limit for number of pods.

cc @EngHabu @migueltol22

@anandswaminathan
Copy link
Contributor Author

PTAL @EngHabu

@anandswaminathan anandswaminathan force-pushed the k8-array-resource-manager branch from f616f34 to 50ccc6b Compare October 2, 2020 00:22
@anandswaminathan
Copy link
Contributor Author

PTAL @katrogan @kumare3 @migueltol22

if totalRunning+totalSuccesses < minSuccesses {
logger.Infof(ctx, "Array failed early because totalRunning[%v] + totalSuccesses[%v] < minSuccesses[%v]",
totalRunning, totalSuccesses, minSuccesses)
if totalRunning+totalSuccesses+totalWaitingForResources < minSuccesses {
Copy link
Contributor

Choose a reason for hiding this comment

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

wow how was this working correctly before?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because we never have totalWaitingForResources ? Is that your question?

Copy link
Contributor

Choose a reason for hiding this comment

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

oh I didn't realize that phase was introduced here. yes, thanks for explaining

return string(token), nil
}

// Reads secret values from paths specified in the config to initialize a Kubernetes rest client Config.
Copy link
Contributor

Choose a reason for hiding this comment

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

we should move this to flytestdlib since it also exists in flyteadmin

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup. Will add TODO.

Copy link
Contributor

Choose a reason for hiding this comment

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

@katrogan / @anandswaminathan I prefer we dont do this at all, I know you want to do this to test, but keep it for shorter time. My preference is that we run the entire workflow in a separate cluster if need be

// Continue with execution if successful
case LaunchError:
return currentState, logLinks, err
// If Resource manager is enabled and there are currently not enough resources we can skip this round
Copy link
Contributor

Choose a reason for hiding this comment

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

is this the only case when we get to LaunchWaiting?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Only resourcemanager has introduced LaunchWaiting.

func (t Task) Launch(ctx context.Context, tCtx core.TaskExecutionContext, kubeClient core.KubeClient) (LaunchResult, error) {
podTemplate, _, err := FlyteArrayJobToK8sPodTemplate(ctx, tCtx)
// Do not owner references for remote cluster execution
if t.Config.RemoteClusterConfig.Enabled {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: move this check after if err != nil { below? or is it necessary to clear regardless?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Aah good catch

return MonitorError, errors2.Wrapf(ErrCheckPodStatus, err, "Failed to check pod status.")
}

logger.Debugf(ctx, "Monitor - phase info %v", phaseInfo)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: add task index to this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed. For debug. Not useful.


return nil
}
return err
Copy link
Contributor

Choose a reason for hiding this comment

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

should this be wrapped flytestdlib.error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure. Any reason to?

Copy link
Contributor

Choose a reason for hiding this comment

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

we have been wrapping it in stdlib error if we want to achieve some specific behavior. But for plugins we want to make it simpler

Copy link
Contributor

Choose a reason for hiding this comment

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

👍 got it


resourceNamespace := core.ResourceNamespace(config.ResourceConfig.PrimaryLabel)
resourceConstraintSpec := core.ResourceConstraintsSpec{
ProjectScopeResourceConstraint: nil,
Copy link
Contributor

Choose a reason for hiding this comment

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

why are these nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because we do not want any Project/Namespace based restriction today. We can add later if needed. I think it will not be used at all as resource quota will get a lot sooner. On top there is global limit as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused though, don't we need to specify some constraint in order to leverage resource manager?

Copy link
Contributor

Choose a reason for hiding this comment

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

or is the resourceNamespace that constraint and sufficient?

@codecov-io
Copy link

codecov-io commented Oct 7, 2020

Codecov Report

Merging #120 into master will decrease coverage by 0.64%.
The diff coverage is 38.46%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #120      +/-   ##
==========================================
- Coverage   61.84%   61.20%   -0.65%     
==========================================
  Files         104      105       +1     
  Lines        5797     5941     +144     
==========================================
+ Hits         3585     3636      +51     
- Misses       1845     1930      +85     
- Partials      367      375       +8     
Impacted Files Coverage Δ
go/tasks/aws/config.go 50.00% <ø> (ø)
go/tasks/pluginmachinery/core/phase.go 28.88% <0.00%> (-0.66%) ⬇️
go/tasks/plugins/array/core/state.go 37.70% <0.00%> (-1.96%) ⬇️
go/tasks/plugins/array/k8s/launcher.go 32.00% <0.00%> (-12.16%) ⬇️
go/tasks/plugins/array/k8s/config.go 10.71% <7.40%> (-89.29%) ⬇️
go/tasks/plugins/array/k8s/executor.go 38.14% <15.38%> (-8.61%) ⬇️
go/tasks/plugins/array/k8s/task.go 48.24% <48.24%> (ø)
go/tasks/plugins/array/k8s/monitor.go 55.23% <53.84%> (-0.06%) ⬇️
go/tasks/plugins/array/k8s/config_flags.go 61.29% <100.00%> (+13.46%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0d28888...fac4413. Read the comment docs.

@anandswaminathan anandswaminathan force-pushed the k8-array-resource-manager branch from ce45427 to cf9c388 Compare October 7, 2020 17:12
@kumare3
Copy link
Contributor

kumare3 commented Oct 7, 2020

@anandswaminathan can you please associate this with the issue?

import core "github.com/lyft/flyteplugins/go/tasks/pluginmachinery/core"
import mock "github.com/stretchr/testify/mock"
import (
context "context"
Copy link
Contributor

Choose a reason for hiding this comment

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

too many blank lines?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will check

Limit int `json:"limit" pflag:",Resource quota (in the number of outstanding requests) for the cluster"`
}

type ClusterConfig struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we put some comments here, explaining why we have a cluster config and why we need to do this? This seems a little complicated IMO

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.

logger.Infof(ctx, "Array failed early because totalRunning[%v] + totalSuccesses[%v] < minSuccesses[%v]",
totalRunning, totalSuccesses, minSuccesses)
if totalRunning+totalSuccesses+totalWaitingForResources < minSuccesses {
logger.Infof(ctx, "Array failed early because totalRunning[%v] + totalSuccesses[%v] + totalWaitingForResource[%v] < minSuccesses[%v]",
Copy link
Contributor

Choose a reason for hiding this comment

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

Array failed early because number of failures are > minimum success requirements. Snapshot: TotalRunning[%d].....

Copy link
Contributor

Choose a reason for hiding this comment

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

do we have concurrency limits?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

if strings.Contains(err.Error(), "exceeded quota") {
// TODO: Quota errors are retried forever, it would be good to have support for backoff strategy.
logger.Infof(ctx, "Failed to launch job, resource quota exceeded. Err: %v", err)
t.State = t.State.SetPhase(arrayCore.PhaseWaitingForResources, 0).SetReason("Not enough resources to launch job")
Copy link
Contributor

Choose a reason for hiding this comment

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

is this the same as plugin manager?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As in ? yes. If you are referring to same phase? then yes

podName := formatSubTaskName(ctx, tCtx.TaskExecutionMetadata().GetTaskExecutionID().GetGeneratedName(), indexStr)
resourceNamespace := core.ResourceNamespace(config.ResourceConfig.PrimaryLabel)

err := tCtx.ResourceManager().ReleaseResource(ctx, resourceNamespace, podName)
Copy link
Contributor

Choose a reason for hiding this comment

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

is not found handled here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup. I checked and confirmed logs. Will confirm with resource manager API as well.

@anandswaminathan
Copy link
Contributor Author

PTAL @kumare3 @katrogan Addressed comments


// TODO: Move logic to flytestdlib
// Reads secret values from paths specified in the config to initialize a Kubernetes rest client Config.
func RemoteClusterConfig(host string, auth Auth) (*restclient.Config, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the purpose of remoteCluster?

Copy link
Contributor Author

@anandswaminathan anandswaminathan Oct 8, 2020

Choose a reason for hiding this comment

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

This is our V0 milestone. We do not have a way to prioritize regular tasks over array tasks in the same namespace. Array task will end up utilizing all the resource quotas, that will prevent all the other tasks from progressing.

}

if phaseInfo.Info() != nil {
logLinks = append(logLinks, phaseInfo.Info().Logs...)
// The first time we enter this state we will launch every subtask. On subsequent rounds, the pod
Copy link
Contributor

Choose a reason for hiding this comment

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

which state? i don't see this wrapped in a check for a specific phase

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the entire function - LaunchAndCheckSubTasksState . The specific phase is the caller - PhaseCheckingSubTaskExecutions

Copy link
Contributor

Choose a reason for hiding this comment

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

so we call Launch everytime we're in PhaseCheckingSubTaskExecutions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup :)

Copy link
Contributor

Choose a reason for hiding this comment

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

is launch idempotent?

Copy link
Contributor Author

@anandswaminathan anandswaminathan Oct 9, 2020

Choose a reason for hiding this comment

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

Yup. And we handle K8s already exists.

Not just launch, but also resource allocation.

katrogan
katrogan previously approved these changes Oct 12, 2020
Copy link
Contributor

@katrogan katrogan left a comment

Choose a reason for hiding this comment

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

lgtm, but not sure if @kumare3 has more comments

@anandswaminathan anandswaminathan merged commit f6148f4 into master Oct 13, 2020
eapolinario pushed a commit that referenced this pull request Sep 6, 2023
* Support for remote endpoint
* Unit tests for resource manager and k8s array.
* Few minor fixes and updates.
* Remove owner refs for remote execution.
* Removed project/namespace limit for number of pods.
* abort then finalize
* rm unnecessary code & update state transition
* Adding unit tests, remote endpoint and fixes


Co-authored-by: Miguel Toledo <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants