Configure Divert
Divert enables developers to create lightweight development environments that deploy only the services they're actively working on, while routing traffic to shared services for everything else. This section covers the administrative setup required to enable Divert in your Okteto installation.
Divert Drivers
Okteto supports two drivers for Divert routing:
| Driver | Description | Default | Purpose |
|---|---|---|---|
| nginx | Uses Okteto's built-in nginx ingress controller | ✅ Yes | Standard installations with Okteto-managed routing |
| istio | Uses Istio's VirtualService for header-based routing | No | Environments with existing Istio service mesh |
Istio and Linkerd serve different purposes:
- Istio is a divert driver - an alternative to the nginx driver for environments already using Istio
- Linkerd is required for the nginx driver - it provides service mesh capabilities for service-to-service routing
- You cannot use both Istio driver and Linkerd together
- Choose one: nginx driver (requires Linkerd) OR istio driver
nginx Driver (Default)
The nginx driver is enabled by default in Okteto installations. It uses the okteto-nginx ingress controller to inject and route based on the baggage: okteto-divert=<namespace> header.
Requirements
- Standard Okteto installation (no additional configuration needed)
- Required: Linkerd service mesh for service-to-service routing
How It Works
- When a developer deploys with
divertconfiguration, Okteto creates ingress rules that inject the baggage header - Requests through the developer's endpoint automatically include
baggage: okteto-divert=<namespace> - The nginx ingress controller routes requests to the appropriate namespace based on this header
- Linkerd's service mesh handles service-to-service routing based on the propagated baggage header
- Applications must propagate the baggage header for routing to work across service boundaries
Linkerd Integration (Required)
For service-to-service routing with the nginx driver, Linkerd must be installed. Linkerd provides:
- Header-based routing at the service mesh level for inter-service communication
- Automatic mTLS between services
- Advanced traffic management and observability
- Improved reliability with retries and circuit breaking
While ingress-level routing works without Linkerd, service-to-service routing requires Linkerd to be installed. Without Linkerd, only external ingress traffic can be diverted, not internal service-to-service calls.
See Linkerd Installation for setup instructions.
istio Driver
The istio driver is designed for environments that already use Istio for service mesh. It leverages Istio's VirtualService for header-based routing without requiring additional components.
The istio driver is for environments that have already installed Istio and prefer Istio-native routing. If you don't have Istio, use the nginx driver instead. Do not install Istio just for Divert - the nginx driver is simpler and sufficient.
Requirements
- Okteto configured with Istio ingress mode
- Istio service mesh installed in the cluster
- Istio sidecar injection enabled for Okteto-managed namespaces
Helm Configuration
To enable Istio support, add the following to your Okteto Helm values:
# Disable the default okteto-nginx since we're using Istio
okteto-nginx:
enabled: false
# Enable VirtualService endpoints in the UI
virtualServices:
enabled: true
# Enable Istio sidecar injection for all Okteto namespaces
namespace:
labels:
istio-injection: enabled
Istio Installation
See the Istio Divert Sample for detailed installation instructions, including:
- Installing Istio base, istiod, and ingress gateway
- Configuring the Istio ingress for Okteto
- Setting up SSL/TLS certificates
How It Works (Istio)
- When a developer deploys with
divertanddriver: istio, Okteto:- Creates/modifies VirtualServices to route based on the baggage header
- Clones the specified host VirtualServices to the developer namespace for header injection
- Requests through the developer's endpoint include the baggage header
- Istio's routing rules direct traffic to the appropriate namespace
- The Istio sidecar propagates headers through the service mesh
Developer Configuration
Once an administrator has configured the Divert infrastructure, developers use the divert section in their okteto.yaml:
nginx Driver Example
deploy:
commands:
- helm upgrade --install myservice chart
divert:
driver: nginx # Optional, this is the default
namespace: staging
istio Driver Example
deploy:
commands:
- helm upgrade --install myservice chart
divert:
driver: istio
virtualServices:
- name: frontend-vs
namespace: staging
routes:
- main-route
hosts:
- virtualService: frontend
namespace: staging
Header Format
Both drivers use the same header format (unified in Okteto 1.31+):
baggage: okteto-divert=<namespace>
For backward compatibility with older nginx driver installations, the header baggage.okteto-divert is also supported but deprecated.
Network Policies
If you have network policies enabled in your Okteto installation, ensure they allow cross-namespace communication for Divert to function properly.
Configuring Network Policies
If using networkPolicies.enabled: true in your Helm values, add rules to allow:
- Cross-namespace communication between developer namespaces and shared namespaces
- Traffic from the ingress controller to all namespaces
Example configuration in your Helm values:
networkPolicies:
enabled: true
ingress:
- from:
- namespaceSelector:
matchLabels:
dev.okteto.com/okteto-managed: "true"
For complete network policy configuration options, see the Helm Configuration reference.
Troubleshooting
This section covers admin-level troubleshooting for Divert configuration. For developer troubleshooting, see Using Divert.
Verify Sidecar Injection
Check namespace annotation (nginx driver with Linkerd):
kubectl get namespace <namespace> -o jsonpath='{.metadata.annotations}'
Should include: linkerd.io/inject: enabled
Check Istio sidecar injection (istio driver):
kubectl get namespace <namespace> -o jsonpath='{.metadata.labels}'
Should include: istio-injection: enabled
Verify sidecars are running:
# For Linkerd
kubectl get pods -n <namespace> -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}'
# Should show linkerd-proxy or istio-proxy alongside application containers
Check Ingress Controller Status
Verify ingress controller is running (nginx driver):
kubectl get deployments -n okteto
# Should see okteto-nginx deployment in Ready state
kubectl get pods -n okteto -l app=okteto-nginx
# All pods should be Running
Check ingress controller logs:
kubectl logs -n okteto deployment/okteto-nginx -f
For Istio driver, check Istio ingress gateway:
kubectl get pods -n istio-system -l app=istio-ingressgateway
kubectl logs -n istio-system deployment/istio-ingressgateway -f
Verify Linkerd Deployment (nginx driver)
Check Linkerd control plane health:
# Using Linkerd CLI
linkerd check
# Manual verification
kubectl get deployments -n linkerd
# Should show: linkerd-destination, linkerd-identity, linkerd-proxy-injector
kubectl get pods -n linkerd
# All pods should be Running
Verify Linkerd viz extension (for monitoring):
linkerd viz check
kubectl get deployments -n linkerd-viz
Check ServiceProfiles (if configured):
kubectl get serviceprofiles --all-namespaces
Header Propagation Testing
Test ingress header injection:
# Create a test deployment with divert
curl -v https://test-app-namespace.okteto.example.com 2>&1 | grep -i baggage
# Should see: baggage: okteto-divert=<namespace>
Verify header format:
# Correct format
baggage: okteto-divert=alice-feature
# Incorrect formats
baggage.okteto-divert=alice-feature # Wrong separator
okteto-divert: alice-feature # Wrong header name
Test service-to-service routing:
# Deploy test pods in two namespaces
kubectl run test-client -n dev --image=curlimages/curl --command -- sleep 3600
kubectl run test-server -n staging --image=hashicorp/http-echo --command -- /http-echo -listen=:5678 -text="shared"
# Test routing with header
kubectl exec -it test-client -n dev -- \
curl -H "baggage: okteto-divert=dev" \
http://test-server.staging.svc.cluster.local:5678
Divert Not Working
-
Check driver configuration: Ensure the correct driver is installed and configured
# For nginx driver
kubectl get deployment okteto-nginx -n okteto
# For istio driver
kubectl get deployment istiod -n istio-system -
Verify header propagation: Test with
curl -H "baggage: okteto-divert=<namespace>"to confirm routing works -
Check namespace labels: For Istio, verify
istio-injection: enabledlabel existskubectl get namespace <namespace> -o yaml | grep -A 5 labels -
Review ingress configuration: Ensure ingress rules are being created correctly
kubectl get ingress --all-namespaces
kubectl describe ingress <ingress-name> -n <namespace> -
Check Okteto configuration:
kubectl get configmap okteto-config -n okteto -o yaml
# Verify driver settings
VirtualServices Not Appearing (Istio)
-
Verify
virtualServices.enabled: truein Helm valueshelm get values okteto -n okteto -
Check that Istio CRDs are installed
kubectl get crd | grep istio -
Ensure the VirtualService is in a namespace managed by Okteto
kubectl get virtualservices --all-namespaces -
Check Okteto API logs for VirtualService creation:
kubectl logs -n okteto deployment/okteto-api | grep -i virtualservice
Cross-Namespace Communication Failing
-
Check network policies allow the traffic (see Network Policies section)
kubectl get networkpolicies --all-namespaces
kubectl describe networkpolicy <policy-name> -n <namespace> -
Verify DNS resolution works across namespaces
kubectl run dns-test --image=busybox --rm -it -- \
nslookup service-name.namespace.svc.cluster.local -
Test direct pod-to-pod communication to isolate the issue
# Get pod IPs
kubectl get pods -n namespace-a -o wide
kubectl get pods -n namespace-b -o wide
# Test connectivity
kubectl exec -it pod-in-namespace-a -- nc -zv <pod-ip-in-namespace-b> 8080 -
Check if service mesh is blocking traffic:
# For Linkerd
linkerd viz tap deployment/<deployment> -n <namespace>
# For Istio
istioctl proxy-status
Common Configuration Issues
-
Linkerd not installed: Required for nginx driver
linkerd version
# Should show both client and server versions -
Wrong driver in okteto.yaml: Manifest specifies different driver than cluster
# Check what user specified
cat okteto.yaml | grep -A 2 divert
# Check cluster configuration
kubectl get configmap okteto-config -n okteto -o yaml -
Network policies too restrictive: Blocking cross-namespace traffic
# Temporarily disable to test
kubectl delete networkpolicy <policy-name> -n <namespace> -
Istio and Linkerd both installed: Cannot use both together
kubectl get namespaces -o custom-columns=NAME:.metadata.name,ISTIO:.metadata.labels.istio-injection,LINKERD:.metadata.annotations.linkerd\\.io/inject
Getting Help
For persistent issues:
-
Collect diagnostic information:
kubectl logs -n okteto deployment/okteto-api > okteto-api.log
kubectl logs -n okteto deployment/okteto-nginx > okteto-nginx.log
linkerd check > linkerd-check.log # If using nginx driver
kubectl get all --all-namespaces > cluster-state.txt -
Enable debug logging in Okteto Helm values:
api:
logLevel: debug -
Consult related documentation:
- Linkerd Installation - Linkerd-specific issues
- Using Divert - Developer-side troubleshooting
- Divert Core Concepts - Architecture and flow troubleshooting
Next Steps
- Linkerd Installation - Enhanced routing with Linkerd (nginx driver only)
- Using Divert - Developer implementation guide
- Divert Tutorial - Getting started guide for developers
- Core Concepts - Understanding Divert architecture