Skip to content

docs: beef up "submit flows to dynamic infra" with realistic k8s example#20997

Draft
devin-ai-integration[bot] wants to merge 2 commits intomainfrom
devin/1772755928-beef-up-k8s-submit-docs
Draft

docs: beef up "submit flows to dynamic infra" with realistic k8s example#20997
devin-ai-integration[bot] wants to merge 2 commits intomainfrom
devin/1772755928-beef-up-k8s-submit-docs

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Mar 6, 2026

Improves the "Submit Flows Directly to Dynamic Infrastructure" docs page to make the feature more approachable — specifically, making it obvious how dependencies get into the pod.

Motivated by a Bluesky conversation where the existing docs were too abstract for someone who just wants to "send a function to k8s."

Changes

  • "Running a flow with custom dependencies" subsection: Added under "Customizing infrastructure configuration" — shows building a Dockerfile with PyTorch, pushing it, and passing image= in the @kubernetes decorator so the pod runs your custom image instead of the default Prefect image
  • Fixed stale link: Updated base job template link from /v3/how-to-guides/deployment_infra/manage-work-pools#base-job-template/v3/advanced/customize-base-job-templates
  • Updated Further reading: Fixed work pools link to current path, added link to customize-base-job-templates page

All existing examples and content are preserved as-is; the new content is purely additive.

Updates since last revision

Addressed reviewer feedback ("doing too much") — removed the job variables table, numbered walkthrough, dynamic infrastructure sizing example, and "How it works under the hood" section. Kept only the focused custom image example.

Checklist for reviewers

  • Verify the two internal doc links resolve: /v3/advanced/customize-base-job-templates, /v3/deploy/infrastructure-concepts/work-pools
  • Confirm the <Tip> block and dockerfile code fence render correctly in Mintlify
  • Verify the {{ image }} placeholder explanation is technically accurate

Checklist

  • This pull request references any related issue by including "closes <link to issue>"
    • If no issue exists and your change is not a small fix, please create an issue first.
  • If this pull request adds new functionality, it includes unit tests that cover the changes
  • If this pull request removes docs files, it includes redirect settings in mint.json.
  • If this pull request adds functions or classes, it includes helpful docstrings.

Link to Devin session: https://app.devin.ai/sessions/20f3e4d9c79447a6bf0359793371c702
Requested by: Nate Nowack (@zzstoatzz)

Add detailed examples showing how dependencies get into pods via custom
images, a table of available k8s job variables, a dynamic memory sizing
example, and a 'how it works under the hood' section explaining the
relationship between the decorator, work pool base job template, and worker.

Co-authored-by: Nate Nowack <nate@prefect.io>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@github-actions github-actions bot added the docs label Mar 6, 2026
```python
@kubernetes(
work_pool="my-kubernetes-pool",
work_pool="my-k8s-pool",
Copy link
Collaborator

Choose a reason for hiding this comment

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

why switch this?

To submit a flow to specific infrastructure, use the appropriate decorator for that infrastructure type.

Here's an example using `@kubernetes`:
Here's a basic example using `@kubernetes`:
Copy link
Collaborator

Choose a reason for hiding this comment

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

you should have added an additional example, keeping the first one simple and adding this more idiosyncratic one second. furthermore making the example more complex and adding the word "basic" makes no sense

Comment on lines +247 to +253
Here's what happens when you run `ml_pipeline()` on your laptop:

1. `ml_pipeline` executes **locally** on your machine
2. When it calls `train_model`, Prefect serializes the function and its arguments, uploads them to the object storage configured on `my-k8s-pool`, and submits a flow run to the work pool
3. A worker polling `my-k8s-pool` picks up the run and creates a Kubernetes job using the work pool's **base job template** &mdash; a manifest that defines the shape of the `Job` spec (image, env vars, resource requests, etc.)
4. Because `image` is passed in the decorator, it overrides the `{{ image }}` placeholder in the job template, so the pod runs **your custom image** with PyTorch installed
5. The pod starts, downloads the serialized flow from object storage, executes it, and reports results back
Copy link
Collaborator

Choose a reason for hiding this comment

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

why are you explaining all this? the goal was to add a scrutable example for someone who just "wants function on a k8s pod", not add concept docs

Comment on lines +295 to +303
## How it works under the hood

Understanding the relationship between the decorator, the work pool, and the resulting Kubernetes job helps demystify this feature:

1. **Work pool** &mdash; A work pool of type `kubernetes` stores a **base job template**: a Kubernetes `Job` manifest with `{{ placeholder }}` variables like `{{ image }}`, `{{ namespace }}`, and `{{ env }}`. You can view and customize this template in the Prefect UI or via the CLI.

2. **`@kubernetes` decorator** &mdash; When you add `@kubernetes(work_pool="my-k8s-pool", image="...")` to a flow, the extra keyword arguments (`image`, `namespace`, etc.) become **job variable overrides**. These replace the corresponding `{{ placeholder }}` values in the base job template when a run is created.

3. **Worker** &mdash; A worker process polling the work pool receives the flow run, renders the final job manifest by merging the base template with the job variable overrides, and creates the Kubernetes `Job`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

doing too much

…age example

Restore the original first example and customization section untouched.
Remove the job variables table, numbered walkthrough, dynamic sizing
example, and 'how it works' section. Keep only the new 'Running a flow
with custom dependencies' subsection showing Dockerfile + image kwarg.

Co-authored-by: Nate Nowack <nate@prefect.io>
@devin-ai-integration devin-ai-integration bot changed the title docs: beef up "submit flows to dynamic infra" with realistic k8s examples docs: beef up "submit flows to dynamic infra" with realistic k8s example Mar 6, 2026
@devin-ai-integration
Copy link
Contributor Author

Addressed all comments — restored the original examples untouched, cut the job variables table / numbered walkthrough / dynamic sizing / "how it works" section. The only net-new content is the "Running a flow with custom dependencies" subsection (Dockerfile + image= kwarg example).

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant