Application Services
Flyte Application Services enable the deployment and management of long-running services and applications. Built on top of Knative, this system provides automated scaling (including scaling to zero), public ingress management, and integrated log streaming.
The architecture is split into a control plane (AppService) and a data plane (InternalAppService). The control plane handles request proxying and status caching, while the data plane interacts directly with Kubernetes via the AppK8sClient to manage Knative Service (KService) resources.
Deploying an Application
To deploy an application, you define a flyteapp.App with a container payload. Flyte transforms this specification into a Knative Service manifest.
app := &flyteapp.App{
Metadata: &flyteapp.Meta{
Id: &flyteapp.Identifier{
Project: "my-project",
Domain: "development",
Name: "web-server",
},
},
Spec: &flyteapp.Spec{
AppPayload: &flyteapp.Spec_Container{
Container: &flytecoreapp.Container{
Image: "nginx:latest",
Ports: []*flytecoreapp.ContainerPort{
{ContainerPort: 80, Name: "http"},
},
},
},
Autoscaling: &flyteapp.Autoscaling{
Replicas: &flyteapp.Autoscaling_ReplicaRange{
Min: 1,
Max: 10,
},
},
},
}
Internally, AppK8sClient.buildKService (in app/internal/k8s/app_client.go) maps this spec to a servingv1.Service. It handles:
- Naming: Generates a deterministic name using
{name}-{project}-{domain}. If this exceeds the 63-character Kubernetes limit, it appends a SHA256 suffix to ensure uniqueness while staying within the limit. - Autoscaling: Maps the
Autoscalingspec to Knative annotations likeautoscaling.knative.dev/min-scaleandautoscaling.knative.dev/max-scale. - Timeouts: Applies request timeouts to the
RevisionSpec, capped by theinternalApps.maxRequestTimeoutconfiguration.
Internal Communication
Every deployed app is injected with an INTERNAL_APP_ENDPOINT_PATTERN environment variable. This allows application code to discover and connect to other apps within the same cluster using a predictable URL format:
http://{app_fqdn}-{{ project }}-{{ domain }}.flyte.svc.cluster.local
Lifecycle Management
Flyte supports two ways to stop an application: scaling to zero (Stop) and full removal (Delete).
Stopping (Scale to Zero)
When you set an app's DesiredState to STOPPED, the AppK8sClient.Stop method patches the KService.
- It sets
autoscaling.knative.dev/min-scaleandinitial-scaleto0. - It applies the
networking.knative.dev/visibility: cluster-locallabel, which removes the app from the public ingress gateway. - It deletes the
LatestReadyRevisionto force the immediate termination of existing pods, rather than waiting for the standard Knative scale-down window.
Deleting
The Delete operation removes the KService resource entirely from Kubernetes. Unlike Stop, this removes all configuration and history for the app; it must be re-created from scratch to run again.
Networking and Ingress
Flyte manages public access to applications through Kourier (the default Knative ingress provider).
The public URL is generated deterministically by AppK8sClient.PublicIngress based on the internalApps.baseDomain and internalApps.scheme configurations. For an app named myapp in project p1 and domain d1, the URL typically follows the pattern:
https://myapp-p1-d1.example.com
Observability and Logs
Flyte provides a streaming log service specifically tuned for Knative-based applications.
Log Streaming
The InternalAppLogsService (in app/internal/service/app_logs_service.go) allows you to tail logs for an entire app or a specific replica (pod). It resolves the app identifier to the current set of active pods and initiates a stream for each.
Sidecar Filtering
Knative injects a queue-proxy sidecar into every pod to manage request queuing and metrics. To ensure you only see relevant application data, the K8sAppLogStreamer (in app/internal/service/app_logs_streamer.go) explicitly filters out this container:
// pickUserContainer returns the primary user container, skipping Knative sidecars.
func pickUserContainer(pod *corev1.Pod) string {
for _, c := range pod.Spec.Containers {
if c.Name != "queue-proxy" {
return c.Name
}
}
return ""
}
Configuration
Application services are configured via the internalApps and apps sections in the Flyte configuration.
| Setting | Default | Description |
|---|---|---|
internalApps.defaultRequestTimeout | 300s | Timeout applied if not specified in the app spec. |
internalApps.maxRequestTimeout | 3600s | Hard cap on the allowed request timeout. |
internalApps.baseDomain | (empty) | The root domain for public ingress URLs. |
internalApps.namespacedNameSuffixTemplate | {{ project }}-{{ domain }} | Template for internal cluster DNS suffixes. |
apps.cacheTtl | 30s | TTL for the control plane's in-memory status cache. |
All applications are deployed into a dedicated Kubernetes namespace defined by the AppNamespace constant, which defaults to flyte.