Skip to content

Inject INTERNAL_APP_ENDPOINT_PATTERN into KService pods for in-cluster app discovery#7323

Open
AdilFayyaz wants to merge 1 commit intomainfrom
adil/apps-internal-endpoint
Open

Inject INTERNAL_APP_ENDPOINT_PATTERN into KService pods for in-cluster app discovery#7323
AdilFayyaz wants to merge 1 commit intomainfrom
adil/apps-internal-endpoint

Conversation

@AdilFayyaz
Copy link
Copy Markdown
Contributor

@AdilFayyaz AdilFayyaz commented Apr 30, 2026

Why are the changes needed?

When multiple Flyte apps run in the same cluster (e.g. a Gradio app calling a vLLM model-serving app), apps need to call each other via the internal Kubernetes service URL (*.flyte.svc.cluster.local). Previouly the INTERNAL_APP_ENDPOINT_PATTERN env var — which the Flyte SDK's AppEndpoint uses to resolve internal URLs — was never injected into KService pods. This meant AppEndpoint(app_name="...") had no pattern to resolve against, and developers had to manually construct and hardcode the full internal cluster URL.

What changes were proposed in this pull request?

  • Inject INTERNAL_APP_ENDPOINT_PATTERN into every KService container at deploy time in buildKService. The value is a URL template with an {app_fqdn} placeholder that the SDK substitutes at runtime with the target app's name:

http://{app_fqdn}-{project}-{domain}.flyte.svc.cluster.local

  • The project and domain are baked in as a suffix to match Flyte's KService naming convention ({name}-{project}-{domain}). When the SDK resolves AppEndpoint(app_name="gemma4-26b") in project flytesnacks / domain development, it produces:

http://gemma4-26b-flytesnacks-development.flyte.svc.cluster.local

  • No auth is required on this path (bypasses ingress), and traffic stays in-cluster

Code Changes

  • app/config/config.go — adds NamespacedNamePrefixTemplate field to InternalAppConfig
  • app/internal/k8s/app_client.go — injects INTERNAL_APP_ENDPOINT_PATTERN in buildKService

How was this patch tested?

Verified using the app_calling_app SDK example (examples/apps/app_calling_app/app.py). After this change, hitting app2-calls-app1.../greeting/world correctly proxies through to app1 via the internal cluster URL

This is important to improve the readability of release notes.

Setup process

Screenshots

Check all the applicable boxes

  • I updated the documentation accordingly.
  • All new and existing tests passed.
  • All commits are signed-off.

Related PRs

Stack

If you do use git town to manage PR Stacks, the stack relevant to this PR
will show below. Otherwise, you can ignore this section.

Docs link

Signed-off-by: M. Adil Fayyaz <62440954+AdilFayyaz@users.noreply.github.com>
@AdilFayyaz AdilFayyaz self-assigned this Apr 30, 2026
Copilot AI review requested due to automatic review settings April 30, 2026 20:12
@AdilFayyaz AdilFayyaz added the fixed For any bug fixes label Apr 30, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to enable in-cluster Flyte app-to-app discovery by injecting an INTERNAL_APP_ENDPOINT_PATTERN environment variable into Knative Service (KService) pods at deploy time, so SDK code can resolve internal service URLs without hardcoding full cluster DNS names.

Changes:

  • Inject INTERNAL_APP_ENDPOINT_PATTERN into the first container of each deployed KService pod.
  • Add NamespacedNamePrefixTemplate to InternalAppConfig (intended to support templated internal endpoint patterns).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
app/internal/k8s/app_client.go Injects INTERNAL_APP_ENDPOINT_PATTERN into KService pod env during manifest construction.
app/config/config.go Adds a new InternalAppConfig field intended for templating the internal endpoint pattern.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +539 to +544
Name: "INTERNAL_APP_ENDPOINT_PATTERN",
Value: fmt.Sprintf("http://{app_fqdn}-%s-%s.%s.svc.cluster.local",
strings.ToLower(appID.GetProject()),
strings.ToLower(appID.GetDomain()),
ns),
})
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

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

The generated INTERNAL_APP_ENDPOINT_PATTERN does not match the actual KService naming logic for apps with mixed-case or long names. KServiceName() lowercases the full name and, when >63 chars, truncates and appends a SHA256 suffix; this pattern assumes the service name is always "{app_fqdn}-{project}-{domain}". For long app names, AppEndpoint resolution will produce a hostname that can never exist. Consider aligning the pattern/placeholder with KServiceName() semantics (e.g., have the SDK compute the KServiceName and substitute that), or enforce/reject names that would trigger hashing so the pattern remains valid.

