Files
api7-demo/helm/api7ee-demo-k8s
d.viti a0dee1d499
Some checks failed
Helm Chart Build / lint-only (push) Has been skipped
Build and Deploy / build-web (push) Failing after 7s
Helm Chart Build / build-helm (push) Successful in 12s
Build and Deploy / build-api (push) Successful in 42s
Add proxy-rewrite plugin to remove /api prefix
Added proxy-rewrite plugin to strip /api prefix from requests before
forwarding to backend API microservice. The API service is a standalone
microservice that expects requests without the /api prefix.

Changes:
- Added proxy-rewrite plugin to both API routes:
  * /api/llm/* route (priority 20)
  * /api/* route (priority 10)
- Uses regex_uri to rewrite: /api/endpoint -> /endpoint

Example transformations:
- /api/health -> /health
- /api/users/123 -> /users/123
- /api/llm/chat -> /llm/chat

Plugin configuration:
  proxy-rewrite:
    regex_uri:
      - "^/api/(.*)"
      - "/$1"

This allows the API microservice to work independently without
needing to handle the /api prefix in its routes.

Reference: https://docs.api7.ai/hub/proxy-rewrite/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-09 17:05:24 +02:00
..

API7 Enterprise Edition Demo - Helm Chart

A comprehensive Helm chart for deploying the API7 Enterprise Edition demo platform on Kubernetes. This chart deploys both web frontend and API backend services with full API7 Gateway integration, including automatic ADC configuration, TLS management, and advanced rate limiting.

📋 Overview

This Helm chart provides:

  • Dual Service Deployment: Web frontend + API backend
  • API7 Gateway Configuration: Automatic ADC (API7 Declarative CLI) sync to existing gateway
    • ⚠️ Does NOT install API7 Gateway - gateway must already exist
    • Only configures routes, services, and upstreams on existing gateway
  • TLS/SSL Management: cert-manager integration or custom certificates
  • Service Discovery: Kubernetes-native service discovery
  • Rate Limiting: Standard and AI token-based rate limiting
  • Autoscaling: Horizontal Pod Autoscaler (HPA) support
  • High Availability: Pod Disruption Budgets and multi-replica deployment
  • Security: Pod Security Contexts, RBAC, and Network Policies

🎯 Features

Deployments

  • Web Service (apache-service): FastAPI frontend with embedded documentation
  • API Service (nginx-service): FastAPI backend with REST API and LLM endpoints

API7 Gateway Configuration

  • Automatic ADC Sync: Configures routes, services, and upstreams
  • Advanced Rate Limiting:
    • Standard: 100 req/60s per IP for /api/*
    • AI: 100 tokens/60s for /api/llm/*
  • Route Prioritization: LLM (20) > API (10) > Web (1)
  • TLS/SSL: Automatic HTTPS redirect and certificate management
  • Plugins: CORS, Prometheus metrics, request logging, authentication

Kubernetes Resources

  • Deployments (Web and API)
  • Services (ClusterIP)
  • Ingress (NGINX)
  • ConfigMaps (Application config and ADC config)
  • Secrets (TLS certificates, API7 credentials)
  • ServiceAccount and RBAC
  • HorizontalPodAutoscaler
  • PodDisruptionBudget
  • Certificate (cert-manager)
  • Job (ADC sync)

📦 Prerequisites

Required

  • Kubernetes: v1.19 or higher
  • Helm: 3.8.0 or higher
  • API7 Enterprise Edition Gateway: MUST be already installed and running
    • This chart does NOT install API7 Gateway
    • This chart only configures routes and services on an existing gateway
    • You need the DP Manager admin URL and admin key
    • Example: http://api7ee3-0-xxx-dp-manager.api7ee.svc.cluster.local:7900

Optional

  • Ingress Controller: NGINX Ingress Controller (for direct Kubernetes ingress)
  • cert-manager: v1.0+ (for automatic TLS certificate management)

Before Installation

  1. Verify API7 Gateway is Running:

    kubectl get pods -n api7ee | grep gateway
    kubectl get pods -n api7ee | grep dp-manager
    
  2. Get API7 Admin Credentials:

    # Get DP Manager URL
    kubectl get svc -n api7ee | grep dp-manager
    
    # Get admin key from API7 Dashboard or documentation
    # Default is usually generated during API7 installation
    
  3. Test Gateway Connectivity:

    # Test from within cluster
    kubectl run test-curl --rm -i --restart=Never --image=curlimages/curl:latest \
      -- curl -s http://api7ee3-0-xxx-dp-manager.api7ee.svc.cluster.local:7900/version
    

🚀 Installation

Add Helm Repository

# Add the Gitea Helm repository
helm repo add api7ee https://git.commandware.com/api/packages/demos/helm

# Update repositories
helm repo update

# Search for available versions
helm search repo api7ee/api7ee-demo-k8s

Basic Installation

# Install with default values
helm install api7ee-demo api7ee/api7ee-demo-k8s \
  --namespace api7ee \
  --create-namespace

# Check installation
helm list -n api7ee
kubectl get pods -n api7ee

Installation with Custom Values

# Install with custom values file
helm install api7ee-demo api7ee/api7ee-demo-k8s \
  --namespace api7ee \
  --create-namespace \
  -f custom-values.yaml

# Install with command-line overrides
helm install api7ee-demo api7ee/api7ee-demo-k8s \
  --namespace api7ee \
  --set web.replicaCount=3 \
  --set api.replicaCount=5 \
  --set api7.gateway.adminKey="your-admin-key" \
  --set api7.hosts[0]="your-domain.com"

Install from Local Chart

# Install from local directory
helm install api7ee-demo ./helm/api7ee-demo-k8s \
  --namespace api7ee \
  --create-namespace

# With development values
helm install api7ee-dev ./helm/api7ee-demo-k8s \
  -f ./helm/api7ee-demo-k8s/values-dev.yaml \
  --namespace api7ee-dev

⚙️ Configuration

Global Configuration

Parameter Description Default
global.imageRegistry Global Docker registry ""
global.imagePullSecrets Image pull secrets []

Web Service Configuration

Parameter Description Default
web.enabled Enable Web component true
web.replicaCount Number of replicas 2
web.image.registry Image registry gitea.server_url
web.image.repository Image repository gitea.repository/web
web.image.tag Image tag main
web.image.pullPolicy Image pull policy IfNotPresent
web.service.type Service type ClusterIP
web.service.port Service port 8000
web.resources.limits.cpu CPU limit 500m
web.resources.limits.memory Memory limit 512Mi
web.resources.requests.cpu CPU request 250m
web.resources.requests.memory Memory request 256Mi
web.autoscaling.enabled Enable HPA false
web.autoscaling.minReplicas Min replicas 2
web.autoscaling.maxReplicas Max replicas 10
web.autoscaling.targetCPUUtilizationPercentage CPU target 80
web.env Environment variables []

API Service Configuration

Parameter Description Default
api.enabled Enable API component true
api.replicaCount Number of replicas 3
api.image.registry Image registry gitea.server_url
api.image.repository Image repository gitea.repository/api
api.image.tag Image tag main
api.image.pullPolicy Image pull policy IfNotPresent
api.service.type Service type ClusterIP
api.service.port Service port 8080
api.resources.limits.cpu CPU limit 1000m
api.resources.limits.memory Memory limit 1Gi
api.resources.requests.cpu CPU request 500m
api.resources.requests.memory Memory request 512Mi
api.autoscaling.enabled Enable HPA true
api.autoscaling.minReplicas Min replicas 3
api.autoscaling.maxReplicas Max replicas 20
api.autoscaling.targetCPUUtilizationPercentage CPU target 70
api.env Environment variables [{name: LOG_LEVEL, value: info}]

Ingress Configuration

Parameter Description Default
ingress.enabled Enable ingress true
ingress.className Ingress class nginx
ingress.annotations Ingress annotations See values.yaml
ingress.hosts[0].host Hostname commandware.it
ingress.tls[0].secretName TLS secret api7ee-tls
ingress.tls[0].hosts TLS hosts [commandware.it]

API7 Gateway Configuration

Parameter Description Default
api7.enabled Enable API7 ADC config true
api7.adc.image ADC Docker image ghcr.io/api7/adc:latest
api7.adc.verbose Verbose logging true
api7.adc.tlsSkipVerify Skip TLS verify false
api7.gateway.adminUrl API7 Admin API URL http://api7ee3-0-xxx-dp-manager...
api7.gateway.adminKey API7 Admin API key edd1c9f034335f136f87ad84b625c8f1
api7.gateway.group Gateway group default
api7.gateway.gatewayService Gateway service name gateway-0-xxx-gateway
api7.backend Backend type api7ee
api7.autoPublish Auto-publish routes true
api7.hosts Routing hosts [commandware.it]

TLS Configuration

Parameter Description Default
api7.tls.enabled Enable TLS true
api7.tls.certManager.enabled Use cert-manager true
api7.tls.certManager.issuer ClusterIssuer name cloudflare-acme-prod
api7.tls.certManager.issuerKind Issuer kind ClusterIssuer
api7.tls.secretName Existing TLS secret ""
api7.tls.certificate Direct certificate ""
api7.tls.key Direct key ""

Rate Limiting Configuration

Parameter Description Default
api7.plugins.rateLimit.enabled Enable standard rate limiting true
api7.plugins.rateLimit.count Request limit 100
api7.plugins.rateLimit.timeWindow Time window (seconds) 60
api7.plugins.rateLimit.keyType Key type var
api7.plugins.rateLimit.key Key variable remote_addr
api7.plugins.aiRateLimit.enabled Enable AI rate limiting true
api7.plugins.aiRateLimit.limit Token limit 100
api7.plugins.aiRateLimit.timeWindow Time window (seconds) 60
api7.plugins.aiRateLimit.limitStrategy Limit strategy total_tokens

Additional Plugins

Parameter Description Default
api7.plugins.cors.enabled Enable CORS true
api7.plugins.cors.allowOrigins Allowed origins ["*"]
api7.plugins.auth.enabled Enable authentication false
api7.plugins.prometheus.enabled Enable Prometheus metrics true
api7.plugins.logging.enabled Enable request logging false

📝 Configuration Examples

Production Deployment

# production-values.yaml
global:
  imageRegistry: "git.commandware.com"
  imagePullSecrets:
    - name: registry-secret

web:
  replicaCount: 3
  image:
    tag: "v1.0.0"
    pullPolicy: Always
  resources:
    limits:
      cpu: 1000m
      memory: 1Gi
    requests:
      cpu: 500m
      memory: 512Mi
  autoscaling:
    enabled: true
    minReplicas: 3
    maxReplicas: 15

api:
  replicaCount: 5
  image:
    tag: "v1.0.0"
    pullPolicy: Always
  resources:
    limits:
      cpu: 2000m
      memory: 2Gi
    requests:
      cpu: 1000m
      memory: 1Gi
  autoscaling:
    enabled: true
    minReplicas: 5
    maxReplicas: 30

api7:
  gateway:
    adminKey: "${API7_ADMIN_KEY}" # Use secret
  hosts:
    - api7-demo.yourdomain.com
  plugins:
    rateLimit:
      count: 1000
    auth:
      enabled: true
helm install api7ee-prod api7ee/api7ee-demo-k8s \
  -f production-values.yaml \
  --namespace api7ee-prod \
  --create-namespace

Custom Domain and TLS

# custom-domain-values.yaml
api7:
  hosts:
    - api.example.com
    - demo.example.com
  tls:
    certManager:
      enabled: true
      issuer: letsencrypt-prod

ingress:
  hosts:
    - host: api.example.com
      paths:
        - path: /
          pathType: Prefix
          service: web
  tls:
    - secretName: example-tls
      hosts:
        - api.example.com

High Resource Environment

# high-resources-values.yaml
web:
  replicaCount: 5
  resources:
    limits:
      cpu: 2000m
      memory: 2Gi
    requests:
      cpu: 1000m
      memory: 1Gi
  autoscaling:
    enabled: true
    maxReplicas: 20

api:
  replicaCount: 10
  resources:
    limits:
      cpu: 4000m
      memory: 4Gi
    requests:
      cpu: 2000m
      memory: 2Gi
  autoscaling:
    enabled: true
    maxReplicas: 50

podDisruptionBudget:
  enabled: true
  minAvailable: 3

Custom API7 Gateway

# custom-gateway-values.yaml
api7:
  gateway:
    adminUrl: http://my-api7-gateway:9180
    adminKey: "my-custom-key"
    group: production
    gatewayService: my-gateway-service
  backend: apisix # or api7ee
  autoPublish: false # Manual publish

LLM Configuration

# llm-values.yaml
api:
  env:
    - name: OPENAI_API_BASE
      value: "http://openwebui.ai:8080/api"
    - name: OPENAI_API_KEY
      valueFrom:
        secretKeyRef:
          name: llm-secrets
          key: api-key
    - name: DEFAULT_LLM_MODEL
      value: "videogame-expert"

api7:
  plugins:
    aiRateLimit:
      enabled: true
      limit: 200 # Higher limit
      timeWindow: 60

Development Environment

Use the included values-dev.yaml:

helm install api7ee-dev ./helm/api7ee-demo-k8s \
  -f ./helm/api7ee-demo-k8s/values-dev.yaml \
  --namespace api7ee-dev

🔄 Upgrade and Rollback

Upgrade Release

# Upgrade with new values
helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \
  --namespace api7ee \
  -f new-values.yaml

# Upgrade with inline values
helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \
  --namespace api7ee \
  --reuse-values \
  --set api.replicaCount=5

# Force upgrade
helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \
  --namespace api7ee \
  --force

Rollback

# View release history
helm history api7ee-demo -n api7ee

# Rollback to previous release
helm rollback api7ee-demo -n api7ee

# Rollback to specific revision
helm rollback api7ee-demo 3 -n api7ee

Verify Upgrade

# Check release status
helm status api7ee-demo -n api7ee

# View current values
helm get values api7ee-demo -n api7ee

# Check all resources
kubectl get all -n api7ee -l app.kubernetes.io/instance=api7ee-demo

🗑️ Uninstallation

# Uninstall release
helm uninstall api7ee-demo --namespace api7ee

# Keep release history (for rollback)
helm uninstall api7ee-demo --namespace api7ee --keep-history

# Delete namespace
kubectl delete namespace api7ee

🔍 Verification and Testing

Check Deployment Status

# Helm release status
helm list -n api7ee
helm status api7ee-demo -n api7ee

# Kubernetes resources
kubectl get all -n api7ee
kubectl get pods -n api7ee -w

# Check specific resources
kubectl get deployments -n api7ee
kubectl get services -n api7ee
kubectl get ingress -n api7ee
kubectl get hpa -n api7ee

View Logs

# Web service logs
kubectl logs -n api7ee -l app=apache-service --tail=50

# API service logs
kubectl logs -n api7ee -l app=nginx-service --tail=50

# ADC sync job logs
kubectl logs -n api7ee -l app.kubernetes.io/component=adc-sync

# All logs
kubectl logs -n api7ee -l app.kubernetes.io/instance=api7ee-demo --all-containers

Test Endpoints

# Get ingress URL
INGRESS_HOST=$(kubectl get ingress -n api7ee api7ee-demo-ingress -o jsonpath='{.spec.rules[0].host}')

# Test web service
curl https://$INGRESS_HOST/

# Test API
curl https://$INGRESS_HOST/api/items

# Test health checks
curl https://$INGRESS_HOST/health
curl https://$INGRESS_HOST/api/health

# Test LLM endpoint
curl -X POST https://$INGRESS_HOST/api/llm/chat \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "What is Zelda?",
    "max_tokens": 100
  }'

🔧 Troubleshooting

Common Issues

1. ADC Sync Job Fails

Check job logs:

kubectl logs -n api7ee -l app.kubernetes.io/component=adc-sync

# Common errors:
# - "connection refused" → Check adminUrl
# - "unauthorized" → Verify adminKey
# - "route not found" → Check backend type (api7ee vs apisix)

Solution:

# Update API7 credentials
helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \
  --namespace api7ee \
  --reuse-values \
  --set api7.gateway.adminKey="correct-admin-key"

2. Pods Not Starting

Check pod status:

kubectl describe pod -n api7ee <pod-name>

# Common issues:
# - ImagePullBackOff → Check image registry credentials
# - CrashLoopBackOff → Check application logs
# - Pending → Check resources and node capacity

Solution for ImagePullBackOff:

# Create registry secret
kubectl create secret docker-registry gitea-registry \
  --docker-server=git.commandware.com \
  --docker-username=<USERNAME> \
  --docker-password=<TOKEN> \
  -n api7ee

# Update values
helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \
  --namespace api7ee \
  --reuse-values \
  --set global.imagePullSecrets[0].name=gitea-registry

3. Routes Return 404

Cause: Routes not published to gateway group

Check API7 Dashboard:

Services → Select service → Routes → Check publication status

Solution:

# Enable auto-publish
helm upgrade api7ee-demo api7ee/api7ee-demo-k8s \
  --namespace api7ee \
  --reuse-values \
  --set api7.autoPublish=true

# Or publish manually via Dashboard:
# Click "Publish" → Select "default" gateway group

4. TLS Certificate Issues

Check certificate status:

kubectl get certificate -n api7ee
kubectl describe certificate -n api7ee api7ee-tls

# Check cert-manager logs
kubectl logs -n cert-manager -l app=cert-manager --tail=50

Verify cert-manager configuration:

# Check ClusterIssuer
kubectl get clusterissuer cloudflare-acme-prod

# Check challenge
kubectl get challenge -n api7ee

5. Service Discovery Not Working

Check services have named ports:

kubectl get svc -n api7ee apache-service -o yaml | grep -A5 ports

# Ports must have 'name' field:
# ports:
#   - port: 80
#     name: http  # ← Required

Check endpoints:

kubectl get endpoints -n api7ee

6. HPA Not Scaling

Check HPA status:

kubectl get hpa -n api7ee
kubectl describe hpa -n api7ee <hpa-name>

Verify metrics-server:

kubectl top nodes
kubectl top pods -n api7ee

# If metrics not available, install metrics-server:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

📊 Monitoring

Prometheus Metrics

If Prometheus is enabled:

metrics:
  enabled: true
  serviceMonitor:
    enabled: true
    interval: 30s

View metrics:

# Check ServiceMonitor
kubectl get servicemonitor -n api7ee

# Query Prometheus
curl http://<prometheus-server>/api/v1/query?query=up{job="api7ee"}

API7 Dashboard

Access API7 Dashboard to view:

  • Route traffic and statistics
  • Rate limiting metrics
  • Service health and upstreams
  • Plugin performance

🔐 Security

Security Features

  • Pod Security Context: Runs as non-root user (UID 1000)
  • Security Context: Drops all capabilities, prevents privilege escalation
  • Read-only Root Filesystem: Enabled for both services
  • Network Policies: Optional network policy support
  • RBAC: ServiceAccount with minimal permissions
  • Secrets Management: TLS certificates and API keys stored securely

Enable Network Policies

networkPolicy:
  enabled: true
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: api7ee
      ports:
        - protocol: TCP
          port: 8000

Secrets Management

Create secrets before installation:

# API7 admin key
kubectl create secret generic api7-admin-key \
  --from-literal=adminKey='your-admin-key' \
  -n api7ee

# LLM API key
kubectl create secret generic llm-secrets \
  --from-literal=api-key='your-llm-api-key' \
  -n api7ee

# Image pull secret
kubectl create secret docker-registry gitea-registry \
  --docker-server=git.commandware.com \
  --docker-username=<user> \
  --docker-password=<token> \
  -n api7ee

Reference in values:

api7:
  gateway:
    adminKey: "${API7_ADMIN_KEY}"

api:
  env:
    - name: OPENAI_API_KEY
      valueFrom:
        secretKeyRef:
          name: llm-secrets
          key: api-key

📚 Chart Structure

helm/api7ee-demo-k8s/
├── Chart.yaml                      # Chart metadata
├── values.yaml                     # Default values
├── values-dev.yaml                 # Development overrides
├── values-production.yaml          # Production overrides
├── templates/
│   ├── NOTES.txt                   # Post-install notes
│   ├── _helpers.tpl                # Template helpers
│   ├── deployment-web.yaml         # Web deployment
│   ├── deployment-api.yaml         # API deployment
│   ├── service-web.yaml            # Web service
│   ├── service-api.yaml            # API service
│   ├── ingress.yaml                # Ingress resource
│   ├── configmap.yaml              # Application config
│   ├── configmap-adc.yaml          # API7 ADC config
│   ├── job-adc-sync.yaml           # ADC sync job
│   ├── secret.yaml                 # Application secrets
│   ├── secret-api7.yaml            # API7 secrets
│   ├── certificate.yaml            # cert-manager certificate
│   ├── serviceaccount.yaml         # ServiceAccount
│   ├── rbac-adc.yaml               # RBAC for ADC
│   ├── hpa-web.yaml                # Web HPA
│   ├── hpa-api.yaml                # API HPA
│   └── poddisruptionbudget.yaml    # PDB
└── README.md                       # This file

📦 Chart Information

📄 Resources

Documentation

🤝 Support


Chart Version: 0.1.0 | Maintainer: CommandWare | License: Demo Project