Contour is a Kubernetes ingress controller that serves as the control plane for Envoy. It watches Kubernetes resources, builds a configuration from them and streams it to Envoy proxies over the xDS API, so routing changes apply without restarts. It addresses two common ingress problems: configuration that reloads a proxy on every change, and the lack of safe delegation when several teams share one cluster. Contour was created at Heptio in 2017, came to VMware when it acquired Heptio in 2018, and released version 1.0 in November 2019. The CNCF Technical Oversight Committee accepted it as an incubating project on July 7, 2020.
CNCF daily · Sprint 2, day 4 · Service Proxy
At a glance
| Category | Orchestration & Management › Service Proxy |
| CNCF status | Incubating. Accepted July 7, 2020 |
| Written in | Go (control plane); the data plane is Envoy |
| License | Apache 2.0 |
| Current release line | 1.33 (1.33.4 in April 2026 included a security fix and Envoy 1.35.10); check the project’s releases page for newer versions |
| Configuration APIs | HTTPProxy (projectcontour.io/v1), Kubernetes Ingress, and Gateway API (GatewayClass, Gateway, HTTPRoute, TLSRoute, GRPCRoute) |
| Tested with | Kubernetes 1.32 to 1.34 for the 1.33 line |
Architecture
flowchart TB
CLIENT[Clients] ==>|HTTP and HTTPS| LB[Cloud load balancer]
LB ==> ENV
K8S[Kubernetes API<br/>HTTPProxy, Ingress, Gateway API] -.->|watch| EH
subgraph CT[Contour control plane]
EH[Event handler<br/>and cache] --> DAG[DAG builder<br/>routes and delegation]
DAG --> XDS[xDS gRPC server]
end
CERTGEN[certgen job<br/>xDS TLS certificates] -.->|mTLS certificates| XDS
PROV[Gateway provisioner<br/>optional] -.->|one Contour and Envoy per Gateway| ENV
XDS ==>|dynamic configuration| ENV[Envoy proxies<br/>data plane]
ENV ==>|routed requests| SVC[Backend services<br/>pods]
classDef actor fill:#eceff1,stroke:#455a64,stroke-width:1.5px,color:#1d1c1a
classDef core fill:#0f766e,stroke:#064e4a,stroke-width:2px,color:#ffffff
classDef ctrl fill:#ede7f6,stroke:#5e35b1,stroke-width:1.5px,color:#1d1c1a
classDef data fill:#e3f2fd,stroke:#1565c0,stroke-width:1.5px,color:#1d1c1a
classDef store fill:#fff3e0,stroke:#e65100,stroke-width:1.5px,color:#1d1c1a
classDef sec fill:#fce4ec,stroke:#ad1457,stroke-width:1.5px,color:#1d1c1a
classDef obs fill:#e8f5e9,stroke:#2e7d32,stroke-width:1.5px,color:#1d1c1a
class CLIENT actor
class LB,ENV,SVC data
class K8S,PROV ctrl
class EH,DAG,XDS core
class CERTGEN sec
style CT fill:#0f766e14,stroke:#0f766e,stroke-width:2px
Key: teal blocks are the project itself, blue are workloads and proxies, purple are control and configuration, amber are storage, red are security and identity, green are observability, grey are external actors. Thick arrows show the primary path, thin solid arrows other data flows, dashed arrows control, discovery and telemetry.
| Component | Responsibility |
|---|---|
| Contour controller | Watches Kubernetes resources, filters and caches them, and rebuilds the routing model after each batch of changes. |
| DAG builder | Converts resources into an intermediate graph, applying delegation and validation rules before configuration is produced. |
| xDS server | Streams listeners, routes and clusters to Envoy over gRPC, so updates take effect without a proxy restart. |
| Envoy | Handles the traffic: TLS termination, routing, load balancing, retries, timeouts and rate limiting. |
| HTTPProxy | Contour’s own resource for virtual hosts, routes, per-route policy, TCP proxying and cross-namespace delegation. |
| Gateway provisioner | Optional component that creates a dedicated Contour and Envoy pair for each Gateway resource. |
Design principle. Contour separates control plane and data plane and keeps the control plane small. It translates Kubernetes resources into Envoy configuration and leaves traffic handling to Envoy, which keeps the proxy in the data path simple and lets changes apply continuously. Delegation rules let a platform team own the root domain while application teams manage only their own routes.
Production reference design
A typical deployment on EKS, GKE, AKS or on-premises Kubernetes runs Contour as a Deployment with two or more replicas and Envoy either as a DaemonSet on dedicated ingress nodes or as an autoscaled Deployment behind a cloud load balancer.
- Install Contour from the official manifest or Helm chart, pinning the version, and verify the pods:
For production, render the manifests or chart at a fixed version and keep them in Git rather than applying the quickstart URL directly.kubectl apply -f https://projectcontour.io/quickstart/contour.yaml kubectl get pods -n projectcontour - Choose a topology. The default runs Envoy as a DaemonSet with host networking for low latency; a centralized Deployment with a horizontal autoscaler suits clouds where a load balancer fronts a stable set of proxy pods.
- Define a root HTTPProxy for the shared domain, with TLS from cert-manager, and delegate path prefixes to team namespaces:
apiVersion: projectcontour.io/v1 kind: HTTPProxy metadata: name: shop-root namespace: platform spec: virtualhost: fqdn: shop.example.com tls: secretName: shop-example-com-tls includes: - name: orders namespace: orders conditions: - prefix: /api/orders --- apiVersion: projectcontour.io/v1 kind: HTTPProxy metadata: name: orders namespace: orders spec: routes: - services: - name: orders-v1 port: 8080 weight: 90 - name: orders-v2 port: 8080 weight: 10 timeoutPolicy: response: 10s retryPolicy: count: 2 perTryTimeout: 3s - Share certificates safely with
TLSCertificateDelegationso a wildcard certificate in one namespace can be used by named namespaces only. - Add global controls through the
ContourConfigurationresource: access logging, external authorization, rate limiting through a global service and Envoy settings. - Monitor with Contour’s and Envoy’s Prometheus metrics, and alert on xDS connection errors, 5xx rates and configuration rejections.
Typical production uses are shared ingress for multi-team clusters, canary releases through weighted services, TLS termination with automated certificates, and gradual migration from Ingress to Gateway API.
Operational considerations
- Scaling: scale Envoy with traffic (DaemonSet on ingress nodes, or a Deployment with an autoscaler) and run at least two Contour replicas; Contour itself uses little CPU unless the number of routes is very large.
- High availability: Envoy keeps serving with its last configuration if Contour is briefly unavailable, but run multiple Contour replicas and spread pods across zones. Use graceful shutdown settings so connections drain during Envoy rollouts.
- Security: restrict which namespaces may create root HTTPProxies and which may use delegated certificates, keep the xDS channel secured with the certgen certificates, and track security advisories; the 1.33.4 release fixed a Lua code injection issue in the cookie rewriting feature.
- Cost and sizing: a cloud load balancer per environment is the main cost; centralized Envoy pods are inexpensive compared with per-application ingress.
- Common pitfalls: upgrading Contour without matching the required Envoy version, leaving the CRDs behind after upgrades, relying on HTTPProxy features that Gateway API cannot express when planning a migration, and conflicting definitions of the same host across Ingress and HTTPProxy.
Adoption
The CNCF incubation announcement named Adobe, Kinvolk, Kintone, PhishLabs and Replicated among Contour’s users; Adobe uses it as the ingress controller of its multi-tenant Project Ethos platform. The project’s adopters page lists Knative, VMware, Flyte, Gojek, DaoCloud, SnappCloud and Bugfender. Knative uses Contour as one of its supported networking layers.
Alternatives
| Solution | Model | Best suited to |
|---|---|---|
| Envoy Gateway (Envoy project, CNCF Graduated) | Gateway API implementation on Envoy | Teams choosing the Envoy project’s own Gateway API controller |
| Kgateway (CNCF Sandbox) | Gateway API control plane on Envoy | Teams moving off ingress-nginx and adopting Gateway API |
| ingress-nginx | NGINX-based ingress controller, retired in March 2026 | Existing installations that need a planned migration |
| Traefik, HAProxy Ingress, Kong | Other ingress and gateway products | Teams that prefer those feature sets |
| Istio ingress gateway (CNCF Graduated) | Envoy gateway within a mesh | Clusters already running a service mesh |
Strengths and limitations
| Strengths | Limitations |
|---|---|
| Envoy data plane with dynamic updates and no reloads | Smaller community than the largest ingress controllers |
| HTTPProxy delegation suits multi-team clusters | HTTPProxy is Contour-specific, so routes are not portable |
| Supports Ingress, HTTPProxy and Gateway API together | Gateway API coverage depends on the Contour release |
| Small control plane, clear separation from the data plane | Envoy and Contour versions must be kept in step |
| Vendor-neutral CNCF project, in use at Adobe and others | Advanced traffic policy needs Envoy knowledge |
Recommendation
Trial Contour for clusters shared by several teams that want an Envoy-based ingress with clear delegation rules, and for teams that value its small control plane. Use Gateway API resources where they cover your needs to keep routes portable, and keep HTTPProxy for delegation and policy that the standard API lacks. Pin Contour and Envoy versions together and read the security advisories at each upgrade. Teams standardising entirely on Gateway API should compare Envoy Gateway and kgateway as well.
References: CNCF: TOC accepts Contour as an incubating project · Contour documentation · Contour adopters · Contour v1.33.4 release · Contour on GitHub · CNCF project page