Skip to main content
Version: 1.40

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:

DriverDescriptionDefaultPurpose
nginxUses Okteto's built-in nginx ingress controller✅ YesStandard installations with Okteto-managed routing
istioUses Istio's VirtualService for header-based routingNoEnvironments with existing Istio service mesh
Important Distinction

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

  1. When a developer deploys with divert configuration, Okteto creates ingress rules that inject the baggage header
  2. Requests through the developer's endpoint automatically include baggage: okteto-divert=<namespace>
  3. The nginx ingress controller routes requests to the appropriate namespace based on this header
  4. Linkerd's service mesh handles service-to-service routing based on the propagated baggage header
  5. 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
Required Component

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.

warning

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)

  1. When a developer deploys with divert and driver: istio, Okteto:
    • Creates/modifies VirtualServices to route based on the baggage header
    • Clones the specified host VirtualServices to the developer namespace for header injection
  2. Requests through the developer's endpoint include the baggage header
  3. Istio's routing rules direct traffic to the appropriate namespace
  4. 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"
tip

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

  1. 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
  2. Verify header propagation: Test with curl -H "baggage: okteto-divert=<namespace>" to confirm routing works

  3. Check namespace labels: For Istio, verify istio-injection: enabled label exists

    kubectl get namespace <namespace> -o yaml | grep -A 5 labels
  4. Review ingress configuration: Ensure ingress rules are being created correctly

    kubectl get ingress --all-namespaces
    kubectl describe ingress <ingress-name> -n <namespace>
  5. Check Okteto configuration:

    kubectl get configmap okteto-config -n okteto -o yaml
    # Verify driver settings

VirtualServices Not Appearing (Istio)

  1. Verify virtualServices.enabled: true in Helm values

    helm get values okteto -n okteto
  2. Check that Istio CRDs are installed

    kubectl get crd | grep istio
  3. Ensure the VirtualService is in a namespace managed by Okteto

    kubectl get virtualservices --all-namespaces
  4. Check Okteto API logs for VirtualService creation:

    kubectl logs -n okteto deployment/okteto-api | grep -i virtualservice

Cross-Namespace Communication Failing

  1. Check network policies allow the traffic (see Network Policies section)

    kubectl get networkpolicies --all-namespaces
    kubectl describe networkpolicy <policy-name> -n <namespace>
  2. Verify DNS resolution works across namespaces

    kubectl run dns-test --image=busybox --rm -it -- \
    nslookup service-name.namespace.svc.cluster.local
  3. 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
  4. Check if service mesh is blocking traffic:

    # For Linkerd
    linkerd viz tap deployment/<deployment> -n <namespace>

    # For Istio
    istioctl proxy-status

Common Configuration Issues

  1. Linkerd not installed: Required for nginx driver

    linkerd version
    # Should show both client and server versions
  2. 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
  3. Network policies too restrictive: Blocking cross-namespace traffic

    # Temporarily disable to test
    kubectl delete networkpolicy <policy-name> -n <namespace>
  4. 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:

  1. 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
  2. Enable debug logging in Okteto Helm values:

    api:
    logLevel: debug
  3. Consult related documentation:

Next Steps