Skip to content

Commit 28dd2bf

Browse files
htahir1schustmi
andauthored
Kubeflow workaround added (#886)
* Kubeflow workaround added * Add missing host Co-authored-by: Michael Schuster <[email protected]>
1 parent e35cb26 commit 28dd2bf

File tree

1 file changed

+78
-1
lines changed

1 file changed

+78
-1
lines changed

docs/book/mlops-stacks/orchestrators/kubeflow.md

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,81 @@ A concrete example of using the Kubeflow orchestrator can be found
198198
[here](https://github.com/zenml-io/zenml/tree/main/examples/kubeflow_pipelines_orchestration).
199199

200200
For more information and a full list of configurable attributes of the Kubeflow orchestrator, check out the
201-
[API Docs](https://apidocs.zenml.io/latest/api_docs/integrations/#zenml.integrations.kubeflow.orchestrators.kubeflow_orchestrator.KubeflowOrchestrator).
201+
[API Docs](https://apidocs.zenml.io/latest/api_docs/integrations/#zenml.integrations.kubeflow.orchestrators.kubeflow_orchestrator.KubeflowOrchestrator).
202+
203+
## Important Note for Multi-Tenancy Deployments
204+
205+
Kubeflow has a notion of [multi-tenancy](https://www.kubeflow.org/docs/components/multi-tenancy/overview/)
206+
built into its deployment. Kubeflow’s multi-user isolation simplifies user
207+
operations because each user only views and edited\s the Kubeflow components
208+
and model artifacts defined in their configuration.
209+
210+
Currently, the default ZenML Kubeflow orchestrator yields the following error
211+
when running a pipeline:
212+
213+
```shell
214+
HTTP response body: {"error":"Invalid input error: Invalid resource references for experiment. ListExperiment requires filtering by namespace.","code":3,"message":"Invalid input error: Invalid resource references for experiment. ListExperiment requires filtering by
215+
namespace.","details":[{"@type":"type.googleapis.com/api.Error","error_message":"Invalid resource references for experiment. ListExperiment requires filtering by namespace.","error_details":"Invalid input error: Invalid resource references for experiment. ListExperiment requires filtering by namespace."}]}
216+
```
217+
218+
The current workaround is as follows:
219+
220+
```python
221+
import json
222+
import os
223+
import kfp
224+
225+
NAMESPACE = "namespace_name" # set this
226+
USERNAME = "foo" # set this
227+
PASSWORD = "bar" # set this
228+
HOST = "https://qux.com" # set this
229+
KFP_CONFIG = '~/.config/kfp/context.json' # set this manually if you'd like
230+
231+
def get_kfp_token(username: str, password: str) -> str:
232+
"""Get token for kubeflow authentication."""
233+
session = requests.Session()
234+
response = session.get(HOST)
235+
headers = {
236+
"Content-Type": "application/x-www-form-urlencoded",
237+
}
238+
data = {"login": username, "password": password}
239+
session.post(response.url, headers=headers, data=data)
240+
session_cookie = session.cookies.get_dict()["authservice_session"]
241+
return session_cookie
242+
243+
token = get_kfp_token()
244+
cookies = 'authservice_session=' + token
245+
246+
# 1: Set user namespace globally
247+
kfp.Client(host=HOST, cookies=cookies).set_user_namespace(NAMESPACE)
248+
249+
# 2: Set cookie globally in the kfp config file
250+
with open(KFP_CONFIG, 'r') as f:
251+
data = json.load(f)
252+
data['client_authentication_cookie'] = cookies
253+
254+
os.remove(KFP_CONFIG)
255+
with open(KFP_CONFIG, 'w') as f:
256+
json.dump(data, f)
257+
258+
# Continue with your normal pipeline code..
259+
```
260+
261+
Please note that in the above code, `HOST` should be registered on orchestration registration,
262+
with the `kubeflow_hostname` parameter:
263+
264+
```
265+
export HOST=https://qux.com
266+
zenml orchestrator register multi_tenant_kf --flavor=kubeflow \
267+
--kubeflow_hostname=$(HOST)/pipeline # /pipeline is important!
268+
--other_params..
269+
```
270+
In future ZenML versions, multi-tenancy will be natively supported. See this
271+
[Slack thread](https://zenml.slack.com/archives/C01FWQ5D0TT/p1662545810395779) for more details
272+
on how the above workaround came to effect.
273+
274+
Please note that the above is all to initialize the `kfp.Client()` class in the standard orchestrator logic.
275+
This code can be seen [here](https://github.com/zenml-io/zenml/blob/main/src/zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py#L709).
276+
277+
You can simply override this logic and add your custom authentication scheme if needed. Read [here](custom.md)
278+
for more details on how to create a custom orchestrator.

0 commit comments

Comments
 (0)