From 58a1a014d68d09fcb08bfa13daefdd56480f0064 Mon Sep 17 00:00:00 2001 From: Cody Landstrom Date: Tue, 3 Feb 2026 22:31:39 -0800 Subject: [PATCH] Beging addressing Divert Docs feedback --- src/content/core/divert.mdx | 523 +++++++++++++++++- src/content/development/using-divert.mdx | 160 +++++- .../self-hosted/install/divert/index.mdx | 241 +++++++- .../install/divert/linkerd-installation.mdx | 8 +- versioned_docs/version-1.40/core/divert.mdx | 523 +++++++++++++++++- .../version-1.40/development/using-divert.mdx | 160 +++++- .../self-hosted/install/divert/index.mdx | 241 +++++++- .../install/divert/linkerd-installation.mdx | 8 +- 8 files changed, 1824 insertions(+), 40 deletions(-) diff --git a/src/content/core/divert.mdx b/src/content/core/divert.mdx index ab4c4cbb2..e065936f0 100644 --- a/src/content/core/divert.mdx +++ b/src/content/core/divert.mdx @@ -20,6 +20,203 @@ Divert transforms how teams develop microservices by making selective service de - **Reduce infrastructure costs**: Share expensive resources like databases and message queues across your team - **Test against real services**: No more mocks or stubs for services you're not modifying +## Getting Started with Divert + +This section provides a complete end-to-end guide for setting up and using Divert in your organization. Follow these steps in order for a successful implementation. + +### Step 1: Prerequisites Check + +Before enabling Divert, ensure you have: + +**For Administrators:** +- Okteto self-hosted installation (version 1.31+) +- Cluster admin access via `kubectl` +- Helm 3.x installed +- Decision on driver: nginx (default) or istio (if Istio already installed) + +**For Developers:** +- Access to an Okteto instance with Divert enabled +- Okteto CLI installed ([installation guide](../get-started/install-okteto-cli.mdx)) +- Git repository with your application's `okteto.yaml` manifest + +**Application Requirements:** +- Microservice architecture with multiple services +- Services that can propagate HTTP headers to downstream calls +- A stable, complete deployment that can serve as the shared environment + +### Step 2: Set Up Shared Environment + +Create a shared namespace containing your complete application stack: + +```bash +# Option 1: Deploy using Okteto CLI +okteto deploy --namespace staging + +# Option 2: Use kubectl/helm directly +kubectl create namespace staging +helm install myapp ./chart --namespace staging +``` + +**Key considerations:** +- Choose a memorable namespace name (e.g., `staging`, `shared`, `baseline`) +- Deploy all services, databases, and dependencies +- Ensure all services are healthy and accessible +- This environment should be stable and updated regularly + +See [Setting Up Shared Environments](#setting-up-shared-environments) for detailed configuration options. + +### Step 3: Choose and Configure Driver + +**Option A: nginx Driver (Recommended)** + +The nginx driver is enabled by default. Install Linkerd for service-to-service routing: + +```bash +# 1. Install Linkerd (Administrators only) +curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh +linkerd install --crds | kubectl apply -f - +linkerd install | kubectl apply -f - +linkerd check + +# 2. Enable Linkerd in Okteto namespaces +# Add to Okteto Helm values: +namespace: + annotations: + linkerd.io/inject: enabled +``` + +**Option B: istio Driver (If Istio Already Installed)** + +Configure Okteto to use Istio: + +```yaml +# Okteto Helm values +okteto-nginx: + enabled: false + +virtualServices: + enabled: true + +namespace: + labels: + istio-injection: enabled +``` + +See [Self-Hosted Configuration](../self-hosted/install/divert/index.mdx) for complete admin setup. + +### Step 4: Configure Your Application + +Update your `okteto.yaml` to enable Divert: + +```yaml +build: + frontend: + context: ./frontend + +deploy: + commands: + # Deploy only the service(s) you're modifying + - helm upgrade --install frontend ./charts/frontend + --set image=${OKTETO_BUILD_FRONTEND_IMAGE} + + # Enable Divert and point to shared environment + divert: + driver: nginx # or 'istio' if using Istio + namespace: ${OKTETO_SHARED_NAMESPACE:-staging} +``` + +**Key configuration:** +- `divert.namespace`: Points to your shared environment +- `divert.driver`: Matches your cluster configuration (nginx or istio) +- `deploy.commands`: Only deploy services you're actively changing + +### Step 5: Implement Header Propagation + +Update your application code to propagate the `baggage` header: + +**Example (Node.js/Express):** +```javascript +app.use((req, res, next) => { + req.baggage = req.headers['baggage']; + next(); +}); + +// In your service calls +fetch('http://api-service/endpoint', { + headers: { 'baggage': req.baggage } +}); +``` + +See [Using Divert](../development/using-divert.mdx#header-propagation) for language-specific examples. + +### Step 6: Deploy Your First Diverted Environment + +Deploy your personal development environment: + +```bash +# Deploy with Divert enabled +okteto deploy + +# Okteto will: +# 1. Deploy only your modified service(s) +# 2. Create an ingress with header injection +# 3. Provide a unique URL for your environment +``` + +You'll receive a URL like: `https://frontend-alice-myapp.okteto.example.com` + +### Step 7: Verify Divert is Working + +Test that traffic routing works correctly: + +**1. Check your deployed service:** +```bash +okteto namespace alice-myapp +kubectl get pods +# Should show only your modified service(s), not the full stack +``` + +**2. Verify sidecar injection (nginx driver):** +```bash +kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}' +# Should show 'linkerd-proxy' alongside your application container +``` + +**3. Test routing with the baggage header:** +```bash +# Test your endpoint +curl https://frontend-alice-myapp.okteto.example.com + +# Test the shared environment +curl https://frontend-staging-myapp.okteto.example.com + +# Verify different responses (yours vs. shared) +``` + +**4. Check service-to-service routing:** +```bash +# Exec into your pod and test downstream services +kubectl exec -it deployment/frontend -- curl http://api-service/health +# Should successfully reach the shared service +``` + +### Step 8: Develop and Iterate + +With Divert working, you can now: + +1. **Make changes** to your service locally +2. **Deploy updates** with `okteto deploy` +3. **Test immediately** using your personal URL +4. **Share with teammates** - they can access your URL to review +5. **Work in parallel** - other developers can work on different services + +### Next Steps + +- **[How Divert Works](#how-divert-works)** - Deep dive into architecture and routing +- **[Divert Tutorial](/docs/tutorials/divert)** - Hands-on walkthrough with sample app +- **[Using Divert](../development/using-divert.mdx)** - Implementation patterns and best practices +- **[Troubleshooting](#troubleshooting)** - Common issues and solutions + ## How Divert Works Divert creates lightweight development environments containing only your modified services, then intelligently routes traffic between your services and shared infrastructure based on HTTP headers. @@ -36,7 +233,7 @@ Divert creates lightweight development environments containing only your modifie ### Traffic Routing Mechanism -Divert uses the W3C Trace Context standard `baggage` header for routing decisions: +Divert uses the [W3C Trace Context standard `baggage` header](https://www.w3.org/TR/baggage/) for routing decisions: ``` baggage: okteto-divert=alice-feature @@ -56,17 +253,17 @@ Consider a Movies application with multiple microservices. Alice is working on t graph TB User[User Request] Frontend["Frontend (React)
Alice's personal version"] - Catalog[Catalog Service] API[API Gateway] + Catalog[Catalog Service] Rent[Rent Service] MongoDB[(MongoDB)] PostgreSQL[(PostgreSQL)] Kafka[(Kafka)] User --> Frontend - Frontend --> Catalog Frontend --> API - Frontend --> Rent + API --> Catalog + API --> Rent Catalog --> MongoDB API --> PostgreSQL Rent --> Kafka @@ -76,7 +273,7 @@ graph TB classDef infrastructure fill:#f5f5f5,stroke:#ccc,color:#000 class Frontend personal - class Catalog,API,Rent shared + class API,Catalog,Rent shared class MongoDB,PostgreSQL,Kafka infrastructure ``` @@ -87,13 +284,141 @@ graph TB Alice doesn't need to deploy or manage the catalog service, rent service, API gateway, MongoDB, PostgreSQL, or Kafka. Divert handles all the routing transparently. +## Setting Up Shared Environments + +For Divert to work effectively, you need a shared namespace containing a complete, stable deployment of your application. This serves as the "baseline" environment that all developers' diverted namespaces will fall back to. + +### Shared Namespace Recommendations + +**Creating the Shared Namespace:** + +You have two primary options for creating shared namespaces: + +1. **Global Preview Namespace** (Recommended for most teams) + - Created via Okteto's preview environment system + - Automatically managed by Okteto + - Good for teams with CI/CD pipelines + - Requires: Configure preview automation in your repository + +2. **Regular Namespace** + - Standard Okteto namespace deployed manually or via CI + - More control over deployment timing + - Good for stable staging/demo environments + - Requires: Manual deployment management + +:::info Access Requirements +All developers need **read access** to the shared namespace services for Divert routing to work. Configure namespace permissions to ensure team members can access shared resources without deployment permissions. +::: + +### Infrastructure Configuration Options + +When setting up your shared environment, you can configure databases and message queues in two ways: + +#### Option 1: Shared Infrastructure (Most Common) + +Databases and queues remain in the shared namespace, accessed by all developers: + +```yaml +# In shared namespace (e.g., staging) +deploy: + commands: + - helm upgrade --install postgresql bitnami/postgresql + - helm upgrade --install kafka bitnami/kafka + - helm upgrade --install frontend chart/ --set image=${FRONTEND_IMAGE} + - helm upgrade --install api chart/ --set image=${API_IMAGE} +``` + +**Benefits:** +- Shared test data across all developers +- Lower resource usage per developer +- Simpler configuration +- Best for stable database schemas + +**Use when:** +- Database schemas are stable +- Test data can be shared +- You want minimal resource overhead + +#### Option 2: Isolated Databases (Per Developer) + +Each developer deploys their own database instances in their personal namespace: + +```yaml +# In developer namespace (e.g., alice-feature) +dependencies: + postgresql: + repository: https://github.com/okteto/postgresql + wait: true + +deploy: + commands: + # Deploy local database + - helm upgrade --install postgresql bitnami/postgresql + # Deploy only services you're modifying + - helm upgrade --install api chart/ --set image=${OKTETO_BUILD_API_IMAGE} + divert: + namespace: staging +``` + +**Benefits:** +- Full control over test data +- Can modify schemas without affecting others +- Great for testing migrations +- Can use [volume snapshots](use-volume-snapshots.mdx) for fast database cloning + +**Use when:** +- Testing database migrations +- Need isolated test data +- Schema changes are frequent +- Working with sensitive data + +:::tip Hybrid Approach +You can mix both patterns: share stable databases (e.g., user accounts) while running isolated databases for services under active development (e.g., new feature schemas). +::: + +### Linkerd Configuration for Shared Namespaces + +When using the nginx driver, **Linkerd must be installed and configured** in both your shared namespace and developer namespaces for service-to-service routing to work. + +**Key Requirements:** +- Linkerd sidecar injection must be enabled in the shared namespace +- All services in the shared namespace need Linkerd sidecars +- Developer namespaces automatically inherit Linkerd configuration + +See the [Linkerd Installation Guide](../self-hosted/install/divert/linkerd-installation.mdx) for detailed setup instructions. + +### Verifying Your Shared Environment + +Before developers start using Divert, verify your shared namespace is correctly configured: + +1. **Check all services are running:** + ```bash + kubectl get pods -n staging + ``` + +2. **Verify Linkerd sidecars (nginx driver only):** + ```bash + kubectl get pods -n staging -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}' + ``` + Each pod should show both application and `linkerd-proxy` containers + +3. **Test service connectivity:** + ```bash + kubectl exec -n staging deployment/frontend -- curl http://api-service/health + ``` + +4. **Confirm ingress is accessible:** + ```bash + curl https://staging-yourapp.okteto.example.com + ``` + ## Divert Drivers Okteto supports two implementations of Divert to accommodate different infrastructure setups: | Driver | Use Case | Requirements | |--------|----------|--------------| -| **nginx** (default) | Standard Okteto installations | Uses Okteto's built-in nginx ingress with optional Linkerd for service mesh | +| **nginx** (default) | Standard Okteto installations | Uses Okteto's built-in nginx ingress. **Requires Linkerd** for service-to-service routing | | **istio** | Environments with existing Istio service mesh | Requires Istio installation (non-default Okteto configuration) | Both drivers provide the same developer experience and use the same `okteto.yaml` configuration. The difference is in the underlying routing technology. @@ -107,7 +432,7 @@ Both drivers now use the same baggage header format: `baggage: okteto-divert= -o jsonpath='{.metadata.annotations}' +``` + +Should include: `linkerd.io/inject: enabled` + +**Verify Linkerd sidecars are running:** +```bash +kubectl get pods -n -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}' +``` + +Each pod should show both your application container and `linkerd-proxy`. + +**Force sidecar injection:** +```bash +# Restart all deployments to trigger injection +kubectl rollout restart deployment -n +``` + +### Ingress Controller Issues + +**Check nginx ingress controller status (nginx driver):** +```bash +kubectl get pods -n okteto +# Should see okteto-nginx pods in Running state +``` + +**Verify ingress rules are created:** +```bash +kubectl get ingress -n +# Should show ingress for your service with divert annotations +``` + +**Check ingress logs for errors:** +```bash +kubectl logs -n okteto deployment/okteto-nginx -f +``` + +### Linkerd Deployment Verification + +**Check Linkerd control plane (nginx driver):** +```bash +# Using Linkerd CLI +linkerd check + +# Or using kubectl +kubectl get deployments -n linkerd +# Should show: linkerd-destination, linkerd-identity, linkerd-proxy-injector +``` + +**Verify Linkerd is routing traffic:** +```bash +# Watch traffic flow +linkerd viz tap deployment/ --namespace +``` + +**Check ServiceProfiles (if configured):** +```bash +kubectl get serviceprofiles -n +``` + +### Header Propagation Problems + +**Test header is being injected at ingress:** +```bash +curl -v https://your-app.okteto.example.com 2>&1 | grep -i baggage +# Should see: baggage: okteto-divert= +``` + +**Verify header format:** +```bash +# Correct format +baggage: okteto-divert=alice-feature + +# Incorrect formats (won't work) +baggage.okteto-divert=alice-feature +okteto-divert: alice-feature +``` + +**Check application code propagates headers:** +- Review service code to ensure `baggage` header is forwarded in all HTTP/gRPC calls +- Add logging to verify header presence at each service boundary +- Use distributed tracing to follow header through the call chain + +**Test service-to-service routing:** +```bash +# Exec into your pod and test with header +kubectl exec -it deployment/your-service -- \ + curl -H "baggage: okteto-divert=your-namespace" \ + http://downstream-service/api/endpoint +``` + +### Traffic Not Being Diverted + +**Verify divert configuration in okteto.yaml:** +```yaml +deploy: + divert: + namespace: staging # Must match your shared namespace exactly + driver: nginx # Must match cluster configuration +``` + +**Check namespace exists and is healthy:** +```bash +kubectl get namespaces | grep staging +kubectl get pods -n staging +# All pods should be Running +``` + +**Test DNS resolution:** +```bash +kubectl exec -it deployment/your-service -- \ + nslookup api-service.staging.svc.cluster.local +# Should resolve to service IP +``` + +**Verify network policies allow traffic:** +```bash +kubectl get networkpolicies -n staging +kubectl get networkpolicies -n +# Ensure policies allow cross-namespace communication +``` + +### Services Not Discovered + +**Check service names and DNS:** +```bash +# Services should be accessible at +..svc.cluster.local + +# Test resolution +kubectl exec -it deployment/your-service -- \ + nslookup api-service.staging.svc.cluster.local +``` + +**Verify shared environment services are running:** +```bash +kubectl get services -n staging +kubectl get endpoints -n staging +# Endpoints should show pod IPs +``` + +### Common Configuration Mistakes + +1. **Wrong namespace in divert config**: Namespace name must exactly match the shared environment +2. **Missing Linkerd on shared namespace**: Both personal and shared namespaces need Linkerd sidecars +3. **Forgot to propagate headers**: Application code must forward the `baggage` header +4. **Driver mismatch**: Manifest specifies `istio` but cluster uses `nginx` (or vice versa) +5. **Network policies blocking traffic**: Ensure cross-namespace communication is allowed + +### Getting Help + +If issues persist after trying these steps: + +1. **Check Okteto logs:** + ```bash + kubectl logs -n okteto deployment/okteto-api + ``` + +2. **Review pod events:** + ```bash + kubectl describe pod -n + ``` + +3. **Enable debug logging:** Add to your `okteto.yaml`: + ```yaml + deploy: + divert: + namespace: staging + debug: true # Enables verbose routing logs + ``` + +4. **Consult documentation:** + - [Using Divert](../development/using-divert.mdx#troubleshooting) - Developer troubleshooting + - [Linkerd Installation](../self-hosted/install/divert/linkerd-installation.mdx#troubleshooting) - Admin troubleshooting + - [Configure Divert](../self-hosted/install/divert/index.mdx#troubleshooting) - Driver configuration issues + ## Next Steps - **[Using Divert](../development/using-divert.mdx)** - Implementation details, manifest configuration, and code patterns diff --git a/src/content/development/using-divert.mdx b/src/content/development/using-divert.mdx index 3f4f92c6e..f94801e51 100644 --- a/src/content/development/using-divert.mdx +++ b/src/content/development/using-divert.mdx @@ -365,23 +365,181 @@ Others can access your diverted environment using: ## Troubleshooting +This section covers common issues developers encounter when using Divert. For admin-level troubleshooting, see [Configure Divert](../self-hosted/install/divert/index.mdx#troubleshooting). + +### Verify Sidecar Injection (nginx driver) + +**Check if Linkerd sidecar is running:** +```bash +kubectl get pods -n -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}' +``` + +Should show both your application container and `linkerd-proxy`. + +**If sidecar is missing:** +```bash +# Check namespace annotation +kubectl get namespace -o jsonpath='{.metadata.annotations}' + +# Restart deployment to trigger injection +kubectl rollout restart deployment/ -n +``` + +### Check Ingress Controller + +**Verify ingress is created:** +```bash +kubectl get ingress -n +``` + +Should show your service ingress with divert annotations. + +**Check ingress controller logs:** +```bash +kubectl logs -n okteto deployment/okteto-nginx -f | grep +``` + +### Verify Linkerd Deployment (nginx driver) + +**Check Linkerd control plane:** +```bash +# Quick health check +linkerd check + +# Or manually verify deployments +kubectl get deployments -n linkerd +``` + +**Watch traffic flow:** +```bash +linkerd viz tap deployment/ --namespace +``` + +### Header Propagation Issues + +**Test header at ingress:** +```bash +curl -v https://your-app.okteto.example.com 2>&1 | grep -i baggage +# Should see: baggage: okteto-divert= +``` + +**Verify header format:** +```bash +# ✅ Correct +baggage: okteto-divert=alice-feature + +# ❌ Incorrect +baggage.okteto-divert=alice-feature +okteto-divert: alice-feature +``` + +**Check application code:** +- Ensure all services propagate the `baggage` header to downstream calls +- Add logging at service boundaries: `console.log('Baggage header:', req.headers['baggage'])` +- Verify header exists in: HTTP clients, gRPC calls, message queue producers + +**Test service-to-service routing:** +```bash +kubectl exec -it deployment/ -n -- \ + curl -H "baggage: okteto-divert=" \ + http://api-service/endpoint +``` + ### Traffic Not Being Diverted 1. **Check header format**: Ensure you're using `baggage: okteto-divert=` (not `baggage.okteto-divert`) 2. **Verify header propagation**: All services in the call chain must forward the baggage header 3. **Check namespace name**: The namespace in the header must match your Okteto namespace exactly +4. **Verify divert config**: In your `okteto.yaml`: + ```yaml + deploy: + divert: + namespace: staging # Must match shared environment + driver: nginx # Must match cluster config + ``` ### Services Not Discovered 1. **Verify shared namespace**: Ensure the shared namespace is running and healthy -2. **Check service names**: Service discovery uses Kubernetes DNS (`..svc.cluster.local`) + ```bash + kubectl get pods -n staging + # All pods should be Running + ``` + +2. **Check service names**: Service discovery uses Kubernetes DNS + ```bash + # Services are accessible at: + ..svc.cluster.local + + # Test DNS resolution: + kubectl exec -it deployment/ -- \ + nslookup api-service.staging.svc.cluster.local + ``` + 3. **Review divert config**: Ensure `divert.namespace` points to the correct shared environment +4. **Check network policies**: + ```bash + kubectl get networkpolicies -n staging + kubectl get networkpolicies -n + # Ensure cross-namespace communication is allowed + ``` + ### Database Connection Issues 1. **Check connection strings**: Ensure they resolve to the correct database (shared vs. local) + ```bash + # For shared database: + postgresql.staging.svc.cluster.local + + # For local database: + postgresql..svc.cluster.local + ``` + 2. **Verify network policies**: Ensure cross-namespace communication is allowed + ```bash + # Test connectivity + kubectl exec -it deployment/ -n -- \ + nc -zv postgresql.staging.svc.cluster.local 5432 + ``` + 3. **Test connectivity**: Use `kubectl exec` to test database connectivity from your pod + ```bash + kubectl exec -it deployment/ -n -- \ + psql -h postgresql.staging.svc.cluster.local -U user -d database + ``` + +### Quick Diagnostic Checklist + +Run through this checklist when troubleshooting: + +- [ ] Linkerd sidecars are running in your pods (nginx driver) +- [ ] Ingress is created with correct annotations +- [ ] Shared namespace exists and all services are Running +- [ ] Header format is correct: `baggage: okteto-divert=` +- [ ] Application code propagates headers to all downstream calls +- [ ] DNS resolves shared services: `.staging.svc.cluster.local` +- [ ] Network policies allow cross-namespace traffic +- [ ] `divert.namespace` in okteto.yaml matches shared environment + +### Getting Additional Help + +If issues persist: + +1. **Check pod logs**: + ```bash + kubectl logs deployment/ -n + ``` + +2. **Review pod events**: + ```bash + kubectl describe pod -n + ``` + +3. **Consult related documentation**: + - [Divert Core Concepts](../core/divert.mdx#troubleshooting) - Architecture and setup troubleshooting + - [Configure Divert](../self-hosted/install/divert/index.mdx#troubleshooting) - Admin configuration issues + - [Linkerd Installation](../self-hosted/install/divert/linkerd-installation.mdx#troubleshooting) - Service mesh issues ## Best Practices diff --git a/src/content/self-hosted/install/divert/index.mdx b/src/content/self-hosted/install/divert/index.mdx index f8929fcb7..e35886de5 100644 --- a/src/content/self-hosted/install/divert/index.mdx +++ b/src/content/self-hosted/install/divert/index.mdx @@ -18,9 +18,9 @@ Okteto supports two drivers for Divert routing: :::info 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 an **optional enhancement** for the **nginx driver** - it adds service mesh capabilities to nginx-based routing +- **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 (with optional Linkerd) **OR** istio driver +- Choose one: nginx driver (requires Linkerd) **OR** istio driver ::: ## nginx Driver (Default) @@ -30,24 +30,29 @@ The nginx driver is enabled by default in Okteto installations. It uses the `okt ### Requirements - Standard Okteto installation (no additional configuration needed) -- Optional: [Linkerd service mesh](linkerd-installation.mdx) for enhanced service-to-service routing +- **Required**: [Linkerd service mesh](linkerd-installation.mdx) 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=` 3. The nginx ingress controller routes requests to the appropriate namespace based on this header -4. For service-to-service communication, applications must propagate the baggage 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 (Optional) +### Linkerd Integration (Required) -For enhanced service mesh capabilities with the nginx driver, you can install Linkerd. This provides: +For service-to-service routing with the nginx driver, Linkerd must be installed. Linkerd provides: -- Header-based routing at the service mesh level +- 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 +:::warning 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](linkerd-installation.mdx) for setup instructions. ## istio Driver @@ -172,24 +177,246 @@ For complete network policy configuration options, see the [Helm Configuration r ## Troubleshooting +This section covers admin-level troubleshooting for Divert configuration. For developer troubleshooting, see [Using Divert](../../../development/using-divert.mdx#troubleshooting). + +### Verify Sidecar Injection + +**Check namespace annotation (nginx driver with Linkerd):** +```bash +kubectl get namespace -o jsonpath='{.metadata.annotations}' +``` + +Should include: `linkerd.io/inject: enabled` + +**Check Istio sidecar injection (istio driver):** +```bash +kubectl get namespace -o jsonpath='{.metadata.labels}' +``` + +Should include: `istio-injection: enabled` + +**Verify sidecars are running:** +```bash +# For Linkerd +kubectl get pods -n -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):** +```bash +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:** +```bash +kubectl logs -n okteto deployment/okteto-nginx -f +``` + +**For Istio driver, check Istio ingress gateway:** +```bash +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:** +```bash +# 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):** +```bash +linkerd viz check +kubectl get deployments -n linkerd-viz +``` + +**Check ServiceProfiles (if configured):** +```bash +kubectl get serviceprofiles --all-namespaces +``` + +### Header Propagation Testing + +**Test ingress header injection:** +```bash +# 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= +``` + +**Verify header format:** +```bash +# 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:** +```bash +# 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 + ```bash + # 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="` to confirm routing works + 3. **Check namespace labels**: For Istio, verify `istio-injection: enabled` label exists + ```bash + kubectl get namespace -o yaml | grep -A 5 labels + ``` + 4. **Review ingress configuration**: Ensure ingress rules are being created correctly + ```bash + kubectl get ingress --all-namespaces + kubectl describe ingress -n + ``` + +5. **Check Okteto configuration**: + ```bash + kubectl get configmap okteto-config -n okteto -o yaml + # Verify driver settings + ``` ### VirtualServices Not Appearing (Istio) 1. Verify `virtualServices.enabled: true` in Helm values + ```bash + helm get values okteto -n okteto + ``` + 2. Check that Istio CRDs are installed + ```bash + kubectl get crd | grep istio + ``` + 3. Ensure the VirtualService is in a namespace managed by Okteto + ```bash + kubectl get virtualservices --all-namespaces + ``` + +4. Check Okteto API logs for VirtualService creation: + ```bash + 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](#network-policies)) + ```bash + kubectl get networkpolicies --all-namespaces + kubectl describe networkpolicy -n + ``` + 2. Verify DNS resolution works across namespaces + ```bash + 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 + ```bash + # 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 8080 + ``` + +4. Check if service mesh is blocking traffic: + ```bash + # For Linkerd + linkerd viz tap deployment/ -n + + # For Istio + istioctl proxy-status + ``` + +### Common Configuration Issues + +1. **Linkerd not installed**: Required for nginx driver + ```bash + linkerd version + # Should show both client and server versions + ``` + +2. **Wrong driver in okteto.yaml**: Manifest specifies different driver than cluster + ```bash + # 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 + ```bash + # Temporarily disable to test + kubectl delete networkpolicy -n + ``` + +4. **Istio and Linkerd both installed**: Cannot use both together + ```bash + 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**: + ```bash + 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: + ```yaml + api: + logLevel: debug + ``` + +3. **Consult related documentation**: + - [Linkerd Installation](linkerd-installation.mdx#troubleshooting) - Linkerd-specific issues + - [Using Divert](../../../development/using-divert.mdx#troubleshooting) - Developer-side troubleshooting + - [Divert Core Concepts](../../../core/divert.mdx#troubleshooting) - Architecture and flow troubleshooting ## Next Steps diff --git a/src/content/self-hosted/install/divert/linkerd-installation.mdx b/src/content/self-hosted/install/divert/linkerd-installation.mdx index e937ef50e..5e9db90be 100644 --- a/src/content/self-hosted/install/divert/linkerd-installation.mdx +++ b/src/content/self-hosted/install/divert/linkerd-installation.mdx @@ -1,6 +1,6 @@ --- title: Linkerd Installation for Divert -description: Install Linkerd to enhance Divert routing capabilities with the nginx driver +description: Install Linkerd to enable Divert service-to-service routing with the nginx driver sidebar_label: Linkerd Installation --- @@ -8,14 +8,14 @@ sidebar_label: Linkerd Installation This guide is for **Okteto administrators** setting up Linkerd in the cluster. Developers do not need to install anything - once Linkerd is configured in the cluster, Divert works transparently for all developers. ::: -This guide covers installing Linkerd to enhance Divert's routing capabilities when using the nginx driver. Linkerd provides service mesh functionality that enables more sophisticated traffic routing based on HTTP headers. +This guide covers installing Linkerd to enable Divert's service-to-service routing when using the nginx driver. Linkerd provides the service mesh functionality that enables traffic routing based on HTTP headers between services. :::warning For nginx Driver Only Linkerd is **only** for use with the **nginx driver**. If you're using the istio driver, do not install Linkerd - Istio already provides service mesh capabilities. See [Configure Divert](index.mdx) for the distinction between drivers. ::: -:::info -Linkerd is **optional** for the nginx driver. The basic Divert functionality works without it, but Linkerd enables enhanced service-to-service routing within the mesh. +:::warning Required for nginx Driver +Linkerd is **required** for service-to-service routing with the nginx driver. While Divert can route ingress traffic without Linkerd, service-to-service communication within the cluster requires Linkerd's service mesh capabilities. ::: ## Prerequisites diff --git a/versioned_docs/version-1.40/core/divert.mdx b/versioned_docs/version-1.40/core/divert.mdx index ab4c4cbb2..e065936f0 100644 --- a/versioned_docs/version-1.40/core/divert.mdx +++ b/versioned_docs/version-1.40/core/divert.mdx @@ -20,6 +20,203 @@ Divert transforms how teams develop microservices by making selective service de - **Reduce infrastructure costs**: Share expensive resources like databases and message queues across your team - **Test against real services**: No more mocks or stubs for services you're not modifying +## Getting Started with Divert + +This section provides a complete end-to-end guide for setting up and using Divert in your organization. Follow these steps in order for a successful implementation. + +### Step 1: Prerequisites Check + +Before enabling Divert, ensure you have: + +**For Administrators:** +- Okteto self-hosted installation (version 1.31+) +- Cluster admin access via `kubectl` +- Helm 3.x installed +- Decision on driver: nginx (default) or istio (if Istio already installed) + +**For Developers:** +- Access to an Okteto instance with Divert enabled +- Okteto CLI installed ([installation guide](../get-started/install-okteto-cli.mdx)) +- Git repository with your application's `okteto.yaml` manifest + +**Application Requirements:** +- Microservice architecture with multiple services +- Services that can propagate HTTP headers to downstream calls +- A stable, complete deployment that can serve as the shared environment + +### Step 2: Set Up Shared Environment + +Create a shared namespace containing your complete application stack: + +```bash +# Option 1: Deploy using Okteto CLI +okteto deploy --namespace staging + +# Option 2: Use kubectl/helm directly +kubectl create namespace staging +helm install myapp ./chart --namespace staging +``` + +**Key considerations:** +- Choose a memorable namespace name (e.g., `staging`, `shared`, `baseline`) +- Deploy all services, databases, and dependencies +- Ensure all services are healthy and accessible +- This environment should be stable and updated regularly + +See [Setting Up Shared Environments](#setting-up-shared-environments) for detailed configuration options. + +### Step 3: Choose and Configure Driver + +**Option A: nginx Driver (Recommended)** + +The nginx driver is enabled by default. Install Linkerd for service-to-service routing: + +```bash +# 1. Install Linkerd (Administrators only) +curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh +linkerd install --crds | kubectl apply -f - +linkerd install | kubectl apply -f - +linkerd check + +# 2. Enable Linkerd in Okteto namespaces +# Add to Okteto Helm values: +namespace: + annotations: + linkerd.io/inject: enabled +``` + +**Option B: istio Driver (If Istio Already Installed)** + +Configure Okteto to use Istio: + +```yaml +# Okteto Helm values +okteto-nginx: + enabled: false + +virtualServices: + enabled: true + +namespace: + labels: + istio-injection: enabled +``` + +See [Self-Hosted Configuration](../self-hosted/install/divert/index.mdx) for complete admin setup. + +### Step 4: Configure Your Application + +Update your `okteto.yaml` to enable Divert: + +```yaml +build: + frontend: + context: ./frontend + +deploy: + commands: + # Deploy only the service(s) you're modifying + - helm upgrade --install frontend ./charts/frontend + --set image=${OKTETO_BUILD_FRONTEND_IMAGE} + + # Enable Divert and point to shared environment + divert: + driver: nginx # or 'istio' if using Istio + namespace: ${OKTETO_SHARED_NAMESPACE:-staging} +``` + +**Key configuration:** +- `divert.namespace`: Points to your shared environment +- `divert.driver`: Matches your cluster configuration (nginx or istio) +- `deploy.commands`: Only deploy services you're actively changing + +### Step 5: Implement Header Propagation + +Update your application code to propagate the `baggage` header: + +**Example (Node.js/Express):** +```javascript +app.use((req, res, next) => { + req.baggage = req.headers['baggage']; + next(); +}); + +// In your service calls +fetch('http://api-service/endpoint', { + headers: { 'baggage': req.baggage } +}); +``` + +See [Using Divert](../development/using-divert.mdx#header-propagation) for language-specific examples. + +### Step 6: Deploy Your First Diverted Environment + +Deploy your personal development environment: + +```bash +# Deploy with Divert enabled +okteto deploy + +# Okteto will: +# 1. Deploy only your modified service(s) +# 2. Create an ingress with header injection +# 3. Provide a unique URL for your environment +``` + +You'll receive a URL like: `https://frontend-alice-myapp.okteto.example.com` + +### Step 7: Verify Divert is Working + +Test that traffic routing works correctly: + +**1. Check your deployed service:** +```bash +okteto namespace alice-myapp +kubectl get pods +# Should show only your modified service(s), not the full stack +``` + +**2. Verify sidecar injection (nginx driver):** +```bash +kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}' +# Should show 'linkerd-proxy' alongside your application container +``` + +**3. Test routing with the baggage header:** +```bash +# Test your endpoint +curl https://frontend-alice-myapp.okteto.example.com + +# Test the shared environment +curl https://frontend-staging-myapp.okteto.example.com + +# Verify different responses (yours vs. shared) +``` + +**4. Check service-to-service routing:** +```bash +# Exec into your pod and test downstream services +kubectl exec -it deployment/frontend -- curl http://api-service/health +# Should successfully reach the shared service +``` + +### Step 8: Develop and Iterate + +With Divert working, you can now: + +1. **Make changes** to your service locally +2. **Deploy updates** with `okteto deploy` +3. **Test immediately** using your personal URL +4. **Share with teammates** - they can access your URL to review +5. **Work in parallel** - other developers can work on different services + +### Next Steps + +- **[How Divert Works](#how-divert-works)** - Deep dive into architecture and routing +- **[Divert Tutorial](/docs/tutorials/divert)** - Hands-on walkthrough with sample app +- **[Using Divert](../development/using-divert.mdx)** - Implementation patterns and best practices +- **[Troubleshooting](#troubleshooting)** - Common issues and solutions + ## How Divert Works Divert creates lightweight development environments containing only your modified services, then intelligently routes traffic between your services and shared infrastructure based on HTTP headers. @@ -36,7 +233,7 @@ Divert creates lightweight development environments containing only your modifie ### Traffic Routing Mechanism -Divert uses the W3C Trace Context standard `baggage` header for routing decisions: +Divert uses the [W3C Trace Context standard `baggage` header](https://www.w3.org/TR/baggage/) for routing decisions: ``` baggage: okteto-divert=alice-feature @@ -56,17 +253,17 @@ Consider a Movies application with multiple microservices. Alice is working on t graph TB User[User Request] Frontend["Frontend (React)
Alice's personal version"] - Catalog[Catalog Service] API[API Gateway] + Catalog[Catalog Service] Rent[Rent Service] MongoDB[(MongoDB)] PostgreSQL[(PostgreSQL)] Kafka[(Kafka)] User --> Frontend - Frontend --> Catalog Frontend --> API - Frontend --> Rent + API --> Catalog + API --> Rent Catalog --> MongoDB API --> PostgreSQL Rent --> Kafka @@ -76,7 +273,7 @@ graph TB classDef infrastructure fill:#f5f5f5,stroke:#ccc,color:#000 class Frontend personal - class Catalog,API,Rent shared + class API,Catalog,Rent shared class MongoDB,PostgreSQL,Kafka infrastructure ``` @@ -87,13 +284,141 @@ graph TB Alice doesn't need to deploy or manage the catalog service, rent service, API gateway, MongoDB, PostgreSQL, or Kafka. Divert handles all the routing transparently. +## Setting Up Shared Environments + +For Divert to work effectively, you need a shared namespace containing a complete, stable deployment of your application. This serves as the "baseline" environment that all developers' diverted namespaces will fall back to. + +### Shared Namespace Recommendations + +**Creating the Shared Namespace:** + +You have two primary options for creating shared namespaces: + +1. **Global Preview Namespace** (Recommended for most teams) + - Created via Okteto's preview environment system + - Automatically managed by Okteto + - Good for teams with CI/CD pipelines + - Requires: Configure preview automation in your repository + +2. **Regular Namespace** + - Standard Okteto namespace deployed manually or via CI + - More control over deployment timing + - Good for stable staging/demo environments + - Requires: Manual deployment management + +:::info Access Requirements +All developers need **read access** to the shared namespace services for Divert routing to work. Configure namespace permissions to ensure team members can access shared resources without deployment permissions. +::: + +### Infrastructure Configuration Options + +When setting up your shared environment, you can configure databases and message queues in two ways: + +#### Option 1: Shared Infrastructure (Most Common) + +Databases and queues remain in the shared namespace, accessed by all developers: + +```yaml +# In shared namespace (e.g., staging) +deploy: + commands: + - helm upgrade --install postgresql bitnami/postgresql + - helm upgrade --install kafka bitnami/kafka + - helm upgrade --install frontend chart/ --set image=${FRONTEND_IMAGE} + - helm upgrade --install api chart/ --set image=${API_IMAGE} +``` + +**Benefits:** +- Shared test data across all developers +- Lower resource usage per developer +- Simpler configuration +- Best for stable database schemas + +**Use when:** +- Database schemas are stable +- Test data can be shared +- You want minimal resource overhead + +#### Option 2: Isolated Databases (Per Developer) + +Each developer deploys their own database instances in their personal namespace: + +```yaml +# In developer namespace (e.g., alice-feature) +dependencies: + postgresql: + repository: https://github.com/okteto/postgresql + wait: true + +deploy: + commands: + # Deploy local database + - helm upgrade --install postgresql bitnami/postgresql + # Deploy only services you're modifying + - helm upgrade --install api chart/ --set image=${OKTETO_BUILD_API_IMAGE} + divert: + namespace: staging +``` + +**Benefits:** +- Full control over test data +- Can modify schemas without affecting others +- Great for testing migrations +- Can use [volume snapshots](use-volume-snapshots.mdx) for fast database cloning + +**Use when:** +- Testing database migrations +- Need isolated test data +- Schema changes are frequent +- Working with sensitive data + +:::tip Hybrid Approach +You can mix both patterns: share stable databases (e.g., user accounts) while running isolated databases for services under active development (e.g., new feature schemas). +::: + +### Linkerd Configuration for Shared Namespaces + +When using the nginx driver, **Linkerd must be installed and configured** in both your shared namespace and developer namespaces for service-to-service routing to work. + +**Key Requirements:** +- Linkerd sidecar injection must be enabled in the shared namespace +- All services in the shared namespace need Linkerd sidecars +- Developer namespaces automatically inherit Linkerd configuration + +See the [Linkerd Installation Guide](../self-hosted/install/divert/linkerd-installation.mdx) for detailed setup instructions. + +### Verifying Your Shared Environment + +Before developers start using Divert, verify your shared namespace is correctly configured: + +1. **Check all services are running:** + ```bash + kubectl get pods -n staging + ``` + +2. **Verify Linkerd sidecars (nginx driver only):** + ```bash + kubectl get pods -n staging -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}' + ``` + Each pod should show both application and `linkerd-proxy` containers + +3. **Test service connectivity:** + ```bash + kubectl exec -n staging deployment/frontend -- curl http://api-service/health + ``` + +4. **Confirm ingress is accessible:** + ```bash + curl https://staging-yourapp.okteto.example.com + ``` + ## Divert Drivers Okteto supports two implementations of Divert to accommodate different infrastructure setups: | Driver | Use Case | Requirements | |--------|----------|--------------| -| **nginx** (default) | Standard Okteto installations | Uses Okteto's built-in nginx ingress with optional Linkerd for service mesh | +| **nginx** (default) | Standard Okteto installations | Uses Okteto's built-in nginx ingress. **Requires Linkerd** for service-to-service routing | | **istio** | Environments with existing Istio service mesh | Requires Istio installation (non-default Okteto configuration) | Both drivers provide the same developer experience and use the same `okteto.yaml` configuration. The difference is in the underlying routing technology. @@ -107,7 +432,7 @@ Both drivers now use the same baggage header format: `baggage: okteto-divert= -o jsonpath='{.metadata.annotations}' +``` + +Should include: `linkerd.io/inject: enabled` + +**Verify Linkerd sidecars are running:** +```bash +kubectl get pods -n -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}' +``` + +Each pod should show both your application container and `linkerd-proxy`. + +**Force sidecar injection:** +```bash +# Restart all deployments to trigger injection +kubectl rollout restart deployment -n +``` + +### Ingress Controller Issues + +**Check nginx ingress controller status (nginx driver):** +```bash +kubectl get pods -n okteto +# Should see okteto-nginx pods in Running state +``` + +**Verify ingress rules are created:** +```bash +kubectl get ingress -n +# Should show ingress for your service with divert annotations +``` + +**Check ingress logs for errors:** +```bash +kubectl logs -n okteto deployment/okteto-nginx -f +``` + +### Linkerd Deployment Verification + +**Check Linkerd control plane (nginx driver):** +```bash +# Using Linkerd CLI +linkerd check + +# Or using kubectl +kubectl get deployments -n linkerd +# Should show: linkerd-destination, linkerd-identity, linkerd-proxy-injector +``` + +**Verify Linkerd is routing traffic:** +```bash +# Watch traffic flow +linkerd viz tap deployment/ --namespace +``` + +**Check ServiceProfiles (if configured):** +```bash +kubectl get serviceprofiles -n +``` + +### Header Propagation Problems + +**Test header is being injected at ingress:** +```bash +curl -v https://your-app.okteto.example.com 2>&1 | grep -i baggage +# Should see: baggage: okteto-divert= +``` + +**Verify header format:** +```bash +# Correct format +baggage: okteto-divert=alice-feature + +# Incorrect formats (won't work) +baggage.okteto-divert=alice-feature +okteto-divert: alice-feature +``` + +**Check application code propagates headers:** +- Review service code to ensure `baggage` header is forwarded in all HTTP/gRPC calls +- Add logging to verify header presence at each service boundary +- Use distributed tracing to follow header through the call chain + +**Test service-to-service routing:** +```bash +# Exec into your pod and test with header +kubectl exec -it deployment/your-service -- \ + curl -H "baggage: okteto-divert=your-namespace" \ + http://downstream-service/api/endpoint +``` + +### Traffic Not Being Diverted + +**Verify divert configuration in okteto.yaml:** +```yaml +deploy: + divert: + namespace: staging # Must match your shared namespace exactly + driver: nginx # Must match cluster configuration +``` + +**Check namespace exists and is healthy:** +```bash +kubectl get namespaces | grep staging +kubectl get pods -n staging +# All pods should be Running +``` + +**Test DNS resolution:** +```bash +kubectl exec -it deployment/your-service -- \ + nslookup api-service.staging.svc.cluster.local +# Should resolve to service IP +``` + +**Verify network policies allow traffic:** +```bash +kubectl get networkpolicies -n staging +kubectl get networkpolicies -n +# Ensure policies allow cross-namespace communication +``` + +### Services Not Discovered + +**Check service names and DNS:** +```bash +# Services should be accessible at +..svc.cluster.local + +# Test resolution +kubectl exec -it deployment/your-service -- \ + nslookup api-service.staging.svc.cluster.local +``` + +**Verify shared environment services are running:** +```bash +kubectl get services -n staging +kubectl get endpoints -n staging +# Endpoints should show pod IPs +``` + +### Common Configuration Mistakes + +1. **Wrong namespace in divert config**: Namespace name must exactly match the shared environment +2. **Missing Linkerd on shared namespace**: Both personal and shared namespaces need Linkerd sidecars +3. **Forgot to propagate headers**: Application code must forward the `baggage` header +4. **Driver mismatch**: Manifest specifies `istio` but cluster uses `nginx` (or vice versa) +5. **Network policies blocking traffic**: Ensure cross-namespace communication is allowed + +### Getting Help + +If issues persist after trying these steps: + +1. **Check Okteto logs:** + ```bash + kubectl logs -n okteto deployment/okteto-api + ``` + +2. **Review pod events:** + ```bash + kubectl describe pod -n + ``` + +3. **Enable debug logging:** Add to your `okteto.yaml`: + ```yaml + deploy: + divert: + namespace: staging + debug: true # Enables verbose routing logs + ``` + +4. **Consult documentation:** + - [Using Divert](../development/using-divert.mdx#troubleshooting) - Developer troubleshooting + - [Linkerd Installation](../self-hosted/install/divert/linkerd-installation.mdx#troubleshooting) - Admin troubleshooting + - [Configure Divert](../self-hosted/install/divert/index.mdx#troubleshooting) - Driver configuration issues + ## Next Steps - **[Using Divert](../development/using-divert.mdx)** - Implementation details, manifest configuration, and code patterns diff --git a/versioned_docs/version-1.40/development/using-divert.mdx b/versioned_docs/version-1.40/development/using-divert.mdx index 3f4f92c6e..f94801e51 100644 --- a/versioned_docs/version-1.40/development/using-divert.mdx +++ b/versioned_docs/version-1.40/development/using-divert.mdx @@ -365,23 +365,181 @@ Others can access your diverted environment using: ## Troubleshooting +This section covers common issues developers encounter when using Divert. For admin-level troubleshooting, see [Configure Divert](../self-hosted/install/divert/index.mdx#troubleshooting). + +### Verify Sidecar Injection (nginx driver) + +**Check if Linkerd sidecar is running:** +```bash +kubectl get pods -n -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}' +``` + +Should show both your application container and `linkerd-proxy`. + +**If sidecar is missing:** +```bash +# Check namespace annotation +kubectl get namespace -o jsonpath='{.metadata.annotations}' + +# Restart deployment to trigger injection +kubectl rollout restart deployment/ -n +``` + +### Check Ingress Controller + +**Verify ingress is created:** +```bash +kubectl get ingress -n +``` + +Should show your service ingress with divert annotations. + +**Check ingress controller logs:** +```bash +kubectl logs -n okteto deployment/okteto-nginx -f | grep +``` + +### Verify Linkerd Deployment (nginx driver) + +**Check Linkerd control plane:** +```bash +# Quick health check +linkerd check + +# Or manually verify deployments +kubectl get deployments -n linkerd +``` + +**Watch traffic flow:** +```bash +linkerd viz tap deployment/ --namespace +``` + +### Header Propagation Issues + +**Test header at ingress:** +```bash +curl -v https://your-app.okteto.example.com 2>&1 | grep -i baggage +# Should see: baggage: okteto-divert= +``` + +**Verify header format:** +```bash +# ✅ Correct +baggage: okteto-divert=alice-feature + +# ❌ Incorrect +baggage.okteto-divert=alice-feature +okteto-divert: alice-feature +``` + +**Check application code:** +- Ensure all services propagate the `baggage` header to downstream calls +- Add logging at service boundaries: `console.log('Baggage header:', req.headers['baggage'])` +- Verify header exists in: HTTP clients, gRPC calls, message queue producers + +**Test service-to-service routing:** +```bash +kubectl exec -it deployment/ -n -- \ + curl -H "baggage: okteto-divert=" \ + http://api-service/endpoint +``` + ### Traffic Not Being Diverted 1. **Check header format**: Ensure you're using `baggage: okteto-divert=` (not `baggage.okteto-divert`) 2. **Verify header propagation**: All services in the call chain must forward the baggage header 3. **Check namespace name**: The namespace in the header must match your Okteto namespace exactly +4. **Verify divert config**: In your `okteto.yaml`: + ```yaml + deploy: + divert: + namespace: staging # Must match shared environment + driver: nginx # Must match cluster config + ``` ### Services Not Discovered 1. **Verify shared namespace**: Ensure the shared namespace is running and healthy -2. **Check service names**: Service discovery uses Kubernetes DNS (`..svc.cluster.local`) + ```bash + kubectl get pods -n staging + # All pods should be Running + ``` + +2. **Check service names**: Service discovery uses Kubernetes DNS + ```bash + # Services are accessible at: + ..svc.cluster.local + + # Test DNS resolution: + kubectl exec -it deployment/ -- \ + nslookup api-service.staging.svc.cluster.local + ``` + 3. **Review divert config**: Ensure `divert.namespace` points to the correct shared environment +4. **Check network policies**: + ```bash + kubectl get networkpolicies -n staging + kubectl get networkpolicies -n + # Ensure cross-namespace communication is allowed + ``` + ### Database Connection Issues 1. **Check connection strings**: Ensure they resolve to the correct database (shared vs. local) + ```bash + # For shared database: + postgresql.staging.svc.cluster.local + + # For local database: + postgresql..svc.cluster.local + ``` + 2. **Verify network policies**: Ensure cross-namespace communication is allowed + ```bash + # Test connectivity + kubectl exec -it deployment/ -n -- \ + nc -zv postgresql.staging.svc.cluster.local 5432 + ``` + 3. **Test connectivity**: Use `kubectl exec` to test database connectivity from your pod + ```bash + kubectl exec -it deployment/ -n -- \ + psql -h postgresql.staging.svc.cluster.local -U user -d database + ``` + +### Quick Diagnostic Checklist + +Run through this checklist when troubleshooting: + +- [ ] Linkerd sidecars are running in your pods (nginx driver) +- [ ] Ingress is created with correct annotations +- [ ] Shared namespace exists and all services are Running +- [ ] Header format is correct: `baggage: okteto-divert=` +- [ ] Application code propagates headers to all downstream calls +- [ ] DNS resolves shared services: `.staging.svc.cluster.local` +- [ ] Network policies allow cross-namespace traffic +- [ ] `divert.namespace` in okteto.yaml matches shared environment + +### Getting Additional Help + +If issues persist: + +1. **Check pod logs**: + ```bash + kubectl logs deployment/ -n + ``` + +2. **Review pod events**: + ```bash + kubectl describe pod -n + ``` + +3. **Consult related documentation**: + - [Divert Core Concepts](../core/divert.mdx#troubleshooting) - Architecture and setup troubleshooting + - [Configure Divert](../self-hosted/install/divert/index.mdx#troubleshooting) - Admin configuration issues + - [Linkerd Installation](../self-hosted/install/divert/linkerd-installation.mdx#troubleshooting) - Service mesh issues ## Best Practices diff --git a/versioned_docs/version-1.40/self-hosted/install/divert/index.mdx b/versioned_docs/version-1.40/self-hosted/install/divert/index.mdx index f8929fcb7..e35886de5 100644 --- a/versioned_docs/version-1.40/self-hosted/install/divert/index.mdx +++ b/versioned_docs/version-1.40/self-hosted/install/divert/index.mdx @@ -18,9 +18,9 @@ Okteto supports two drivers for Divert routing: :::info 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 an **optional enhancement** for the **nginx driver** - it adds service mesh capabilities to nginx-based routing +- **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 (with optional Linkerd) **OR** istio driver +- Choose one: nginx driver (requires Linkerd) **OR** istio driver ::: ## nginx Driver (Default) @@ -30,24 +30,29 @@ The nginx driver is enabled by default in Okteto installations. It uses the `okt ### Requirements - Standard Okteto installation (no additional configuration needed) -- Optional: [Linkerd service mesh](linkerd-installation.mdx) for enhanced service-to-service routing +- **Required**: [Linkerd service mesh](linkerd-installation.mdx) 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=` 3. The nginx ingress controller routes requests to the appropriate namespace based on this header -4. For service-to-service communication, applications must propagate the baggage 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 (Optional) +### Linkerd Integration (Required) -For enhanced service mesh capabilities with the nginx driver, you can install Linkerd. This provides: +For service-to-service routing with the nginx driver, Linkerd must be installed. Linkerd provides: -- Header-based routing at the service mesh level +- 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 +:::warning 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](linkerd-installation.mdx) for setup instructions. ## istio Driver @@ -172,24 +177,246 @@ For complete network policy configuration options, see the [Helm Configuration r ## Troubleshooting +This section covers admin-level troubleshooting for Divert configuration. For developer troubleshooting, see [Using Divert](../../../development/using-divert.mdx#troubleshooting). + +### Verify Sidecar Injection + +**Check namespace annotation (nginx driver with Linkerd):** +```bash +kubectl get namespace -o jsonpath='{.metadata.annotations}' +``` + +Should include: `linkerd.io/inject: enabled` + +**Check Istio sidecar injection (istio driver):** +```bash +kubectl get namespace -o jsonpath='{.metadata.labels}' +``` + +Should include: `istio-injection: enabled` + +**Verify sidecars are running:** +```bash +# For Linkerd +kubectl get pods -n -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):** +```bash +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:** +```bash +kubectl logs -n okteto deployment/okteto-nginx -f +``` + +**For Istio driver, check Istio ingress gateway:** +```bash +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:** +```bash +# 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):** +```bash +linkerd viz check +kubectl get deployments -n linkerd-viz +``` + +**Check ServiceProfiles (if configured):** +```bash +kubectl get serviceprofiles --all-namespaces +``` + +### Header Propagation Testing + +**Test ingress header injection:** +```bash +# 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= +``` + +**Verify header format:** +```bash +# 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:** +```bash +# 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 + ```bash + # 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="` to confirm routing works + 3. **Check namespace labels**: For Istio, verify `istio-injection: enabled` label exists + ```bash + kubectl get namespace -o yaml | grep -A 5 labels + ``` + 4. **Review ingress configuration**: Ensure ingress rules are being created correctly + ```bash + kubectl get ingress --all-namespaces + kubectl describe ingress -n + ``` + +5. **Check Okteto configuration**: + ```bash + kubectl get configmap okteto-config -n okteto -o yaml + # Verify driver settings + ``` ### VirtualServices Not Appearing (Istio) 1. Verify `virtualServices.enabled: true` in Helm values + ```bash + helm get values okteto -n okteto + ``` + 2. Check that Istio CRDs are installed + ```bash + kubectl get crd | grep istio + ``` + 3. Ensure the VirtualService is in a namespace managed by Okteto + ```bash + kubectl get virtualservices --all-namespaces + ``` + +4. Check Okteto API logs for VirtualService creation: + ```bash + 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](#network-policies)) + ```bash + kubectl get networkpolicies --all-namespaces + kubectl describe networkpolicy -n + ``` + 2. Verify DNS resolution works across namespaces + ```bash + 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 + ```bash + # 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 8080 + ``` + +4. Check if service mesh is blocking traffic: + ```bash + # For Linkerd + linkerd viz tap deployment/ -n + + # For Istio + istioctl proxy-status + ``` + +### Common Configuration Issues + +1. **Linkerd not installed**: Required for nginx driver + ```bash + linkerd version + # Should show both client and server versions + ``` + +2. **Wrong driver in okteto.yaml**: Manifest specifies different driver than cluster + ```bash + # 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 + ```bash + # Temporarily disable to test + kubectl delete networkpolicy -n + ``` + +4. **Istio and Linkerd both installed**: Cannot use both together + ```bash + 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**: + ```bash + 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: + ```yaml + api: + logLevel: debug + ``` + +3. **Consult related documentation**: + - [Linkerd Installation](linkerd-installation.mdx#troubleshooting) - Linkerd-specific issues + - [Using Divert](../../../development/using-divert.mdx#troubleshooting) - Developer-side troubleshooting + - [Divert Core Concepts](../../../core/divert.mdx#troubleshooting) - Architecture and flow troubleshooting ## Next Steps diff --git a/versioned_docs/version-1.40/self-hosted/install/divert/linkerd-installation.mdx b/versioned_docs/version-1.40/self-hosted/install/divert/linkerd-installation.mdx index e937ef50e..5e9db90be 100644 --- a/versioned_docs/version-1.40/self-hosted/install/divert/linkerd-installation.mdx +++ b/versioned_docs/version-1.40/self-hosted/install/divert/linkerd-installation.mdx @@ -1,6 +1,6 @@ --- title: Linkerd Installation for Divert -description: Install Linkerd to enhance Divert routing capabilities with the nginx driver +description: Install Linkerd to enable Divert service-to-service routing with the nginx driver sidebar_label: Linkerd Installation --- @@ -8,14 +8,14 @@ sidebar_label: Linkerd Installation This guide is for **Okteto administrators** setting up Linkerd in the cluster. Developers do not need to install anything - once Linkerd is configured in the cluster, Divert works transparently for all developers. ::: -This guide covers installing Linkerd to enhance Divert's routing capabilities when using the nginx driver. Linkerd provides service mesh functionality that enables more sophisticated traffic routing based on HTTP headers. +This guide covers installing Linkerd to enable Divert's service-to-service routing when using the nginx driver. Linkerd provides the service mesh functionality that enables traffic routing based on HTTP headers between services. :::warning For nginx Driver Only Linkerd is **only** for use with the **nginx driver**. If you're using the istio driver, do not install Linkerd - Istio already provides service mesh capabilities. See [Configure Divert](index.mdx) for the distinction between drivers. ::: -:::info -Linkerd is **optional** for the nginx driver. The basic Divert functionality works without it, but Linkerd enables enhanced service-to-service routing within the mesh. +:::warning Required for nginx Driver +Linkerd is **required** for service-to-service routing with the nginx driver. While Divert can route ingress traffic without Linkerd, service-to-service communication within the cluster requires Linkerd's service mesh capabilities. ::: ## Prerequisites