Istio Installation for Divert
This guide is for Okteto administrators setting up Istio in the cluster. Developers do not need to install anything - once Istio is configured, Divert works transparently for all developers.
This guide covers installing Istio and configuring Okteto to use the Istio driver for Divert. The Istio driver uses Istio's VirtualService for header-based routing and is designed for environments that already use Istio or prefer Istio-native service mesh capabilities.
This installation is only required when using the istio driver. If you're using the default nginx driver, do not install Istio - see Configure Divert for the distinction between drivers.
Prerequisites
- Kubernetes cluster with Okteto installed
kubectlconfigured with cluster admin accesshelmv3.x installed- Administrator/operator access (this is a one-time cluster setup)
Configure Okteto for Istio
Before installing Istio, update your Okteto Helm values to disable the built-in nginx ingress and enable Istio integration:
# Disable the default okteto-nginx since we will enable Istio ingress mode
okteto-nginx:
enabled: false
# Enable VirtualService endpoints in the Okteto UI
virtualServices:
enabled: true
# Inject the Istio sidecar injection label on every namespace managed by Okteto
namespace:
labels:
istio-injection: enabled
okteto-nginx: enabled: false— Disables the built-in nginx ingress controller so Istio can handle ingressvirtualServices: enabled: true— Displays VirtualService endpoints in the Okteto UInamespace: labels: istio-injection: enabled— Instructs Istio to inject sidecars into every pod in Okteto-managed namespaces, ensuring all traffic goes through the Istio mesh
Apply the changes:
helm upgrade okteto okteto/okteto -f values.yaml
Install Istio
Step 1: Add the Istio Helm Repository
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update
Step 2: Set Your Domain
Export the OKTETO_DOMAIN environment variable with the subdomain Helm value of your Okteto instance:
export OKTETO_DOMAIN=okteto.example.com
Step 3: Install Istio Base (CRDs)
helm install --namespace istio-system --create-namespace istio-base istio/base --wait
Step 4: Prepare the Istio Ingress Namespace
kubectl create namespace istio-ingress
kubectl label namespace istio-ingress istio-injection=enabled
Step 5: Install Istiod (Control Plane)
Create a istiod-helm-values.yaml file with the following configuration:
meshConfig:
outboundTrafficPolicy:
mode: "ALLOW_ANY" # Dev configuration only — not recommended for production
enableTracing: false
defaultConfig:
holdApplicationUntilProxyStarts: true
terminationDrainDuration: 5s
proxyMetadata:
ISTIO_META_DNS_CAPTURE: "true"
EXIT_ON_ZERO_ACTIVE_CONNECTIONS: "true"
pilot:
env:
PILOT_PUSH_THROTTLE: 20
PILOT_DEBOUNCE_AFTER: 500ms
autoscaleMin: 2
autoscaleMax: 4
istio_cni:
enabled: false
Install istiod:
helm install --namespace istio-system istiod istio/istiod --values istiod-helm-values.yaml --wait
Step 6: Install the Istio Ingress Gateway
Create a istio-ingress-helm-values.yaml file:
service:
type: NodePort
ports:
- port: 15021
targetPort: 15021
name: status-port
protocol: TCP
- port: 80
targetPort: 8080
name: http2
protocol: TCP
- port: 15443
targetPort: 15443
name: tls
protocol: TCP
autoscaling:
enabled: false
Install the gateway:
helm install --namespace istio-ingress istio-ingress istio/gateway --values istio-ingress-helm-values.yaml --wait
Step 7: Configure the Istio Ingress
Create a istio-ingress-config.yaml file to route traffic from Okteto's control plane nginx to the Istio ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: istio-ingress
spec:
ingressClassName: okteto-controlplane-nginx
tls:
- hosts:
- '*.${OKTETO_DOMAIN}'
rules:
- host: '*.${OKTETO_DOMAIN}'
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: istio-ingress
port:
number: 80
Apply the configuration (using envsubst to substitute your domain):
envsubst < istio-ingress-config.yaml | kubectl apply -n istio-ingress -f -
Step 8: Verify Installation
Check that all Istio components are running:
kubectl get pods -n istio-system
kubectl get pods -n istio-ingress
All pods should be in Running state before continuing.
How Istio Enables Divert
Once configured by administrators, Istio works transparently for all developers. When a developer uses Divert with the Istio driver, Okteto:
- Creates or modifies VirtualServices to route traffic based on the
baggage: okteto-divert=<namespace>header - Clones the specified host VirtualServices to the developer's personal namespace for header injection
- The Istio sidecar propagates the baggage header through all downstream service calls
Developers don't need to install anything or change their workflow.
Traffic Flow with Istio
Request (no header)
│
▼
┌─────────────┐
│ Okteto │ ← nginx control plane
│ Ingress │
└──────┬──────┘
│
▼
┌─────────────┐
│ Istio │ ← Routes to Istio ingress gateway
│ Ingress │
└──────┬──────┘
│ (baggage header injected by VirtualService)
▼
┌─────────────┐
│ Istio │ ← Routes based on baggage header
│ Sidecar │
└──────┬──────┘
│
▼
┌─────────────┐
│ Service │ ← Your diverted service (personal namespace)
│ (personal) │
└──────┬──────┘
│ (header propagated automatically)
▼
┌──────── ─────┐
│ Istio │ ← Routes downstream call
│ Sidecar │
└──────┬──────┘
│
▼
┌─────────────┐
│ Service │ ← Shared service in staging
│ (staging) │
└─────────────┘
Network Policies Compatibility
If you have network policies enabled (networkPolicies.enabled: true), ensure your policies allow cross-namespace communication for Divert. Example configuration in your Okteto Helm values:
networkPolicies:
enabled: true
ingress:
- from:
- namespaceSelector:
matchLabels:
dev.okteto.com/okteto-managed: "true"
For complete network policy options, see the Helm Configuration reference.
Troubleshooting
Sidecar Not Injected
-
Verify the namespace has the Istio injection label:
kubectl get namespace <namespace> --show-labels -
Restart deployments to inject sidecars:
kubectl rollout restart deployment -n <namespace> -
Verify sidecar containers are present:
kubectl get pods -n <namespace> -o jsonpath='{.items[*].spec.containers[*].name}'
VirtualServices Not Created
- Verify
virtualServices.enabled: truein your Okteto Helm values - Check that Istio CRDs are installed:
kubectl get crd | grep istio - Check Okteto logs for errors related to VirtualService creation
Traffic Not Routing Correctly
- Verify the baggage header format:
baggage: okteto-divert=<namespace> - Check that the developer's
okteto.ymlusesdriver: istio - Test direct service communication:
kubectl exec -it <pod> -- curl -H "baggage: okteto-divert=<ns>" http://service/path - Check Istio proxy logs:
kubectl logs <pod> -c istio-proxy -n <namespace>
Ingress Not Working
- Verify the
istio-ingress-config.yamlwas applied correctly:kubectl get ingress -n istio-ingress - Confirm
OKTETO_DOMAINwas substituted correctly in the ingress manifest - Check that
okteto-nginxis disabled in your Okteto Helm values
Uninstalling Istio
If you need to remove Istio:
# Remove ingress configuration
kubectl delete ingress istio-ingress -n istio-ingress
# Uninstall Helm releases
helm uninstall istio-ingress -n istio-ingress
helm uninstall istiod -n istio-system
helm uninstall istio-base -n istio-system
# Remove namespaces
kubectl delete namespace istio-ingress
kubectl delete namespace istio-system
Re-enable the nginx driver in your Okteto Helm values:
okteto-nginx:
enabled: true
virtualServices:
enabled: false
namespace:
labels: {}
Then upgrade Okteto:
helm upgrade okteto okteto/okteto -f values.yaml
Next Steps
- Configure Divert - Overview of Divert configuration
- Using Divert - Developer implementation guide
- Divert with Istio Sample - Full working example
- Istio Documentation - Official Istio docs