The Vespa Operator automatically provisions Kubernetes Service resources to enable external access for feeding and querying data.
This behavior is controlled by the VespaSet Custom Resource configuration.
Load balancers are provisioned exclusively for Container clusters. Content clusters communicate internally
and do not require external load balancing services. The type of service provisioned is determined by the
spec.ingress.endpointType field in the VespaSet.
To ensure zero-downtime deployments, traffic routing is managed dynamically using Kubernetes labels.
The created Services select backend Pods with the selector vespa.ai/tenant-lb: backend.
The operator automatically adds this label to Container Pods depending on whether the Pod is available
to serve as a backend, and removes it when the Pod is not.
Through its own orchestration policy, the operator ensures high availability by rotating Pods in and out of the backend set accordingly. During a rolling upgrade, the label is removed from the terminating Pod(s) before they are shut down, providing a window for the remaining traffic to drain before the Pod is upgraded.
Note: The Service exposes port 80 (plaintext) and 443 (TLS) externally, mapping them to the container's port 4443.
The endpoint type is configured through spec.ingress.endpointType in the VespaSet:
ingress: endpointType: LOAD_BALANCER
| Endpoint Type | Kubernetes Service Type | Use Case |
|---|---|---|
LOAD_BALANCER |
LoadBalancer |
Provision a cloud-native load balancer. Only the AWS variant — the Network Load Balancer (NLB) —
is supported, making this the recommended configuration for production deployments on AWS (EKS).
The ConfigServer automatically applies the annotation
service.beta.kubernetes.io/aws-load-balancer-internal: "true", provisioning an
internal NLB accessible only within the VPC where the EKS cluster nodes reside.
|
CLUSTER_IP |
ClusterIP |
A stable internal endpoint fronting the Container Pods, restricted to within the Kubernetes cluster.
It provides an internal IP and DNS name (e.g., lb-default.vespa.svc.cluster.local)
for feeding and querying, but assigns no external IP. Ideal when the clients (e.g., front-end
applications or ingestion services) run inside the same Kubernetes cluster as Vespa.
|
NONE |
N/A |
No external access layer is provisioned. Use this if you intend to manually define
Ingress resources, use a Service Mesh (like Istio or Linkerd), or have complex
networking requirements not covered by the standard types.
|
The endpointType can be changed on a running deployment. When it changes, the operator reconciles
the external access layer by deleting the Service of the old type and creating a Service of the new type.
Expect a brief window during the switch where the endpoint is unavailable, and note that the endpoint's
IP address and, for LOAD_BALANCER, its external hostname will change.
The operator always provisions an internal
ingress Service for the ConfigServers: a ClusterIP Service named cfg-internal,
exposing the ConfigServer HTTP port (19071). It is not affected by spec.ingress.endpointType.
A ClusterIP Service assigns a virtual IP address and cluster-internal DNS name that is only
reachable from within the Kubernetes cluster. Traffic sent to this IP is transparently distributed
across the Pods matching the Service's selector, either randomly or via round-robin.
The Service selects all ConfigServer Pods by label, providing a single stable endpoint that load-balances HTTP API requests across the ConfigServer quorum. Clients make requests through this endpoint instead of targeting individual Pods, so requests keep working when a ConfigServer Pod is restarted or recreated. This provides high availability and load distribution for the ConfigServer HTTP APIs, e.g. for deploying application packages.
The following ports are exposed on the Vespa Pods, per Pod type.
| Type | Name | Port | Purpose |
|---|---|---|---|
| ConfigServer | config |
19071 | The ConfigServer HTTP API, e.g. for deploying application packages. Targeted by the cfg-internal Service. |
| ConfigServer | config-rpc |
19070 | The ConfigServer RPC port, used to distribute configuration to the Vespa services. |
| Container | status |
4444 | Status endpoint used by the readiness probe. |
| Container | http-internal |
8080 | The internal data plane for queries and feeding from within the Kubernetes cluster. |
| Container | http-external |
4443 | The external data plane (TLS). The external access layer maps ports 80 and 443 to this port. |
| Container | metrics |
19092 | The state and metrics API, e.g. for Prometheus scraping — see Configure Monitoring. |
| Content | http-internal |
19102 | The state and health API, used by the readiness probe. |
| Content | metrics |
19092 | The state and metrics API, e.g. for Prometheus scraping. |
| ClusterControllers | http-internal |
19050 | The cluster-controller state API, used by the readiness probe. |
| ClusterControllers | metrics |
19092 | The state and metrics API, e.g. for Prometheus scraping. |