Contour Ingress Controller Setup
Guide for installing and configuring Contour as the ingress controller for Kubernetes.
Table of Contents
Overview
Contour is an open source Kubernetes ingress controller that:
- Provides high-performance reverse proxy capabilities
- Supports dynamic configuration updates
- Integrates with cert-manager for TLS
- Uses Envoy as the data plane
Prerequisites
Requirements
- Kubernetes cluster 1.19+
- kubectl access to cluster
- LoadBalancer service support (or NodePort)
Network Requirements
- External IP allocation capability
- Port 80/443 access
Installation
Deploy Contour
Install Contour using the quickstart manifest:
kubectl apply -f https://projectcontour.io/quickstart/contour.yaml
Wait for deployment to complete:
kubectl get pods -n projectcontour
Verify Installation
Check that Contour and Envoy are running:
# Check deployments
kubectl get deployments -n projectcontour
# Check services
kubectl get svc -n projectcontour
Expected output should show:
- contour deployment (2 replicas)
- envoy daemonset
- envoy LoadBalancer service with external IP
Configuration
Basic HTTPProxy Example
Create a simple HTTPProxy resource:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: basic-httpproxy
namespace: default
spec:
virtualhost:
fqdn: app.example.com
routes:
- conditions:
- prefix: /
services:
- name: my-service
port: 80
TLS Configuration
Configure HTTPS with cert-manager:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: secure-httpproxy
namespace: default
spec:
virtualhost:
fqdn: app.example.com
tls:
secretName: app-tls-cert
routes:
- conditions:
- prefix: /
services:
- name: my-service
port: 80
Testing
DNS Test
Test DNS resolution for your ingress:
# Get the LoadBalancer IP
INGRESS_IP=$(kubectl get svc -n projectcontour envoy -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Ingress IP: $INGRESS_IP"
# Test with curl
curl -H "Host: app.example.com" http://$INGRESS_IP
Deploy Test Application
Create a test deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
containers:
- name: httpbin
image: kennethreitz/httpbin
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
spec:
ports:
- port: 80
targetPort: 80
selector:
app: httpbin
Advanced Configuration
Rate Limiting
Add rate limiting to an HTTPProxy:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: rate-limited-proxy
spec:
virtualhost:
fqdn: api.example.com
rateLimitPolicy:
local:
requests: 100
unit: second
routes:
- services:
- name: api-service
port: 8080
Path-based Routing
Configure multiple services on different paths:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: multi-path-proxy
spec:
virtualhost:
fqdn: app.example.com
routes:
- conditions:
- prefix: /api
services:
- name: api-service
port: 8080
- conditions:
- prefix: /
services:
- name: frontend-service
port: 80
Troubleshooting
Common Issues
Issue: No external IP assigned
Check LoadBalancer service:
kubectl describe svc -n projectcontour envoy
Issue: 404 errors
Verify HTTPProxy configuration:
kubectl get httpproxy
kubectl describe httpproxy <name>
Debug Commands
# Check Contour logs
kubectl logs -n projectcontour deployment/contour
# Check Envoy logs
kubectl logs -n projectcontour daemonset/envoy
# View HTTPProxy status
kubectl get httpproxy -A
Best Practices
- Use HTTPProxy CRD instead of Ingress resources
- Configure health checks for backend services
- Implement rate limiting for public endpoints
- Use TLS termination at the edge
- Monitor Envoy metrics
References
Last Updated: 2024 Part of the Homelab Documentation Series