New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Application] Introducing application runtime phase I #5234
Conversation
# Conflicts: # mlrun/run.py # mlrun/runtimes/__init__.py # mlrun/runtimes/nuclio/__init__.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking really good overall!
some comments below
mlrun/runtimes/nuclio/function.py
Outdated
if not name: | ||
raise ValueError("Sidecar name must be specified") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just enrich with f"{name}-sidecar"
here?
tests/runtimes/test_application.py
Outdated
assert fn.spec.image == "mlrun/mlrun" | ||
assert fn.metadata.name == "application-test" | ||
assert ( | ||
"Ly8gQ29weXJpZ2h0IDIwMjMgSWd1YXppbwovLwovLyBMaWN" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is base64 of the go reverse proxy func? perhaps add a comment on this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool stuff. Have some comments and suggestions.
mlrun/run.py
Outdated
filename = str(ApplicationRuntime.reverse_proxy_file_path) | ||
handler = "Handler" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filename = str(ApplicationRuntime.reverse_proxy_file_path) | |
handler = "Handler" | |
filename, handler = ApplicationRuntime.get_filename_and_handler() |
It's better to ask the ApplicationRuntime
class what these are - add a class method to the class to return them. This way any change in these will be local to the runtime class, and will not require searching through the code to find the reference here.
mlrun/run.py
Outdated
def resolve_nuclio_sub_kind(_kind): | ||
_is_nuclio = _kind.startswith("nuclio") | ||
_sub_kind = ( | ||
_kind[_kind.find(":") + 1 :] if _is_nuclio and ":" in _kind else None | ||
) | ||
if _kind == RuntimeKinds.serving: | ||
_is_nuclio = True | ||
_sub_kind = serving_subkind | ||
elif _kind == RuntimeKinds.application: | ||
_is_nuclio = True | ||
return _is_nuclio, _sub_kind |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're making these changes - isn't it better to move this to the RuntimeKinds
class? Like resolve_nuclio_runtime
?
@@ -0,0 +1,15 @@ | |||
# Copyright 2023 Iguazio |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Copyright 2023 Iguazio | |
# Copyright 2024 Iguazio |
😃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpicker 🐛 😄
needs to be changed in all files
def __init__(self, spec=None, metadata=None): | ||
super().__init__(metadata, spec) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's terrible that the order of parameters is different between this class and its super()
. How did that happen? As far as I can tell, the parent is KubeResource
which also does the same reversing (there's RemoteRuntime
which doesn't implement __init__
). So, does this even work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh wow fixed. copied it from KubeResource and fixed that one as well.
mlrun/runtimes/nuclio/function.py
Outdated
@@ -958,6 +957,38 @@ def invoke( | |||
data = json.loads(data) | |||
return data | |||
|
|||
def _with_sidecar(self, name: str, image: str, port: int = None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is now a general nuclio functionality, why not make this a public function, allowing users to add sidecars to nuclio functions not just in the application runtime case?
mlrun/runtimes/nuclio/function.py
Outdated
sidecar["image"] = image | ||
|
||
if port: | ||
sidecar["ports"] = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the sidecar function in nuclio supports multiple ports. Why not expose it here, and allow sending a list of ports to this function? Maybe change port
to be ports: Optional[Union[int, list[int]]] = None
?
tests/runtimes/test_application.py
Outdated
"Ly8gQ29weXJpZ2h0IDIwMjMgSWd1YXppbwovLwovLyBMaWN" | ||
in fn.spec.build.functionSourceCode | ||
) | ||
assert fn.spec.function_handler == "reverse_proxy:Handler" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once you add the file-path and handler as class methods for the app runtime, you can use them to construct this value, rather than use a fixed string.
|
||
class ApplicationRuntime(RemoteRuntime): | ||
kind = "application" | ||
reverse_proxy_file_path = pathlib.Path(__file__).parent / "reverse_proxy.go" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity - does nuclio understand that it needs to use Golang runtime based on the suffix of the file? There doesn't seem to be any indication in the code here about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nuclio-jupyter enriches the spec.runtime from the file extension
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good 👍 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work mate :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor
setup.py
Outdated
@@ -59,6 +59,7 @@ def version(): | |||
"server", | |||
] | |||
), | |||
package_data={"": ["*.go"]}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
provide the path and dont take all go files
|
||
if self.status.container_image: | ||
self.from_image(self.status.container_image) | ||
self.spec.build.functionSourceCode = "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.spec.build.functionSourceCode = "" | |
# nuclio implementation detail - when providing the image and emptying out the source code, | |
# nuclio skips rebuilding the image and simply takes the prebuilt image | |
self.spec.build.functionSourceCode = "" |
Application Runtime
MLRun allows user to deploy models and expose them for serving purposes.
We currently lack a way to enable users deploy an application atop those models. e.g. have a model that differentiate between cat and a dog and expose it while having a UI that allows the user to upload image to invoke the model with a given input. To do so, we introduce a way to deploy web application given user container image, port, and a command to run the http server.
The runtime is based on top of Nuclio and will add the application as a side-car to a Nuclio function while the actual function is a reverse proxy to that application.
The reason we want to use Nuclio for this runtime is to leverage its features such as scaling, triggers, monitoring, API gateway, etc.
Phase I
This phase is about making it work.
Usage example
Jira - https://iguazio.atlassian.net/browse/ML-4601