Files
api7-demo/web/docs/api7-configuration.md
d.viti a2eef9efde
Some checks failed
Build and Push Docker Images / build-web (push) Failing after 1m3s
Build and Push Docker Images / build-api (push) Failing after 1m1s
first commit
2025-10-03 01:20:15 +02:00

11 KiB

Gateway Configuration

Complete guide for configuring routes, services, and policies in the API Gateway.

Declarative Configuration Management

The gateway supports declarative configuration management using YAML files through CLI tools.

CLI Tool Installation

# Install the gateway CLI tool
# Installation method varies by gateway solution

# Verify installation
<cli-tool> version

Configuration Structure

services:
  - name: <service-name>
    upstream:
      name: <upstream-name>
      scheme: http|https
      type: roundrobin|chash|least_conn|ewma
      # Option 1: Static nodes
      nodes:
        - host: <hostname>
          port: <port>
          weight: <1-100>
      # Option 2: Service discovery
      discovery_type: kubernetes
      service_name: <namespace>/<service-name>:<port-name>
    routes:
      - name: <route-name>
        priority: <number>
        uris:
          - <path-pattern>
        hosts:
          - <hostname>
        methods:
          - GET|POST|PUT|DELETE|...
        plugins:
          <plugin-name>:
            <plugin-config>

ssls:
  - snis:
      - <domain>
    certificates:
      - certificate: |
          <pem-certificate>
        key: |
          <pem-key>

Service Discovery

Kubernetes Service Discovery

Prerequisites:

  1. Service registry configured in Dashboard
  2. RBAC permissions for gateway service account
  3. Service ports must have name field

Configuration:

Via Dashboard:

  1. Settings → Service Registry → Add Service Registry
  2. Select: Kubernetes
  3. Configure:
    Name: kubernetes-cluster
    API Server: https://kubernetes.default.svc.cluster.local:443
    Token Path: /var/run/secrets/kubernetes.io/serviceaccount/token
    Namespace Filter: <namespace>
    

RBAC Setup:

kubectl create clusterrolebinding gateway-discovery \
  --clusterrole=view \
  --serviceaccount=<namespace>:default

Service Configuration:

upstream:
  discovery_type: kubernetes
  service_name: <namespace>/<service-name>:<port-name>
  # Format: <namespace>/<service-name>:<port-name>

Static Nodes (No Service Discovery)

upstream:
  nodes:
    - host: web-service.<namespace>.svc.cluster.local
      port: 80
      weight: 100
    - host: <cluster-ip>
      port: 80
      weight: 100

Route Configuration

Basic Route