Copilot uses AI. Check for mistakes.
Comment on lines +537 to +544
if len(podSpec.Containers) > 0 {
podSpec.Containers[0].Env = append(podSpec.Containers[0].Env, corev1.EnvVar{
Name: "INTERNAL_APP_ENDPOINT_PATTERN",
Value: fmt.Sprintf("http://{app_fqdn}-%s-%s.%s.svc.cluster.local",
strings.ToLower(appID.GetProject()),
strings.ToLower(appID.GetDomain()),
ns),
})
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

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

This unconditionally appends INTERNAL_APP_ENDPOINT_PATTERN to container env. If users previously worked around this by setting the same env var in their app spec (or via DefaultEnvVars), the resulting duplicate env var name will cause KService validation to fail. Suggest checking for an existing env var with this name and updating/overwriting it (or skipping injection if already set) instead of always appending a new entry.

Copilot uses AI. Check for mistakes.
Comment on lines +533 to +545
// Inject INTERNAL_APP_ENDPOINT_PATTERN so app code can construct internal cluster URLs
// for other apps by substituting {app_fqdn} with the target app name.
// The pattern includes project and domain as a suffix to match the KService name format
// {name}-{project}-{domain} used by KServiceName().
if len(podSpec.Containers) > 0 {
podSpec.Containers[0].Env = append(podSpec.Containers[0].Env, corev1.EnvVar{
Name: "INTERNAL_APP_ENDPOINT_PATTERN",
Value: fmt.Sprintf("http://{app_fqdn}-%s-%s.%s.svc.cluster.local",
strings.ToLower(appID.GetProject()),
strings.ToLower(appID.GetDomain()),
ns),
})
}
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

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

There are existing unit tests in this package covering Deploy/Stop/KServiceName, but no test asserting INTERNAL_APP_ENDPOINT_PATTERN injection/value. Add a test that deploys an app and verifies the env var is present and matches the expected in-cluster URL template (and ideally cover the long-name hashing edge case if that behavior is supported).

Copilot uses AI. Check for mistakes.
Comment thread app/config/config.go
Comment on lines +68 to +72
// NamespacedNamePrefixTemplate is the template for generating the INTERNAL_APP_ENDPOINT_PATTERN env var.
// Supported variables: {{ project }}, {{ domain }}, {{ org }}.
// Example: "{{ project }}-{{ domain }}-"
NamespacedNamePrefixTemplate string `json:"namespacedNamePrefixTemplate" pflag:",Template for internal app endpoint pattern (e.g., {{ project }}-{{ domain }}-)"`

Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

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

NamespacedNamePrefixTemplate is introduced with comments implying it is used to generate INTERNAL_APP_ENDPOINT_PATTERN, but there is no code path that reads this field. This makes the config misleading and risks bitrot. Either wire it into buildKService (and document the actual templating implementation), or remove/adjust the field and comment until it's supported.

Suggested change
// NamespacedNamePrefixTemplate is the template for generating the INTERNAL_APP_ENDPOINT_PATTERN env var.
// Supported variables: {{ project }}, {{ domain }}, {{ org }}.
// Example: "{{ project }}-{{ domain }}-"
NamespacedNamePrefixTemplate string `json:"namespacedNamePrefixTemplate" pflag:",Template for internal app endpoint pattern (e.g., {{ project }}-{{ domain }}-)"`

Copilot uses AI. Check for mistakes.
@AdilFayyaz AdilFayyaz requested review from kumare3 and pingsutw April 30, 2026 20:18
Comment thread app/config/config.go
// NamespacedNamePrefixTemplate is the template for generating the INTERNAL_APP_ENDPOINT_PATTERN env var.
// Supported variables: {{ project }}, {{ domain }}, {{ org }}.
// Example: "{{ project }}-{{ domain }}-"
NamespacedNamePrefixTemplate string `json:"namespacedNamePrefixTemplate" pflag:",Template for internal app endpoint pattern (e.g., {{ project }}-{{ domain }}-)"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this isnt only for the dev mode, it should work in both

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Got it. Is it supposed to be used in app_client.go? I didn’t see any files using it

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

Labels

fixed For any bug fixes flyte2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants