Reorganized documentation to be part of MkDocs site with three new
comprehensive guides covering API7 Gateway configuration.
Changes:
1. Documentation Structure:
- Moved SECRET-MANAGEMENT.md from helm/ to web/docs/
- Created service-discovery.md with complete guide
- Created ingress-routing.md with routing architecture
- Moved externalsecret examples to web/docs/examples/
2. New Documentation - Service Discovery:
- How service discovery works (architecture diagram)
- Benefits vs static configuration
- Configuration examples
- RBAC requirements
- Advanced use cases (auto-scaling, rolling updates)
- Load balancing algorithms
- Monitoring and troubleshooting
- Best practices
3. New Documentation - Ingress & Routing:
- Complete traffic flow architecture
- Ingress configuration explained
- Gateway routing rules and priority
- URI matching patterns (prefix, exact, regex)
- TLS/SSL with cert-manager
- Advanced routing scenarios:
* Multiple domains
* Path-based routing
* Header-based routing
* Method-based routing
- Configuration examples (microservices, WebSocket, canary)
- Monitoring and debugging
- Troubleshooting common issues
4. MkDocs Navigation:
- Updated mkdocs.yml with new pages in Configuration section
- Added: Ingress & Routing
- Added: Service Discovery
- Added: Secret Management
5. Examples Directory:
- Created web/docs/examples/ for configuration examples
- Moved ExternalSecret examples with multiple providers:
* AWS Secrets Manager
* HashiCorp Vault
* Azure Key Vault
* GCP Secret Manager
All documentation now integrated into MkDocs site with proper
navigation, cross-references, and Material theme styling.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
12 KiB
Ingress and Gateway Routing
Learn how external traffic is routed through Kubernetes Ingress to the API7 Gateway, and then to backend services.
Architecture Overview
graph LR
A[External User] -->|HTTPS| B[Ingress Controller]
B -->|HTTP/HTTPS| C[API7 Gateway]
C -->|Apply Plugins| C
C -->|Route Traffic| D[Backend Service 1]
C -->|Route Traffic| E[Backend Service 2]
C -->|Route Traffic| F[Backend Service 3]
G[cert-manager] -->|TLS Cert| B
H[ADC ConfigMap] -->|Routing Rules| C
Traffic Flow:
- External request arrives at Ingress Controller (NGINX)
- Ingress Controller terminates TLS and forwards to API7 Gateway
- API7 Gateway applies policies (rate limiting, CORS, auth)
- Gateway routes to backend services based on ADC rules
- Backend services process request and return response
Ingress Configuration
Current Setup
The Helm chart configures Ingress to route all traffic through API7 Gateway:
# values.yaml
ingress:
enabled: true
className: "nginx"
hosts:
- host: commandware.it
paths:
- path: /
pathType: Prefix
gateway:
serviceName: gateway-0-1759393614-gateway
port: 80
Generated Ingress resource:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api7ee-demo
annotations:
cert-manager.io/cluster-issuer: cloudflare-acme-prod
spec:
ingressClassName: nginx
tls:
- hosts:
- commandware.it
secretName: api7ee-tls
rules:
- host: commandware.it
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gateway-0-1759393614-gateway
port:
number: 80
Why Route Through Gateway?
With API7 Gateway (Recommended):
User → Ingress → API7 Gateway → Backend
↓
TLS, Basic Routing
↓
Advanced Features:
- Dynamic routing
- Rate limiting
- CORS policies
- Authentication
- Request transformation
- Metrics & logging
Direct to Service (Legacy):
User → Ingress → Backend
↓
TLS, Basic Routing
❌ No advanced features
❌ No rate limiting
❌ No CORS
❌ No centralized auth
Gateway Routing Rules
ADC Configuration
API7 Gateway uses ADC (API Declarative Configuration) to define routing rules:
# Managed by Helm chart in ConfigMap
services:
- name: web-service
hosts:
- commandware.it
upstream:
discovery_type: kubernetes
service_name: my-web-app
namespace_id: default
routes:
- name: web-route
uris:
- /*
priority: 1
plugins:
cors: {...}
redirect:
http_to_https: true
- name: api-service
hosts:
- commandware.it
upstream:
discovery_type: kubernetes
service_name: my-api
namespace_id: default
routes:
- name: api-route
uris:
- /api
- /api/*
priority: 10
plugins:
limit-count: {...}
cors: {...}
Route Priority
Routes are evaluated by priority (higher number = higher priority):
routes:
# Evaluated FIRST (highest priority)
- name: api-llm-route
uris:
- /api/llm/*
priority: 20
plugins:
ai-rate-limiting: {...}
# Evaluated SECOND
- name: api-route
uris:
- /api/*
priority: 10
plugins:
limit-count: {...}
# Evaluated LAST (lowest priority)
- name: web-route
uris:
- /*
priority: 1
Example Request Matching:
GET /api/llm/chat→ Matchesapi-llm-route(priority 20)GET /api/users→ Matchesapi-route(priority 10)GET /about→ Matchesweb-route(priority 1)
URI Matching Patterns
Prefix matching:
uris:
- /api/* # Matches /api/users, /api/v1/products, etc.
- /admin/* # Matches /admin/dashboard, /admin/users, etc.
Exact matching:
uris:
- /health # Matches only /health
- /ready # Matches only /ready
Regex matching:
vars:
- - uri
- "~~"
- "^(?!/api)" # Match all URIs NOT starting with /api
TLS/SSL Configuration
Certificate Management
The setup uses cert-manager with Cloudflare ACME:
# values.yaml
ingress:
annotations:
cert-manager.io/cluster-issuer: cloudflare-acme-prod
tls:
- secretName: api7ee-tls
hosts:
- commandware.it
Generated Certificate:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api7ee-demo-tls
spec:
secretName: api7ee-tls
issuerRef:
name: cloudflare-acme-prod
kind: ClusterIssuer
dnsNames:
- commandware.it
duration: 2160h # 90 days
renewBefore: 720h # Renew 30 days before expiry
HTTP to HTTPS Redirect
API7 Gateway handles HTTP→HTTPS redirect:
plugins:
redirect:
http_to_https: true
Request flow:
- User visits
http://commandware.it/api - Gateway returns
301 Moved Permanently - Browser redirects to
https://commandware.it/api
Advanced Routing Scenarios
Multiple Domains
Route different domains to different backends:
services:
- name: main-site
hosts:
- commandware.it
upstream:
service_name: main-web
routes:
- uris: ["/*"]
- name: api-site
hosts:
- api.commandware.it
upstream:
service_name: api-backend
routes:
- uris: ["/*"]
Path-Based Routing
Route based on URL paths:
routes:
# Route 1: Frontend SPA
- name: frontend
uris:
- /
- /app/*
- /assets/*
upstream:
service_name: frontend-app
# Route 2: API endpoints
- name: backend-api
uris:
- /api/*
upstream:
service_name: backend-api
# Route 3: Admin panel
- name: admin
uris:
- /admin/*
upstream:
service_name: admin-panel
plugins:
key-auth: {...} # Require authentication
Header-Based Routing
Route based on HTTP headers:
routes:
# Route for API v2 clients
- name: api-v2
uris:
- /api/*
vars:
- - http_x_api_version
- "=="
- "v2"
upstream:
service_name: api-v2
# Route for API v1 clients (default)
- name: api-v1
uris:
- /api/*
upstream:
service_name: api-v1
Method-Based Routing
Route based on HTTP method:
routes:
# Read operations → Read-only replica
- name: read-ops
uris:
- /api/*
methods:
- GET
- HEAD
upstream:
service_name: api-readonly
# Write operations → Primary backend
- name: write-ops
uris:
- /api/*
methods:
- POST
- PUT
- DELETE
- PATCH
upstream:
service_name: api-primary
Configuration Examples
Example 1: Microservices API
services:
# User service
- name: users-api
hosts:
- api.commandware.it
upstream:
discovery_type: kubernetes
service_name: users-service
routes:
- uris: ["/users", "/users/*"]
plugins:
limit-count:
count: 100
time_window: 60
# Orders service
- name: orders-api
hosts:
- api.commandware.it
upstream:
discovery_type: kubernetes
service_name: orders-service
routes:
- uris: ["/orders", "/orders/*"]
plugins:
key-auth: {}
# Products service
- name: products-api
hosts:
- api.commandware.it
upstream:
discovery_type: kubernetes
service_name: products-service
routes:
- uris: ["/products", "/products/*"]
Example 2: API with WebSocket
services:
- name: websocket-service
hosts:
- ws.commandware.it
upstream:
service_name: websocket-backend
routes:
# WebSocket endpoint
- name: ws-route
uris:
- /ws
enable_websocket: true
# HTTP fallback
- name: http-route
uris:
- /*
Example 3: Canary Deployment
services:
# 90% traffic to stable version
- name: app-stable
hosts:
- app.commandware.it
upstream:
service_name: app-v1
nodes:
- weight: 90
routes:
- uris: ["/*"]
# 10% traffic to canary version
- name: app-canary
hosts:
- app.commandware.it
upstream:
service_name: app-v2
nodes:
- weight: 10
routes:
- uris: ["/*"]
Monitoring and Debugging
Check Ingress Status
# Get Ingress resource
kubectl get ingress -n api7ee
# Describe Ingress
kubectl describe ingress api7ee-demo -n api7ee
# Check Ingress Controller logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
Check Gateway Routing
# View ADC configuration
kubectl get configmap api7ee-demo-api7ee-demo-k8s-adc-config -n api7ee -o yaml
# Check Gateway logs
kubectl logs -n api7ee -l app.kubernetes.io/name=gateway
# Test routing
curl -v https://commandware.it/api/health
Verify TLS Certificate
# Check certificate
kubectl get certificate -n api7ee
# Describe certificate
kubectl describe certificate api7ee-demo-tls -n api7ee
# View certificate secret
kubectl get secret api7ee-tls -n api7ee -o yaml
# Test TLS connection
openssl s_client -connect commandware.it:443 -servername commandware.it
Troubleshooting
404 Not Found
Cause: No route matches the request
Debug:
# Check ADC routes
kubectl get configmap -n api7ee api7ee-demo-adc-config -o yaml | grep -A 10 "routes:"
# Check Gateway logs
kubectl logs -n api7ee -l app.kubernetes.io/name=gateway | grep 404
502 Bad Gateway
Cause: Backend service is unavailable
Debug:
# Check backend service
kubectl get svc my-backend -n api7ee
# Check backend Pods
kubectl get pods -l app=my-backend -n api7ee
# Check service discovery
kubectl get endpoints my-backend -n api7ee
TLS Certificate Issues
Cause: cert-manager failed to issue certificate
Debug:
# Check certificate status
kubectl describe certificate api7ee-demo-tls -n api7ee
# Check cert-manager logs
kubectl logs -n cert-manager -l app=cert-manager
# Check certificate request
kubectl get certificaterequest -n api7ee
Best Practices
1. Always Use Gateway for Production
✅ Do: Route through API7 Gateway for advanced features
❌ Don't: Route directly to backend services
2. Use Descriptive Route Names
# Good
routes:
- name: api-users-list
- name: api-products-create
- name: web-frontend-spa
# Bad
routes:
- name: route1
- name: route2
3. Set Appropriate Priorities
Higher priority for more specific routes:
# Specific route (high priority)
- uris: ["/api/v2/users/*"]
priority: 20
# General route (low priority)
- uris: ["/api/*"]
priority: 10
4. Enable TLS Everywhere
Always use HTTPS in production:
plugins:
redirect:
http_to_https: true
5. Monitor Gateway Metrics
Set up monitoring for:
- Request latency
- Error rates (4xx, 5xx)
- Upstream health
- TLS certificate expiry