routes:
  - name: web-route
    uris:
      - /*
    hosts:
      - app.domain.com
    methods:
      - GET
      - POST
    plugins:
      redirect:
        http_to_https: true

Path-Based Routing with Priorities

services:
  - name: api-service
    upstream:
      discovery_type: kubernetes
      service_name: <namespace>/api-service:http
    routes:
      - name: api-route
        priority: 10  # Higher priority = evaluated first
        uris:
          - /api
          - /api/*
        hosts:
          - app.domain.com
        plugins:
          redirect:
            http_to_https: true
          proxy-rewrite:
            regex_uri:
              - ^/api/(.*)
              - /$1  # Strip /api prefix

  - name: web-service
    upstream:
      discovery_type: kubernetes
      service_name: <namespace>/web-service:http
    routes:
      - name: web-route
        priority: 1  # Lower priority = fallback
        uris:
          - /*
        hosts:
          - app.domain.com

Traffic Flow:

  • app.domain.com/api/users → api-service (receives /users)
  • app.domain.com/anything-else → web-service

Wildcard Host Matching

routes:
  - name: wildcard-route
    uris:
      - /*
    hosts:
      - "*.domain.com"
      - domain.com

Multiple Hosts

routes:
  - name: multi-host-route
    uris:
      - /*
    hosts:
      - api.domain.com
      - api.domain.org
      - api.example.com

Plugins

HTTP to HTTPS Redirect

plugins:
  redirect:
    http_to_https: true

Proxy Rewrite (Path Manipulation)

Strip prefix:

plugins:
  proxy-rewrite:
    regex_uri:
      - ^/api/(.*)
      - /$1

Add prefix:

plugins:
  proxy-rewrite:
    uri: /backend$uri

Rewrite host:

plugins:
  proxy-rewrite:
    host: backend-service.<namespace>.svc.cluster.local

CORS Configuration

plugins:
  cors:
    allow_origins: "*"
    allow_methods: "GET,POST,PUT,DELETE,OPTIONS"
    allow_headers: "Content-Type,Authorization"
    allow_credential: true
    max_age: 3600

Rate Limiting

Per IP:

plugins:
  limit-req:
    rate: 100
    burst: 200
    key: remote_addr
    rejected_code: 429

Per Consumer:

plugins:
  limit-req:
    rate: 1000
    burst: 2000
    key: consumer_name

Authentication

API Key:

plugins:
  key-auth:
    header: X-API-Key

JWT:

plugins:
  jwt-auth:
    key: my-secret-key
    algorithm: HS256

Basic Auth:

plugins:
  basic-auth: {}

Request/Response Transformation

Add headers:

plugins:
  proxy-rewrite:
    headers:
      X-Forwarded-By: "API-Gateway"
      X-Custom-Header: "value"

Remove headers:

plugins:
  response-rewrite:
    headers:
      remove:
        - X-Internal-Header

Caching

plugins:
  proxy-cache:
    cache_method:
      - GET
      - HEAD
    cache_http_status:
      - 200
      - 301
      - 302
    cache_ttl: 3600

IP Restriction

Whitelist:

plugins:
  ip-restriction:
    whitelist:
      - 192.168.1.0/24
      - 10.0.0.0/8

Blacklist:

plugins:
  ip-restriction:
    blacklist:
      - 203.0.113.0/24

SSL/TLS Configuration

Using Existing Kubernetes Secret

ssls:
  - snis:
      - "*.domain.com"
      - domain.com
    certificates:
      - certificate: |
          -----BEGIN CERTIFICATE-----
          <CERTIFICATE_CONTENT>
          -----END CERTIFICATE-----
        key: |
          -----BEGIN PRIVATE KEY-----
          <KEY_CONTENT>
          -----END PRIVATE KEY-----

Extract from Kubernetes Secret

# Extract certificate
kubectl get secret tls-secret -n <namespace> -o jsonpath='{.data.tls\.crt}' | base64 -d

# Extract key
kubectl get secret tls-secret -n <namespace> -o jsonpath='{.data.tls\.key}' | base64 -d

Configuration Examples

Multiple Service Routes

Configuration:

services:
  - name: frontend-service
    upstream:
      name: frontend-upstream
      scheme: http
      type: roundrobin
      nodes:
        - host: frontend-service.<namespace>.svc.cluster.local
          port: 80
          weight: 100
    routes:
      - name: frontend-route
        uris:
          - /*
        hosts:
          - app.domain.com
        plugins:
          redirect:
            http_to_https: true

      - name: root-route
        priority: 1
        uris:
          - /
          - /~*
        hosts:
          - domain.com
        plugins:
          redirect:
            http_to_https: true

  - name: api-service
    upstream:
      name: api-upstream
      scheme: http
      type: roundrobin
      nodes:
        - host: api-service.<namespace>.svc.cluster.local
          port: 80
          weight: 100
    routes:
      - name: api-route
        priority: 10
        uris:
          - /api
          - /api/*
        hosts:
          - domain.com
        plugins:
          redirect:
            http_to_https: true
          proxy-rewrite:
            regex_uri:
              - ^/api/(.*)
              - /$1

Traffic Flow:

  • app.domain.com/* → Frontend Service
  • domain.com/api/* → API Service (with /api prefix stripped)
  • domain.com/* → Frontend Service

Syncing Configuration

Via CLI Tools

Sync configuration:

<cli-tool> sync -f config.yaml \
  --server <dashboard-url> \
  --token <api-token> \
  --gateway-group default

Dump current configuration:

<cli-tool> dump \
  --server <dashboard-url> \
  --token <api-token> > current-config.yaml

Validate configuration:

<cli-tool> validate -f config.yaml

Publishing Routes

⚠️ Important: Routes synced via CLI may need to be published via Dashboard.

Steps:

  1. Access Dashboard
  2. Navigate: Services → Select service
  3. Go to: Routes tab
  4. For each route:
    • Click: Publish
    • Select: Gateway group
    • Confirm

Route Status:

  • Unpublished: Synced but not active
  • Published: Active on gateway

Advanced Configurations

Multi-Environment Setup

Development Gateway Group:

# Sync to dev gateway group
<cli-tool> sync -f config.yaml \
  --gateway-group dev \
  --server <dashboard-url> \
  --token <token>

Production Gateway Group:

# Sync to prod gateway group
<cli-tool> sync -f config.yaml \
  --gateway-group prod \
  --server <dashboard-url> \
  --token <token>

Health Checks

upstream:
  checks:
    active:
      http_path: /health
      healthy:
        interval: 5
        successes: 2
      unhealthy:
        interval: 5
        http_failures: 3

Retry Policy

upstream:
  retries: 3
  retry_timeout: 10
  pass_host: pass  # or rewrite, node

Circuit Breaker

plugins:
  api-breaker:
    break_response_code: 503
    max_breaker_sec: 300
    unhealthy:
      http_statuses: [500, 503]
      failures: 3
    healthy:
      http_statuses: [200]
      successes: 3

Monitoring Route Performance

View Metrics in Dashboard

  1. Navigate: MonitoringRoutes
  2. Select route to view:
    • Request rate (req/s)
    • Latency percentiles (P50, P95, P99)
    • Error rate
    • Status code distribution

Prometheus Metrics

Access Prometheus:

kubectl port-forward -n <namespace> svc/prometheus-server 9090:9090

Useful Queries:

# Request rate by route
sum(rate(http_requests_total[5m])) by (route)

# Latency P95
histogram_quantile(0.95, sum(rate(http_latency_bucket[5m])) by (le, route))

# Error rate
sum(rate(http_requests_total{code=~"5.."}[5m])) by (route)

Troubleshooting

Route Returns 404

Check:

  1. Route is published in Dashboard
  2. Host header matches route configuration exactly
  3. Path matches URI pattern
  4. Gateway pods are healthy
# Check gateway logs
kubectl logs -n <namespace> -l app.kubernetes.io/name=gateway --tail=100

Service Discovery Not Working

Check:

  1. Service registry configured in Dashboard
  2. Service registry status is "Connected"
  3. RBAC permissions granted
  4. Service has named ports
# Verify service
kubectl get svc -n <namespace> <service-name>

# Check endpoints
kubectl get endpoints -n <namespace> <service-name>

Configuration Not Applied

Check:

  1. CLI sync succeeded
  2. Routes are published
  3. Gateway group matches
# Dump and compare
<cli-tool> dump --server <URL> --token <TOKEN> > current.yaml
diff config.yaml current.yaml

Complete configuration reference for API Gateway infrastructure.