Architecture
Big picture
KServe has two planes. The control plane is the Go kserve-controller-manager, a controller-runtime binary that reconciles CRDs into ordinary Kubernetes objects. Its main() lives at cmd/manager/main.go:99, builds a Manager, registers the InferenceServiceReconciler and siblings, and serves the admission webhooks. It runs as a single leader-elected process (LeaderLockName = "kserve-controller-manager-leader-lock", cmd/manager/main.go:56).
The data plane is the set of pods that actually serve inference: a Python KServe runtime or a third-party server such as Triton or TorchServe. Each serving pod gets a storage-initializer init container that pulls the model into a shared volume, plus optional agent, router, batcher, and logger sidecars.
Components
Control plane: kserve-controller-manager
Reconciles the core CRDs into runtime objects. The InferenceServiceReconciler.Reconcile loop is at pkg/controller/v1beta1/inferenceservice/controller.go:121. It owns deployment-mode resolution, finalizers, component reconcilers, ingress, model config, and status. Other binaries live under cmd/: agent, router, llmisvc, localmodel, and localmodelnode.
Core CRDs
InferenceService(isvc): the main API;v1beta1is the storage version (pkg/apis/serving/v1beta1/inference_service.go:147).Predictoris required;TransformerandExplainerare optional (inference_service.go:24-35).ServingRuntime/ClusterServingRuntime(pkg/apis/serving/v1alpha1/servingruntime_types.go:222,:248): pod templates per model format, with auto-selection.InferenceGraph(pkg/apis/serving/v1alpha1/inference_graph.go:35): routing and ensembles across models as a DAG.LLMInferenceService(pkg/apis/serving/v1alpha1/llm_inference_service_types.go:60): the generative-AI resource.
Data plane: serving pods and sidecars
The Python servers under python/kserve/kserve speak the V1 and V2 (Open Inference Protocol) APIs. The storage-initializer init container, agent, router, batcher, and logger attach to the serving pod to handle model download, routing, micro-batching, and request logging.
How a request flows
A kubectl apply -f isvc.yaml reconciles to a running model pod:
- Entry.
InferenceServiceReconciler.Reconcilefetches theisvc; a NotFound returns early for finalizer-driven GC (controller.go:121). - Config and mode. It reads the
inferenceservice-configConfigMap viaGetInferenceServiceConfigMap(controller.go:133) and resolves the deployment mode withGetDeploymentMode(controller.go:154). - Finalizers. If
inferenceservice.finalizersis absent it is added via a merge patch (controller.go:176-187); aDeletionTimestamptriggers cleanup then finalizer removal. - Components. For
Standard/Knativeit appendscomponents.NewPredictorand, if present in the spec, Transformer and Explainer, then runs each reconciler (controller.go:273). - Predictor branch.
Predictor.Reconcile(pkg/controller/v1beta1/inferenceservice/components/predictor.go:85) branches on mode:StandardcallsreconcileRawDeploymentthenraw.NewRawKubeReconcilerfor Deployment + Service + HPA (predictor.go:204,:771);Knativecallsknative.NewKsvcReconcilerfor a Knative Service (predictor.go:836). - Ingress. A factory builds a mode-specific ingress reconciler via
CreateIngressReconciler(controller.go:362). - Status.
modelconfig.NewModelConfigReconciler(...).Reconcileruns (controller.go:394), thenupdateStatuswrites URL, conditions, and components (controller.go:402).
Key design decisions
- Storage-initializer injection by webhook. The model is not baked into the server image; a mutating webhook adds an init container that downloads from
storageUriinto a sharedemptyDirat/mnt/models(pkg/webhook/admission/pod/storage_initializer_injector.go:441,:483). One generic runtime image can serve any model. - Runtime auto-selection. When an
isvcnames a model format, theServingRuntimewithAutoSelect=trueand the highestPriorityis chosen (pkg/apis/serving/v1alpha1/servingruntime_types.go:31). Users need not pin a runtime image. - Default mode is
Standard, plain Kubernetes (pkg/constants/constants.go:554). Knative is opt-in for scale-to-zero and canary, reversing the original Knative-required assumption. - Status uses Knative's condition duck type.
InferenceServiceStatusinlinesduckv1.Status(pkg/apis/serving/v1beta1/inference_service_status.go:42), a legacy of KFServing's Knative roots;PropagateCrossComponentStatusaggregates readiness in Knative mode (controller.go:339-340).
Extension points
ServingRuntime/ClusterServingRuntimefor new model formats and servers (servingruntime_types.go:222,:248).- CRDs as the public API:
InferenceService,InferenceGraph,TrainedModel,LLMInferenceService. - Admission webhooks (mutating and validating) registered on the manager's webhook server.
- The data-plane V1/V2 protocol contract, which any server image can implement (
python/kserve/kserve).