From a2eef9efdec24b219728cf328f19f66d7e661cb8 Mon Sep 17 00:00:00 2001 From: "d.viti" Date: Fri, 3 Oct 2025 01:20:15 +0200 Subject: [PATCH] first commit --- .gitea/workflows/build.yml | 76 ++++ README.md | 492 ++++++++++++++++++++++ api/.dockerignore | 16 + api/Dockerfile | 15 + api/README.md | 87 ++++ api/main.py | 123 ++++++ api/requirements.txt | 3 + web/.dockerignore | 20 + web/Dockerfile | 22 + web/README.md | 168 ++++++++ web/docs/api7-configuration.md | 615 +++++++++++++++++++++++++++ web/docs/architecture.md | 283 +++++++++++++ web/docs/cicd-pipeline.md | 477 +++++++++++++++++++++ web/docs/getting-started.md | 432 +++++++++++++++++++ web/docs/index.md | 82 ++++ web/docs/kubernetes-resources.md | 446 ++++++++++++++++++++ web/docs/mkdocs.yml | 72 ++++ web/docs/troubleshooting.md | 702 +++++++++++++++++++++++++++++++ web/main.py | 137 ++++++ web/requirements.txt | 4 + 20 files changed, 4272 insertions(+) create mode 100644 .gitea/workflows/build.yml create mode 100644 README.md create mode 100644 api/.dockerignore create mode 100644 api/Dockerfile create mode 100644 api/README.md create mode 100644 api/main.py create mode 100644 api/requirements.txt create mode 100644 web/.dockerignore create mode 100644 web/Dockerfile create mode 100644 web/README.md create mode 100644 web/docs/api7-configuration.md create mode 100644 web/docs/architecture.md create mode 100644 web/docs/cicd-pipeline.md create mode 100644 web/docs/getting-started.md create mode 100644 web/docs/index.md create mode 100644 web/docs/kubernetes-resources.md create mode 100644 web/docs/mkdocs.yml create mode 100644 web/docs/troubleshooting.md create mode 100644 web/main.py create mode 100644 web/requirements.txt diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..7308606 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,76 @@ +name: Build and Push Docker Images + +on: + push: + workflow_dispatch: + +jobs: + build-web: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Gitea Container Registry + uses: docker/login-action@v3 + with: + registry: git.commandware.com + username: ${{ gitea.actor }} + password: ${{ secrets.GITEA_TOKEN }} + + - name: Extract metadata for web image + id: meta-web + uses: docker/metadata-action@v5 + with: + images: git.commandware.com/demos/api7-demo/web + tags: | + type=ref,event=branch + + - name: Build and push web image + uses: docker/build-push-action@v5 + with: + context: ./web + file: ./web/Dockerfile + push: true + tags: ${{ steps.meta-web.outputs.tags }} + labels: ${{ steps.meta-web.outputs.labels }} + cache-from: type=registry,ref=git.commandware.com/demos/api7-demo/web:buildcache + cache-to: type=registry,ref=git.commandware.com/demos/api7-demo/web:buildcache,mode=max + + build-api: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Gitea Container Registry + uses: docker/login-action@v3 + with: + registry: git.commandware.com + username: ${{ gitea.actor }} + password: ${{ secrets.GITEA_TOKEN }} + + - name: Extract metadata for api image + id: meta-api + uses: docker/metadata-action@v5 + with: + images: git.commandware.com/demos/api7-demo/api + tags: | + type=ref,event=branch + + - name: Build and push api image + uses: docker/build-push-action@v5 + with: + context: ./api + file: ./api/Dockerfile + push: true + tags: ${{ steps.meta-api.outputs.tags }} + labels: ${{ steps.meta-api.outputs.labels }} + cache-from: type=registry,ref=git.commandware.com/demos/api7-demo/api:buildcache + cache-to: type=registry,ref=git.commandware.com/demos/api7-demo/api:buildcache,mode=max diff --git a/README.md b/README.md new file mode 100644 index 0000000..a08e695 --- /dev/null +++ b/README.md @@ -0,0 +1,492 @@ +# API7 Demo - FastAPI Applications + +Demo project showcasing two FastAPI applications deployed on Kubernetes through API7 Enterprise Gateway with automated CI/CD using Gitea. + +## πŸ“ Project Structure + +``` +api7-demo/ +β”œβ”€β”€ web/ # Web application +β”‚ β”œβ”€β”€ main.py # FastAPI web app with HTML UI +β”‚ β”œβ”€β”€ Dockerfile # Container image +β”‚ └── requirements.txt # Python dependencies +β”œβ”€β”€ api/ # API application +β”‚ β”œβ”€β”€ main.py # FastAPI REST API with Swagger +β”‚ β”œβ”€β”€ Dockerfile # Container image +β”‚ └── requirements.txt # Python dependencies +β”œβ”€β”€ .gitea/ +β”‚ └── workflows/ +β”‚ └── build.yml # CI/CD pipeline +└── README.md +``` + +## 🌐 Applications + +### Web Application (`web/`) + +Modern web interface with: +- Responsive HTML dashboard +- System information display +- Health check endpoints + +**Endpoints:** +- `GET /` - Main webpage +- `GET /health` - Health check + +**Port:** 8000 + +### API Application (`api/`) + +REST API with full documentation: +- CRUD operations for Items and Users +- Automatic Swagger/OpenAPI docs +- Data validation with Pydantic + +**Key Endpoints:** +- `GET /docs` - Swagger UI +- `GET /items` - List items +- `POST /items` - Create item +- `GET /users` - List users +- `GET /health` - Health check + +**Port:** 8001 (internally 8000) + +## πŸš€ Quick Start + +### Local Development + +**Web Application:** +```bash +cd web +pip install -r requirements.txt +python main.py +# Access at http://localhost:8000 +``` + +**API Application:** +```bash +cd api +pip install -r requirements.txt +python main.py +# Swagger at http://localhost:8000/docs +``` + +### Docker + +**Build and run Web:** +```bash +docker build -t web-app ./web +docker run -p 8000:8000 web-app +``` + +**Build and run API:** +```bash +docker build -t api-app ./api +docker run -p 8001:8000 api-app +``` + +## 🐳 CI/CD with Gitea + +### Automated Pipeline + +The `.gitea/workflows/build.yml` pipeline automatically: +1. Builds Docker images for both applications +2. Pushes to Gitea container registry +3. Tags images with branch name +4. Implements layer caching for faster builds + +**Triggers:** +- Any branch push +- Manual dispatch + +**Registry:** `git.commandware.com/demos/api7-demo` + +**Images:** +- `git.commandware.com/demos/api7-demo/web:` +- `git.commandware.com/demos/api7-demo/api:` + +### Setup + +1. **Create `GITEA_TOKEN` secret:** + - Repository Settings β†’ Secrets β†’ Add Secret + - Name: `GITEA_TOKEN` + - Generate token at: User Settings β†’ Applications β†’ Generate Token + - Required scope: `write:package` + +2. **Push to trigger build:** + ```bash + git push origin main + ``` + +## ☸️ Kubernetes Deployment + +### Prerequisites + +- Kubernetes cluster (v1.19+) +- API7 Enterprise Gateway installed +- Namespace: `api7ee` + +### Deployment Manifest + +**k8s-deployments.yaml:** +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: web + namespace: api7ee +spec: + replicas: 2 + selector: + matchLabels: + app: web + template: + metadata: + labels: + app: web + spec: + containers: + - name: web + image: git.commandware.com/demos/api7-demo/web:main + ports: + - containerPort: 8000 + name: http + livenessProbe: + httpGet: + path: /health + port: 8000 +--- +apiVersion: v1 +kind: Service +metadata: + name: web-service + namespace: api7ee +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 8000 + name: http + selector: + app: web +--- +# Similar configuration for api deployment +``` + +### Deploy + +```bash +kubectl apply -f k8s-deployments.yaml +kubectl rollout status deployment/web -n api7ee +kubectl rollout status deployment/api -n api7ee +``` + +## πŸ”Œ API7 Gateway Configuration + +### Route Configuration (ADC) + +**api7-routes.yaml:** +```yaml +services: + - name: web-service + upstream: + name: web-upstream + scheme: http + type: roundrobin + discovery_type: kubernetes + service_name: api7ee/web-service:http + routes: + - name: web-route + uris: + - /* + hosts: + - demo.yourdomain.com + plugins: + redirect: + http_to_https: true + + - name: api-service + upstream: + name: api-upstream + scheme: http + type: roundrobin + discovery_type: kubernetes + service_name: api7ee/api-service:http + routes: + - name: api-route + priority: 10 + uris: + - /api + - /api/* + hosts: + - demo.yourdomain.com + plugins: + redirect: + http_to_https: true + proxy-rewrite: + regex_uri: + - ^/api/(.*) + - /$1 + +ssls: + - snis: + - "*.yourdomain.com" + certificates: + - certificate: | + -----BEGIN CERTIFICATE----- + + -----END CERTIFICATE----- + key: | + -----BEGIN PRIVATE KEY----- + + -----END PRIVATE KEY----- +``` + +### Sync Configuration + +```bash +adc sync -f api7-routes.yaml \ + --backend api7ee \ + --server https://api7-dashboard.yourdomain.com \ + --token \ + --gateway-group default \ + --tls-skip-verify +``` + +### Publish Routes + +Routes must be published via API7 Dashboard to become active: + +1. Navigate to **Services** β†’ Select service +2. Go to **Routes** tab +3. Click **"Publish"** for each route +4. Select gateway group: **"default"** +5. Confirm + +## πŸ§ͺ Testing + +### Test Endpoints + +```bash +# Web application +curl https://demo.yourdomain.com + +# API health check +curl https://demo.yourdomain.com/api/health + +# API Swagger (if exposed) +curl https://demo.yourdomain.com/api/docs + +# Verify HTTP β†’ HTTPS redirect +curl -I http://demo.yourdomain.com +``` + +### Verify Service Discovery + +```bash +# Scale deployment +kubectl scale deployment web -n api7ee --replicas=5 + +# API7 automatically discovers new endpoints +kubectl get endpoints -n api7ee web-service + +# Scale back +kubectl scale deployment web -n api7ee --replicas=2 +``` + +## πŸ“Š Architecture + +``` +Internet + ↓ +LoadBalancer (External IP) + ↓ +NGINX Ingress Controller + ↓ +TLS Termination (Let's Encrypt) + ↓ +API7 Gateway (ClusterIP) + ↓ +[Kubernetes Service Discovery] + ↓ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Web Service β”‚ API Service β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### Traffic Routing + +- `demo.yourdomain.com/api/*` β†’ API Service (priority 10, strips `/api` prefix) +- `demo.yourdomain.com/*` β†’ Web Service (default priority) + +## πŸ”§ API7 Enterprise Setup Guide + +### Certificate Management + +**Using cert-manager with Cloudflare:** + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: cloudflare-acme-prod +spec: + acme: + email: your-email@example.com + server: https://acme-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: letsencrypt-prod-key + solvers: + - dns01: + cloudflare: + apiTokenSecretRef: + name: cloudflare-api-token-secret + key: api-token +``` + +**Create Cloudflare secret:** +```bash +kubectl create secret generic cloudflare-api-token-secret \ + -n cert-manager \ + --from-literal=api-token=YOUR_TOKEN +``` + +### Kubernetes Service Discovery + +**Configure in API7 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: api7ee (optional) + ``` + +**Verify RBAC permissions:** +```bash +kubectl create clusterrolebinding api7-gateway-discovery \ + --clusterrole=view \ + --serviceaccount=:default +``` + +### Ingress Configuration + +**Example ingress for API7 Gateway:** + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: api7-gateway-ingress + namespace: api7ee +spec: + ingressClassName: nginx + tls: + - hosts: + - demo.yourdomain.com + secretName: demo-tls + rules: + - host: demo.yourdomain.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: api7-gateway-service + port: + number: 80 +``` + +**Note:** Ingress backend points to API7 Gateway service, not application services. + +## πŸ› οΈ Troubleshooting + +### Routes Return 404 + +**Problem:** Routes synced but returning 404 + +**Solution:** Routes not published. Publish via API7 Dashboard. + +### Service Discovery Not Working + +**Problem:** `service registry not found` error + +**Checklist:** +- βœ… Service registry configured in dashboard +- βœ… Registry status shows "Connected" +- βœ… RBAC permissions granted +- βœ… Service ports have `name` field + +### Certificate Issues + +**Problem:** Certificate not trusted + +**Solution:** +```bash +# Check certificate status +kubectl get certificate -n api7ee +kubectl describe certificate -n api7ee + +# Check cert-manager logs +kubectl logs -n cert-manager -l app.kubernetes.io/name=cert-manager --tail=50 +``` + +### Container Images Not Found + +**Problem:** ImagePullBackOff in Kubernetes + +**Solution:** +```bash +# Create registry secret +kubectl create secret docker-registry gitea-registry \ + --docker-server=git.commandware.com \ + --docker-username= \ + --docker-password= \ + -n api7ee + +# Add to deployment +spec: + template: + spec: + imagePullSecrets: + - name: gitea-registry +``` + +## πŸ“š Resources + +- **API7 Documentation:** https://docs.api7.ai/ +- **APISIX Documentation:** https://apisix.apache.org/docs/ +- **FastAPI Documentation:** https://fastapi.tiangolo.com/ +- **Gitea Actions:** https://docs.gitea.com/usage/actions/overview + +## πŸ” Best Practices + +### Security +- βœ… Use TLS for all external traffic +- βœ… Implement rate limiting on public endpoints +- βœ… Store secrets in Kubernetes Secrets or external vault +- βœ… Use least-privilege RBAC permissions + +### Performance +- βœ… Enable service discovery for automatic scaling +- βœ… Configure appropriate resource limits +- βœ… Use Docker layer caching in CI/CD +- βœ… Implement health checks and readiness probes + +### Monitoring +- βœ… Monitor gateway metrics in API7 Dashboard +- βœ… Track API usage and performance +- βœ… Set up alerts for certificate expiration +- βœ… Review application logs regularly + +## πŸ“ License + +Demo project for API7 Enterprise Gateway evaluation. + +--- + +**Repository:** https://git.commandware.com/demos/api7-demo.git diff --git a/api/.dockerignore b/api/.dockerignore new file mode 100644 index 0000000..740954f --- /dev/null +++ b/api/.dockerignore @@ -0,0 +1,16 @@ +__pycache__ +*.pyc +*.pyo +*.pyd +.Python +env/ +venv/ +.venv/ +pip-log.txt +pip-delete-this-directory.txt +.pytest_cache/ +.coverage +htmlcov/ +*.log +.DS_Store +.env diff --git a/api/Dockerfile b/api/Dockerfile new file mode 100644 index 0000000..fb5354f --- /dev/null +++ b/api/Dockerfile @@ -0,0 +1,15 @@ +FROM python:3.11-slim + +WORKDIR /app + +# Install dependencies +RUN pip install --no-cache-dir fastapi uvicorn[standard] pydantic + +# Copy application +COPY main.py . + +# Expose port +EXPOSE 8001 + +# Run the application +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8001"] diff --git a/api/README.md b/api/README.md new file mode 100644 index 0000000..e64644d --- /dev/null +++ b/api/README.md @@ -0,0 +1,87 @@ +# API Service - FastAPI + +A RESTful API service built with FastAPI featuring Swagger documentation. + +## Features + +- πŸ“š Automatic Swagger/OpenAPI documentation +- πŸ”„ RESTful API endpoints +- βœ… Data validation with Pydantic +- πŸ“Š Statistics and monitoring endpoints +- ❀️ Health check endpoints + +## Local Development + +### Run with Python + +```bash +# Install dependencies +pip install -r requirements.txt + +# Run the application +python main.py + +# Or use uvicorn directly +uvicorn main:app --reload --host 0.0.0.0 --port 8000 +``` + +### Run with Docker + +```bash +# Build image +docker build -t fastapi-api . + +# Run container +docker run -p 8000:8000 fastapi-api +``` + +## API Endpoints + +### Items +- `GET /items` - List all items (with pagination) +- `GET /items/{item_id}` - Get specific item +- `POST /items` - Create new item +- `PUT /items/{item_id}` - Update item +- `DELETE /items/{item_id}` - Delete item + +### Users +- `GET /users` - List all users +- `GET /users/{user_id}` - Get specific user +- `POST /users` - Create new user + +### Other +- `GET /` - API information +- `GET /health` - Health check +- `GET /info` - Service information +- `GET /stats` - API statistics + +## Documentation + +- Swagger UI: http://localhost:8000/docs +- ReDoc: http://localhost:8000/redoc +- OpenAPI JSON: http://localhost:8000/openapi.json + +## Example Requests + +### Create Item +```bash +curl -X POST "http://localhost:8000/items" \ + -H "Content-Type: application/json" \ + -d '{ + "id": 4, + "name": "Monitor", + "description": "4K Display", + "price": 299.99, + "in_stock": true + }' +``` + +### Get Items +```bash +curl "http://localhost:8000/items?skip=0&limit=10&in_stock=true" +``` + +### Get Statistics +```bash +curl "http://localhost:8000/stats" +``` diff --git a/api/main.py b/api/main.py new file mode 100644 index 0000000..56b6102 --- /dev/null +++ b/api/main.py @@ -0,0 +1,123 @@ +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel +from typing import List, Optional +import uvicorn +from datetime import datetime + +app = FastAPI( + title="API Demo Application", + description="Demo API with Swagger documentation", + version="1.0.0" +) + +# Models +class Item(BaseModel): + id: Optional[int] = None + name: str + description: Optional[str] = None + price: float + in_stock: bool = True + +class User(BaseModel): + id: Optional[int] = None + username: str + email: str + active: bool = True + +# In-memory storage +items_db = [ + {"id": 1, "name": "Laptop", "description": "High-performance laptop", "price": 999.99, "in_stock": True}, + {"id": 2, "name": "Mouse", "description": "Wireless mouse", "price": 29.99, "in_stock": True}, + {"id": 3, "name": "Keyboard", "description": "Mechanical keyboard", "price": 79.99, "in_stock": False}, +] + +users_db = [ + {"id": 1, "username": "john_doe", "email": "john@example.com", "active": True}, + {"id": 2, "username": "jane_smith", "email": "jane@example.com", "active": True}, +] + +# Root endpoint +@app.get("/") +async def root(): + """Root endpoint with API information""" + return { + "message": "Welcome to API Demo", + "version": "1.0.0", + "docs": "/docs", + "timestamp": datetime.now().isoformat() + } + +# Health check +@app.get("/health") +async def health(): + """Health check endpoint""" + return {"status": "healthy", "service": "api", "timestamp": datetime.now().isoformat()} + +# Items endpoints +@app.get("/items", response_model=List[Item], tags=["Items"]) +async def get_items(): + """Get all items""" + return items_db + +@app.get("/items/{item_id}", response_model=Item, tags=["Items"]) +async def get_item(item_id: int): + """Get a specific item by ID""" + item = next((item for item in items_db if item["id"] == item_id), None) + if item is None: + raise HTTPException(status_code=404, detail="Item not found") + return item + +@app.post("/items", response_model=Item, tags=["Items"]) +async def create_item(item: Item): + """Create a new item""" + new_id = max([i["id"] for i in items_db]) + 1 if items_db else 1 + item_dict = item.dict() + item_dict["id"] = new_id + items_db.append(item_dict) + return item_dict + +@app.put("/items/{item_id}", response_model=Item, tags=["Items"]) +async def update_item(item_id: int, item: Item): + """Update an existing item""" + for idx, existing_item in enumerate(items_db): + if existing_item["id"] == item_id: + item_dict = item.dict() + item_dict["id"] = item_id + items_db[idx] = item_dict + return item_dict + raise HTTPException(status_code=404, detail="Item not found") + +@app.delete("/items/{item_id}", tags=["Items"]) +async def delete_item(item_id: int): + """Delete an item""" + for idx, item in enumerate(items_db): + if item["id"] == item_id: + items_db.pop(idx) + return {"message": "Item deleted successfully"} + raise HTTPException(status_code=404, detail="Item not found") + +# Users endpoints +@app.get("/users", response_model=List[User], tags=["Users"]) +async def get_users(): + """Get all users""" + return users_db + +@app.get("/users/{user_id}", response_model=User, tags=["Users"]) +async def get_user(user_id: int): + """Get a specific user by ID""" + user = next((user for user in users_db if user["id"] == user_id), None) + if user is None: + raise HTTPException(status_code=404, detail="User not found") + return user + +@app.post("/users", response_model=User, tags=["Users"]) +async def create_user(user: User): + """Create a new user""" + new_id = max([u["id"] for u in users_db]) + 1 if users_db else 1 + user_dict = user.dict() + user_dict["id"] = new_id + users_db.append(user_dict) + return user_dict + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=8001) diff --git a/api/requirements.txt b/api/requirements.txt new file mode 100644 index 0000000..5313262 --- /dev/null +++ b/api/requirements.txt @@ -0,0 +1,3 @@ +fastapi==0.104.1 +uvicorn[standard]==0.24.0 +pydantic==2.5.0 diff --git a/web/.dockerignore b/web/.dockerignore new file mode 100644 index 0000000..e20135e --- /dev/null +++ b/web/.dockerignore @@ -0,0 +1,20 @@ +__pycache__ +*.pyc +*.pyo +*.pyd +.Python +*.so +*.egg +*.egg-info +dist +build +.git +.gitignore +README.md +site/ +.pytest_cache +.coverage +htmlcov +.env +.venv +venv/ diff --git a/web/Dockerfile b/web/Dockerfile new file mode 100644 index 0000000..7da11a0 --- /dev/null +++ b/web/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.11-slim + +WORKDIR /app + +# Copy requirements first for better caching +COPY requirements.txt . + +# Install dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# Copy application and documentation +COPY main.py . +COPY docs/ ./docs/ + +# Build documentation during image build +RUN mkdocs build -f docs/mkdocs.yml -d site + +# Expose port +EXPOSE 8000 + +# Run the application +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/web/README.md b/web/README.md new file mode 100644 index 0000000..2ea5d83 --- /dev/null +++ b/web/README.md @@ -0,0 +1,168 @@ +# Web Application with Documentation + +FastAPI web application serving a demo dashboard and comprehensive MkDocs documentation. + +## Features + +- **Web Dashboard**: Simple HTML interface with metrics display +- **Documentation Site**: Complete API7 Enterprise setup guide at `/docs` +- **Health Checks**: Monitoring endpoint at `/health` + +## Documentation + +The application includes comprehensive documentation built with MkDocs Material theme, covering: + +- **Architecture Overview**: Complete infrastructure and component details +- **Getting Started**: Quick setup and deployment guide +- **API7 Configuration**: Route and service configuration with examples +- **Kubernetes Resources**: Complete resource reference +- **CI/CD Pipeline**: Gitea Actions workflow documentation +- **Troubleshooting**: Common issues and solutions + +## Running Locally + +### Prerequisites + +```bash +pip install -r requirements.txt +``` + +### Start Application + +```bash +python main.py +``` + +**Access**: + +- Main Page: http://localhost:8000 +- Documentation: http://localhost:8000/docs/ +- Health Check: http://localhost:8000/health + +### Build Documentation Manually + +```bash +mkdocs build -f docs/mkdocs.yml -d site +``` + +## Docker + +### Build Image + +```bash +docker build -t web-app . +``` + +The Dockerfile: + +1. Installs Python dependencies +2. Copies application and documentation source +3. Builds static documentation site with MkDocs +4. Serves both the app and docs + +### Run Container + +```bash +docker run -p 8000:8000 web-app +``` + +## Kubernetes Deployment + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: web + namespace: api7ee +spec: + replicas: 2 + selector: + matchLabels: + app: web + template: + metadata: + labels: + app: web + spec: + containers: + - name: web + image: git.commandware.com/demos/api7-demo/web:main + ports: + - containerPort: 8000 + name: http + livenessProbe: + httpGet: + path: /health + port: 8000 + readinessProbe: + httpGet: + path: /health + port: 8000 +--- +apiVersion: v1 +kind: Service +metadata: + name: web-service + namespace: api7ee +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 8000 + name: http + selector: + app: web +``` + +## Documentation Structure + +``` +docs/ +β”œβ”€β”€ mkdocs.yml # MkDocs configuration +β”œβ”€β”€ index.md # Documentation home +β”œβ”€β”€ getting-started.md # Quick start guide +β”œβ”€β”€ architecture.md # Infrastructure architecture +β”œβ”€β”€ kubernetes-resources.md # K8s resources reference +β”œβ”€β”€ api7-configuration.md # API7 Gateway config guide +β”œβ”€β”€ cicd-pipeline.md # CI/CD documentation +└── troubleshooting.md # Troubleshooting guide +``` + +## Endpoints + +| Endpoint | Description | +| --------- | --------------------------- | +| `/` | Main web dashboard | +| `/docs/` | Documentation site (MkDocs) | +| `/health` | Health check endpoint | + +## CI/CD + +Images are automatically built and pushed to Gitea registry on every push: + +**Registry**: `git.commandware.com/demos/api7-demo/web:` + +See [CI/CD Pipeline documentation](docs/cicd-pipeline.md) for details. + +## Development + +### Update Documentation + +1. Edit markdown files in `docs/` directory +2. Test locally: + ```bash + mkdocs serve -f docs/mkdocs.yml + ``` +3. View at http://localhost:8001 +4. Rebuild with `mkdocs build` or rebuild Docker image + +### Dependencies + +- **fastapi**: Web framework +- **uvicorn**: ASGI server +- **mkdocs**: Documentation site generator +- **mkdocs-material**: Material theme for MkDocs + +--- + +_FastAPI web application with integrated MkDocs documentation for API7 Enterprise demo._ diff --git a/web/docs/api7-configuration.md b/web/docs/api7-configuration.md new file mode 100644 index 0000000..a0d28ff --- /dev/null +++ b/web/docs/api7-configuration.md @@ -0,0 +1,615 @@ +# 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 + +```bash +# Install the gateway CLI tool +# Installation method varies by gateway solution + +# Verify installation + version +``` + +### Configuration Structure + +```yaml +services: + - name: + upstream: + name: + scheme: http|https + type: roundrobin|chash|least_conn|ewma + # Option 1: Static nodes + nodes: + - host: + port: + weight: <1-100> + # Option 2: Service discovery + discovery_type: kubernetes + service_name: /: + routes: + - name: + priority: + uris: + - + hosts: + - + methods: + - GET|POST|PUT|DELETE|... + plugins: + : + + +ssls: + - snis: + - + certificates: + - certificate: | + + 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: + ``` + +**RBAC Setup**: +```bash +kubectl create clusterrolebinding gateway-discovery \ + --clusterrole=view \ + --serviceaccount=:default +``` + +**Service Configuration**: +```yaml +upstream: + discovery_type: kubernetes + service_name: /: + # Format: /: +``` + +### Static Nodes (No Service Discovery) + +```yaml +upstream: + nodes: + - host: web-service..svc.cluster.local + port: 80 + weight: 100 + - host: + port: 80 + weight: 100 +``` + +## Route Configuration + +### Basic Route + +```yaml +routes: + - name: web-route + uris: + - /* + hosts: + - app.domain.com + methods: + - GET + - POST + plugins: + redirect: + http_to_https: true +``` + +### Path-Based Routing with Priorities + +```yaml +services: + - name: api-service + upstream: + discovery_type: kubernetes + service_name: /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: /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 + +```yaml +routes: + - name: wildcard-route + uris: + - /* + hosts: + - "*.domain.com" + - domain.com +``` + +### Multiple Hosts + +```yaml +routes: + - name: multi-host-route + uris: + - /* + hosts: + - api.domain.com + - api.domain.org + - api.example.com +``` + +## Plugins + +### HTTP to HTTPS Redirect + +```yaml +plugins: + redirect: + http_to_https: true +``` + +### Proxy Rewrite (Path Manipulation) + +**Strip prefix**: +```yaml +plugins: + proxy-rewrite: + regex_uri: + - ^/api/(.*) + - /$1 +``` + +**Add prefix**: +```yaml +plugins: + proxy-rewrite: + uri: /backend$uri +``` + +**Rewrite host**: +```yaml +plugins: + proxy-rewrite: + host: backend-service..svc.cluster.local +``` + +### CORS Configuration + +```yaml +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**: +```yaml +plugins: + limit-req: + rate: 100 + burst: 200 + key: remote_addr + rejected_code: 429 +``` + +**Per Consumer**: +```yaml +plugins: + limit-req: + rate: 1000 + burst: 2000 + key: consumer_name +``` + +### Authentication + +**API Key**: +```yaml +plugins: + key-auth: + header: X-API-Key +``` + +**JWT**: +```yaml +plugins: + jwt-auth: + key: my-secret-key + algorithm: HS256 +``` + +**Basic Auth**: +```yaml +plugins: + basic-auth: {} +``` + +### Request/Response Transformation + +**Add headers**: +```yaml +plugins: + proxy-rewrite: + headers: + X-Forwarded-By: "API-Gateway" + X-Custom-Header: "value" +``` + +**Remove headers**: +```yaml +plugins: + response-rewrite: + headers: + remove: + - X-Internal-Header +``` + +### Caching + +```yaml +plugins: + proxy-cache: + cache_method: + - GET + - HEAD + cache_http_status: + - 200 + - 301 + - 302 + cache_ttl: 3600 +``` + +### IP Restriction + +**Whitelist**: +```yaml +plugins: + ip-restriction: + whitelist: + - 192.168.1.0/24 + - 10.0.0.0/8 +``` + +**Blacklist**: +```yaml +plugins: + ip-restriction: + blacklist: + - 203.0.113.0/24 +``` + +## SSL/TLS Configuration + +### Using Existing Kubernetes Secret + +```yaml +ssls: + - snis: + - "*.domain.com" + - domain.com + certificates: + - certificate: | + -----BEGIN CERTIFICATE----- + + -----END CERTIFICATE----- + key: | + -----BEGIN PRIVATE KEY----- + + -----END PRIVATE KEY----- +``` + +### Extract from Kubernetes Secret + +```bash +# Extract certificate +kubectl get secret tls-secret -n -o jsonpath='{.data.tls\.crt}' | base64 -d + +# Extract key +kubectl get secret tls-secret -n -o jsonpath='{.data.tls\.key}' | base64 -d +``` + +## Configuration Examples + +### Multiple Service Routes + +**Configuration**: +```yaml +services: + - name: frontend-service + upstream: + name: frontend-upstream + scheme: http + type: roundrobin + nodes: + - host: frontend-service..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..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**: +```bash + sync -f config.yaml \ + --server \ + --token \ + --gateway-group default +``` + +**Dump current configuration**: +```bash + dump \ + --server \ + --token > current-config.yaml +``` + +**Validate configuration**: +```bash + 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**: +```bash +# Sync to dev gateway group + sync -f config.yaml \ + --gateway-group dev \ + --server \ + --token +``` + +**Production Gateway Group**: +```bash +# Sync to prod gateway group + sync -f config.yaml \ + --gateway-group prod \ + --server \ + --token +``` + +### Health Checks + +```yaml +upstream: + checks: + active: + http_path: /health + healthy: + interval: 5 + successes: 2 + unhealthy: + interval: 5 + http_failures: 3 +``` + +### Retry Policy + +```yaml +upstream: + retries: 3 + retry_timeout: 10 + pass_host: pass # or rewrite, node +``` + +### Circuit Breaker + +```yaml +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: **Monitoring** β†’ **Routes** +2. Select route to view: + - Request rate (req/s) + - Latency percentiles (P50, P95, P99) + - Error rate + - Status code distribution + +### Prometheus Metrics + +Access Prometheus: +```bash +kubectl port-forward -n svc/prometheus-server 9090:9090 +``` + +**Useful Queries**: +```promql +# 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 + +```bash +# Check gateway logs +kubectl logs -n -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 + +```bash +# Verify service +kubectl get svc -n + +# Check endpoints +kubectl get endpoints -n +``` + +### Configuration Not Applied + +**Check**: +1. βœ… CLI sync succeeded +2. βœ… Routes are published +3. βœ… Gateway group matches + +```bash +# Dump and compare + dump --server --token > current.yaml +diff config.yaml current.yaml +``` + +--- + +*Complete configuration reference for API Gateway infrastructure.* diff --git a/web/docs/architecture.md b/web/docs/architecture.md new file mode 100644 index 0000000..961bbe7 --- /dev/null +++ b/web/docs/architecture.md @@ -0,0 +1,283 @@ +# Architecture Overview + +## Infrastructure Architecture + +``` +Internet + ↓ +Load Balancer (External IP) + ↓ +Ingress Controller + ↓ +TLS Termination (Wildcard Certificate) + ↓ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Gateway Ingress β”‚ +β”‚ (*.domain.com / domain.com) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + ↓ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Gateway Service (ClusterIP) β”‚ +β”‚ gateway-service (Internal IP) β”‚ +β”‚ Ports: 80 (β†’9080), 443 (β†’9443) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + ↓ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Gateway Pods (Multiple Replicas) β”‚ +β”‚ - gateway-pod-1 β”‚ +β”‚ - gateway-pod-2 β”‚ +β”‚ - gateway-pod-3 β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + ↓ +[Route Matching & Service Discovery] + ↓ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Backend β”‚ Backend β”‚ +β”‚ Services β”‚ Services β”‚ +β”‚ (ClusterIP) β”‚ (ClusterIP) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + ↓ +Application Pods +``` + +## Component Details + +### 1. External Access Layer + +**Load Balancer** +- Provides external IP address +- Supports LoadBalancer service type +- Exposes Ingress Controller to the internet + +**Ingress Controller** +- Handles HTTP/HTTPS traffic +- TLS termination point +- Routes to appropriate backend services + +### 2. Control Plane + +**Deployment Method**: Helm Chart +**Namespace**: Dedicated namespace for gateway components + +#### Components + +**Dashboard** +- **Function**: Web UI for gateway management +- **Service Type**: ClusterIP +- **Ports**: Management ports (HTTP/HTTPS) +- **Replicas**: Configurable + +**Developer Portal** +- **Function**: API documentation and developer access +- **Service Type**: ClusterIP +- **Ports**: Web service port +- **Replicas**: Configurable + +**Data Plane Manager** +- **Function**: Data Plane management and configuration distribution +- **Service Type**: ClusterIP +- **Ports**: Management and proxy ports +- **Replicas**: Configurable + +**PostgreSQL Database** +- **Function**: Configuration and metadata storage +- **Service Type**: ClusterIP +- **Port**: 5432/TCP +- **Storage**: Persistent volume with configurable size +- **Deployment**: StatefulSet for data persistence + +**Prometheus Server** +- **Function**: Metrics collection and monitoring +- **Service Type**: ClusterIP +- **Port**: 9090/TCP +- **Storage**: Persistent volume for metrics retention + +### 3. Gateway Data Plane + +**Deployment Method**: Helm Chart +**High Availability**: Multiple replicas for fault tolerance + +#### Gateway Deployment + +- **Replicas**: Configurable (recommended: 3+) +- **Strategy**: RollingUpdate for zero-downtime deployments +- **Max Unavailable**: 25% during updates + +**Gateway Groups**: +- Logical grouping of gateway instances +- Environment-based separation (dev/staging/prod) +- Independent configuration per group + +#### Gateway Service + +- **Type**: ClusterIP for internal routing +- **Ports**: + - HTTP: 80/TCP β†’ 9080/TCP + - HTTPS: 443/TCP β†’ 9443/TCP + +#### Gateway Configuration + +**Configuration Store**: +- **Connection**: Secure connection to control plane +- **TLS**: Mutual authentication enabled +- **Certificates**: Managed via Kubernetes secrets + +**Configuration Volumes**: +- Gateway configuration via ConfigMap +- TLS certificates for secure communication +- Service discovery configuration + +### 4. Ingress Configuration + +**Gateway Ingress Resource** + +```yaml +Hosts: + - *.domain.com + - domain.com + +Backend: + Service: gateway-service + Port: 80 + +TLS: + - hosts: + - *.domain.com + - domain.com + secretName: wildcard-tls-secret +``` + +**Access Points**: +- External IP: Provided by Load Balancer +- Protocols: HTTP (80), HTTPS (443) +- Ingress Class: Configurable + +### 5. Storage Architecture + +**Persistent Volumes**: + +| Component | Recommended Size | Usage | +|-----------|-----------------|-------| +| PostgreSQL Database | 10Gi+ | Configuration and metadata storage | +| Prometheus Metrics | 100Gi+ | Time-series metrics retention | +| Configuration Store | 8Gi per node | Distributed configuration (if using etcd) | + +**Storage Classes**: +- Distributed storage for database persistence +- Local or network storage for metrics +- High-performance storage for configuration + +## Network Flow + +### External Request Flow + +1. **Client Request** β†’ Domain URL (HTTP/HTTPS) +2. **DNS Resolution** β†’ External Load Balancer IP +3. **Ingress Controller** β†’ TLS termination with wildcard certificate +4. **Ingress Routing** β†’ Gateway service endpoint +5. **Gateway Service** β†’ Load balances across gateway pod replicas +6. **Route Matching** β†’ Gateway evaluates routes based on host/path/priority +7. **Service Discovery** β†’ Gateway fetches backend endpoints from Kubernetes +8. **Backend Request** β†’ Proxies to backend service pods +9. **Response** β†’ Returns through the chain to client + +### Control Plane Communication + +1. **Dashboard** β†’ Database (configuration storage) +2. **Dashboard** β†’ Data Plane Manager (gateway group management) +3. **Data Plane Manager** β†’ Configuration store (configuration distribution) +4. **Gateway Pods** β†’ Control plane endpoint (fetch routes/services) +5. **Prometheus** β†’ Gateway Pods (scrape metrics) + +## Security Architecture + +### TLS/SSL Configuration + +**External TLS** (Ingress Layer): +- **Certificate**: Wildcard certificate (Let's Encrypt or commercial) +- **Secret**: Kubernetes TLS secret +- **Domains**: Wildcard and root domain support + +**Internal TLS** (Control Plane): +- **Dashboard**: Secure HTTPS access +- **Developer Portal**: Encrypted portal access +- **Data Plane Manager**: Secure management interface + +**Gateway Communication TLS**: +- **Mutual TLS**: Enabled for secure communication +- **CA Certificate**: Certificate authority validation +- **Client Certificates**: Individual component authentication + +### Service Accounts & RBAC + +**Gateway Service Account**: Dedicated service account per namespace + +**Required Permissions**: +- `list/watch` endpoints (for service discovery) +- Read access to services and pods +- Typically bound to appropriate ClusterRole + +## High Availability + +### Gateway Layer +- **Multiple replicas** for fault tolerance (3+ recommended) +- **RollingUpdate** strategy for zero-downtime deployments +- **Load balancing** across all healthy instances + +### Control Plane +- **Database**: StatefulSet with persistent storage +- **Monitoring**: Persistent metrics storage +- **Management Components**: Stateless, scalable replicas + +### Storage +- **Database**: Distributed or replicated storage +- **Metrics**: Persistent volume with retention policy +- **Configuration**: Highly available storage backend + +## Monitoring & Observability + +**Metrics Collection**: +- Time-series metrics from all gateway pods +- Persistent storage for historical data +- Query interface for metrics analysis + +**Gateway Metrics**: +- HTTP request rates and throughput +- Latency percentiles (p50, p95, p99) +- Error rates and status codes +- Active connections and concurrency +- Upstream service health status + +**Health Checks**: +- Gateway readiness and liveness probes +- Service health endpoints +- Automated recovery mechanisms + +## Scalability Considerations + +**Horizontal Scaling**: +- Gateway pods: Scale based on traffic patterns +- Backend services: Auto-scaling based on metrics +- Control plane: Scale management components as needed + +**Vertical Scaling**: +- Database: Expand storage as data grows +- Metrics storage: Adjust retention and volume size +- Gateway resources: Tune CPU/memory for performance + +## Configuration Management + +**Gateway Configuration**: +- **Source**: Dashboard UI or CLI tools +- **Storage**: Centralized database +- **Distribution**: Control plane to data plane synchronization +- **Format**: YAML configuration or Web-based management + +**Kubernetes Resources**: +- **Deployment**: Helm charts for standardized installation +- **Management**: Kubernetes-native resource management +- **Namespaces**: Logical separation of environments + +--- + +*This architecture provides enterprise-grade API Gateway capabilities with high availability, scalability, and comprehensive monitoring.* diff --git a/web/docs/cicd-pipeline.md b/web/docs/cicd-pipeline.md new file mode 100644 index 0000000..e66ada3 --- /dev/null +++ b/web/docs/cicd-pipeline.md @@ -0,0 +1,477 @@ +# CI/CD Pipeline + +Automated build and deployment pipeline using Git-based CI/CD systems. + +## Overview + +The CI/CD pipeline automatically builds Docker images and pushes them to the container registry whenever code is pushed to any branch. + +**Repository**: Git repository with application code + +**Registry**: Container registry for Docker images + +## Pipeline Architecture + +``` +Git Push (any branch) + ↓ +CI/CD System Trigger + ↓ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Job: build-web (parallel) β”‚ +β”‚ Job: build-api (parallel) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + ↓ ↓ +Build Web Image Build API Image + ↓ ↓ +Tag with branch Tag with branch + ↓ ↓ +Push to Registry Push to Registry + ↓ ↓ +/web: +/api: +``` + +## Workflow Configuration + +**Location**: CI/CD workflow files (`.github/workflows/`, `.gitlab-ci.yml`, etc.) + +```yaml +name: Build and Push Docker Images + +on: + push: + workflow_dispatch: + +jobs: + build-web: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Container Registry + uses: docker/login-action@v3 + with: + registry: + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_TOKEN }} + + - name: Extract metadata for web image + id: meta-web + uses: docker/metadata-action@v5 + with: + images: /web + tags: | + type=ref,event=branch + + - name: Build and push web image + uses: docker/build-push-action@v5 + with: + context: ./web + file: ./web/Dockerfile + push: true + tags: ${{ steps.meta-web.outputs.tags }} + labels: ${{ steps.meta-web.outputs.labels }} + cache-from: type=registry,ref=/web:buildcache + cache-to: type=registry,ref=/web:buildcache,mode=max + + build-api: + runs-on: ubuntu-latest + steps: + # Similar steps for API application + ... +``` + +## Trigger Events + +### Automatic Triggers + +**Push to any branch**: +```bash +git push origin +``` + +Images tagged with branch name: +- `/web:` +- `/api:` + +### Manual Trigger + +**Via CI/CD Interface**: +1. Go to repository β†’ **CI/CD** or **Actions** +2. Select workflow: **Build and Push Docker Images** +3. Click: **Run workflow** +4. Select branch +5. Click: **Run** + +**Via Git**: +```bash +# Trigger workflow with empty commit +git commit --allow-empty -m "Trigger CI/CD pipeline" +git push +``` + +## Setup Instructions + +### 1. Create Registry Token + +**Generate Token**: +1. Go to: **User Settings** or **Access Tokens** +2. Click: **Generate New Token** +3. Name: `container-registry` +4. Select appropriate permissions: + - βœ… Write/push access (required) + - βœ… Read/pull access (required) +5. Click: **Generate Token** +6. **Copy token** (shown once only) + +### 2. Add Repository Secret + +**In Repository Settings**: +1. Go to: **Repository β†’ Settings β†’ Secrets/Variables** +2. Click: **Add Secret** +3. Add required secrets: + - `REGISTRY_TOKEN`: Token from step 1 + - `REGISTRY_USER`: Username +4. Click: **Save** + +### 3. Verify Workflow + +**Check workflow file exists**: +```bash +ls -la .github/workflows/ # or appropriate CI/CD directory +``` + +**Push to trigger**: +```bash +git add . +git commit -m "Test CI/CD pipeline" +git push origin main +``` + +**Monitor execution**: +1. Go to repository β†’ **CI/CD** or **Actions** +2. Click on the running workflow +3. View logs for each job + +## Image Naming Convention + +**Format**: `//:` + +**Examples**: +- `/web:main` +- `/web:develop` +- `/web:feature-xyz` +- `/api:main` + +## Using Built Images in Kubernetes + +### 1. Pull Images from Container Registry + +**Create registry secret**: +```bash +kubectl create secret docker-registry registry-secret \ + --docker-server= \ + --docker-username= \ + --docker-password= \ + -n +``` + +### 2. Update Deployment + +**deployment.yaml**: +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: web + namespace: +spec: + template: + spec: + imagePullSecrets: + - name: registry-secret + containers: + - name: web + image: /web:main + imagePullPolicy: Always +``` + +### 3. Deploy to Kubernetes + +```bash +kubectl apply -f deployment.yaml +``` + +### 4. Rollout New Version + +**After pipeline builds new image**: + +```bash +# Force rollout restart (pulls latest image with same tag) +kubectl rollout restart deployment/web -n +kubectl rollout restart deployment/api -n + +# Check rollout status +kubectl rollout status deployment/web -n +``` + +**Or update image explicitly**: +```bash +kubectl set image deployment/web \ + web=/web:main \ + -n + +kubectl set image deployment/api \ + api=/api:main \ + -n +``` + +## Docker Layer Caching + +The pipeline uses Docker layer caching to speed up builds: + +**Cache Configuration**: +```yaml +cache-from: type=registry,ref=/web:buildcache +cache-to: type=registry,ref=/web:buildcache,mode=max +``` + +**Benefits**: +- Faster builds (reuses unchanged layers) +- Reduced build time from ~3min to ~30sec +- Lower resource usage + +**Cache Location**: Stored in registry as special tag `:buildcache` + +## Parallel Builds + +Both applications build in parallel: + +``` +Start + β”œβ”€β†’ build-web job (3-5 min) + └─→ build-api job (3-5 min) + ↓ + Complete (~5 min total) +``` + +Without parallelization: ~10 minutes +With parallelization: ~5 minutes + +## Viewing Build Logs + +### Via CI/CD Interface + +1. Repository β†’ **CI/CD** or **Actions** +2. Click on workflow run +3. Select job (`build-web` or `build-api`) +4. View step-by-step logs + +### Via CLI (if available) + +```bash +# List workflow runs + list runs + +# View specific run logs + view run +``` + +## Troubleshooting + +### Build Fails: Authentication Error + +**Error**: `unauthorized: authentication required` + +**Solution**: +1. Verify registry secrets exist in repository settings +2. Check token has appropriate permissions +3. Regenerate token if expired + +```bash +# Test token manually +docker login -u -p +``` + +### Build Fails: Dockerfile Not Found + +**Error**: `unable to prepare context: unable to evaluate symlinks in Dockerfile path` + +**Solution**: +1. Check Dockerfile exists in correct location: + - `web/Dockerfile` + - `api/Dockerfile` +2. Verify workflow context path matches: + ```yaml + context: ./web + file: ./web/Dockerfile + ``` + +### Image Pull Fails in Kubernetes + +**Error**: `ImagePullBackOff` + +**Solution**: +1. Verify registry secret exists: + ```bash + kubectl get secret registry-secret -n + ``` + +2. Check secret is referenced in deployment: + ```yaml + spec: + template: + spec: + imagePullSecrets: + - name: registry-secret + ``` + +3. Test manual pull: + ```bash + docker pull /web:main + ``` + +### Workflow Doesn't Trigger + +**Check**: +1. βœ… Workflow file in appropriate CI/CD directory +2. βœ… File is named correctly (`.yml` or `.yaml`) +3. βœ… File is committed and pushed to repository +4. βœ… CI/CD is enabled in repository settings + +**Force trigger**: +```bash +git commit --allow-empty -m "Trigger workflow" +git push +``` + +## Best Practices + +### Version Tagging + +**For production deployments**: +```bash +# Tag release +git tag -a v1.0.0 -m "Release v1.0.0" +git push origin v1.0.0 +``` + +**Update workflow for semantic versioning**: +```yaml +tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} +``` + +### Branch Strategy + +**Recommended**: +- `main` β†’ production images +- `develop` β†’ staging images +- `feature/*` β†’ development images + +**Kubernetes deployments**: +```yaml +# Production +image: /web:main + +# Staging +image: /web:develop + +# Development +image: /web:feature-xyz +``` + +### Security + +**Protect main branch**: +1. Repository Settings β†’ **Branches** or **Protected Branches** +2. Add branch protection for `main` +3. Require pull/merge request reviews +4. Enable status checks + +**Rotate tokens regularly**: +- Generate new registry token every 90 days +- Update secrets in repository settings + +## Advanced Configuration + +### Multi-Stage Builds + +Optimize Dockerfile for smaller images: + +```dockerfile +# Build stage +FROM python:3.11-slim AS builder +WORKDIR /app +COPY requirements.txt . +RUN pip install --user --no-cache-dir -r requirements.txt + +# Runtime stage +FROM python:3.11-slim +WORKDIR /app +COPY --from=builder /root/.local /root/.local +COPY . . +ENV PATH=/root/.local/bin:$PATH +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] +``` + +### Build Arguments + +Pass build-time variables: + +```yaml +- name: Build and push + uses: docker/build-push-action@v5 + with: + build-args: | + VERSION=${{ github.sha }} + BUILD_DATE=${{ github.event.head_commit.timestamp }} +``` + +### Matrix Builds + +Build for multiple platforms: + +```yaml +strategy: + matrix: + platform: [linux/amd64, linux/arm64] + +- name: Build and push + uses: docker/build-push-action@v5 + with: + platforms: ${{ matrix.platform }} +``` + +## Monitoring Pipeline + +### Metrics to Track + +- βœ… Build success rate +- βœ… Average build time +- βœ… Cache hit rate +- βœ… Image size trends + +### Notifications + +**Add Discord/Slack notifications** (example): + +```yaml +- name: Notify on failure + if: failure() + run: | + curl -X POST ${{ secrets.WEBHOOK_URL }} \ + -H 'Content-Type: application/json' \ + -d '{"content":"Build failed for ${{ github.ref }}"}' +``` + +--- + +*Automated CI/CD pipeline for building and deploying containerized applications.* diff --git a/web/docs/getting-started.md b/web/docs/getting-started.md new file mode 100644 index 0000000..86bf5fb --- /dev/null +++ b/web/docs/getting-started.md @@ -0,0 +1,432 @@ +# Getting Started + +Quick start guide for working with the API Gateway infrastructure and applications. + +## Prerequisites + +- Access to Kubernetes cluster with `kubectl` configured +- Access to Gateway Dashboard +- CLI tools installed (optional, for command-line configuration) +- Git repository access for application code + +## Quick Start - Local Development + +### 1. Clone Repository + +```bash +git clone +cd +``` + +### 2. Run Applications Locally + +**Web Application**: +```bash +cd web +pip install -r requirements.txt +python main.py +# Access at http://localhost:8000 +``` + +**API Application**: +```bash +cd api +pip install -r requirements.txt +python main.py +# Swagger UI at http://localhost:8000/docs +``` + +### 3. Build Docker Images + +```bash +# Web application +docker build -t web-app ./web + +# API application +docker build -t api-app ./api +``` + +## Deploying to Kubernetes + +### 1. Prepare Namespace + +```bash +# Create namespace if it doesn't exist +kubectl create namespace + +# Verify gateway components are running +kubectl get pods -n +``` + +**Expected Components**: +- βœ… Dashboard pod running +- βœ… Developer Portal pod running +- βœ… Data Plane Manager pod running +- βœ… Gateway pods running (multiple replicas) +- βœ… Database pod running + +### 2. Create Kubernetes Manifests + +**deployment.yaml**: +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: web + namespace: +spec: + replicas: 2 + selector: + matchLabels: + app: web + template: + metadata: + labels: + app: web + spec: + containers: + - name: web + image: /web:latest + ports: + - containerPort: 8000 + name: http + livenessProbe: + httpGet: + path: /health + port: 8000 + readinessProbe: + httpGet: + path: /health + port: 8000 +--- +apiVersion: v1 +kind: Service +metadata: + name: web-service + namespace: +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 8000 + name: http + selector: + app: web +``` + +### 3. Deploy Applications + +```bash +kubectl apply -f deployment.yaml + +# Check deployment status +kubectl get deployments -n +kubectl get pods -n -l app=web +``` + +### 4. Configure Container Registry Access (if needed) + +```bash +# Create registry secret +kubectl create secret docker-registry registry-secret \ + --docker-server= \ + --docker-username= \ + --docker-password= \ + -n + +# Add to deployment +spec: + template: + spec: + imagePullSecrets: + - name: registry-secret +``` + +## Configuring Gateway Routes + +### Method 1: Using CLI Tools + +**1. Create configuration file** (`config.yaml`): + +```yaml +services: + - name: web-service + upstream: + name: web-upstream + scheme: http + type: roundrobin + discovery_type: kubernetes + service_name: /web-service:http + routes: + - name: web-route + uris: + - /* + hosts: + - app.domain.com + plugins: + redirect: + http_to_https: true +``` + +**2. Sync configuration**: + +```bash + sync -f config.yaml \ + --server \ + --token \ + --gateway-group default +``` + +**3. Verify sync**: +```bash +# Expected output: +[CLI] β€Ί βœ” success Create service: "web-service" +[CLI] β€Ί βœ” success Create route: "web-route" +``` + +### Method 2: Using Dashboard Web UI + +**1. Access Dashboard**: +- URL: Gateway Dashboard URL +- Login with credentials + +**2. Configure Service Discovery** (one-time setup): +- Navigate: **Settings β†’ Service Registry** +- Click: **Add Service Registry** +- Select: **Kubernetes** +- Configure: + ``` + Name: kubernetes-cluster + API Server: https://kubernetes.default.svc.cluster.local:443 + Token Path: /var/run/secrets/kubernetes.io/serviceaccount/token + Namespace Filter: + ``` +- Save and verify status shows "Connected" + +**3. Create Service**: +- Navigate: **Services** +- Click: **Create Service** +- Name: `web-service` +- Upstream Type: **Service Discovery** +- Discovery Type: **Kubernetes** +- Service Name: `/web-service:http` + +**4. Create Route**: +- In the service page, go to **Routes** tab +- Click: **Create Route** +- Name: `web-route` +- Host: `app.domain.com` +- Path: `/*` +- Methods: GET, POST, PUT, DELETE +- Add Plugin: **redirect** β†’ `http_to_https: true` + +**5. Publish Route**: +- Find route in the Routes tab +- Click: **Publish** +- Select gateway group: **default** +- Confirm + +## Creating Ingress for External Access + +**ingress.yaml**: +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: app-ingress + namespace: +spec: + ingressClassName: nginx + tls: + - hosts: + - app.domain.com + secretName: app-tls + rules: + - host: app.domain.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: gateway-service + port: + number: 80 +``` + +**Important**: Backend points to Gateway service, not application service directly. + +```bash +kubectl apply -f ingress.yaml +``` + +## Verifying Service Discovery RBAC + +Gateway needs permissions to discover Kubernetes services: + +```bash +# Check current permissions +kubectl auth can-i list endpoints --as=system:serviceaccount::default -n + +# If needed, create ClusterRoleBinding +kubectl create clusterrolebinding gateway-discovery \ + --clusterrole=view \ + --serviceaccount=:default +``` + +## Testing the Deployment + +### 1. Test DNS Resolution + +```bash +# Add to /etc/hosts or configure DNS +echo " app.domain.com" | sudo tee -a /etc/hosts +``` + +### 2. Test HTTP to HTTPS Redirect + +```bash +curl -I http://app.domain.com + +# Expected: +# HTTP/1.1 301 Moved Permanently +# Location: https://app.domain.com +``` + +### 3. Test Application Access + +```bash +# Web application +curl https://app.domain.com + +# API health check +curl https://app.domain.com/api/health +``` + +### 4. Verify Service Discovery + +```bash +# Scale deployment +kubectl scale deployment web -n --replicas=5 + +# Check endpoints +kubectl get endpoints -n web-service + +# Gateway automatically discovers all 5 pod endpoints +# No configuration change needed +``` + +## Accessing Gateway Dashboard + +### Local Access (port-forward) + +```bash +kubectl port-forward -n svc/dashboard-service 7080:7080 + +# Access at http://localhost:7080 +``` + +### Public Access + +Direct access via configured URLs: +- **Dashboard**: Management interface URL +- **Developer Portal**: Developer portal URL + +## CI/CD Pipeline Setup + +### 1. Configure Repository Token + +In repository settings: +1. Go to **Settings β†’ Secrets** +2. Add authentication token +3. Configure with appropriate permissions +4. Enable container registry access + +### 2. Push to Trigger Build + +```bash +git add . +git commit -m "Deploy applications" +git push origin main +``` + +The pipeline will: +- Build Docker images +- Push to container registry +- Tag with branch/version + +### 3. Update Kubernetes Deployment + +```bash +# Manually trigger rollout +kubectl rollout restart deployment/web -n +kubectl rollout restart deployment/api -n + +# Or update image in deployment +kubectl set image deployment/web web=/web:latest -n +``` + +## Common Tasks + +### View Logs + +```bash +# Application logs +kubectl logs -n -l app=web --tail=50 -f + +# Gateway logs +kubectl logs -n -l app.kubernetes.io/name=gateway --tail=50 -f + +# Dashboard logs +kubectl logs -n -l app=dashboard --tail=50 -f +``` + +### Check Route Configuration + +**Via CLI**: +```bash + dump \ + --server \ + --token +``` + +**Via Dashboard**: +- Navigate: **Services β†’ β†’ Routes** +- View route details and publication status + +### Update Route Configuration + +```bash +# Edit config file +vim config.yaml + +# Sync changes + sync -f config.yaml \ + --server \ + --token \ + --gateway-group default +``` + +### Monitor Gateway Metrics + +**Prometheus**: +```bash +kubectl port-forward -n svc/prometheus-server 9090:9090 + +# Access at http://localhost:9090 +``` + +**Dashboard Metrics**: +- Navigate: **Monitoring** in Gateway Dashboard +- View request rates, latency, error rates + +## Next Steps + +- [Configure advanced routing](api7-configuration.md) +- [Set up monitoring and alerts](monitoring.md) +- [Review troubleshooting guide](troubleshooting.md) +- [Learn about the architecture](architecture.md) + +--- + +*You're now ready to deploy and manage applications with the API Gateway infrastructure!* diff --git a/web/docs/index.md b/web/docs/index.md new file mode 100644 index 0000000..1e51d3d --- /dev/null +++ b/web/docs/index.md @@ -0,0 +1,82 @@ +# API Gateway Infrastructure - Documentation + +Welcome to the API Gateway infrastructure documentation. This guide covers the complete setup and configuration of the API Gateway system. + +## Overview + +This documentation provides comprehensive information about: + +- **Architecture**: Understanding the API Gateway setup +- **Applications**: Backend applications integration (Web & API) +- **Configuration**: Gateway routes, services, and policies +- **Deployment**: CI/CD pipeline automation +- **Operations**: Monitoring, troubleshooting, and maintenance + +## Quick Links + +- [Architecture Overview](architecture.md) +- [Getting Started](getting-started.md) +- [Gateway Configuration](api7-configuration.md) +- [Kubernetes Resources](kubernetes-resources.md) +- [CI/CD Pipeline](cicd-pipeline.md) +- [Troubleshooting Guide](troubleshooting.md) + +## Infrastructure Components + +### Gateway Control Plane + +**Control Plane Components** +- Dashboard: Web-based management interface +- Developer Portal: API documentation and testing portal +- DP Manager: Data plane management service +- PostgreSQL Database: Configuration storage +- Prometheus Monitoring: Metrics collection + +**Gateway Data Plane** +- Multiple replicas for high availability +- ClusterIP service for internal communication +- Gateway Groups for logical organization +- External access via Ingress Controller + +### Applications + +- **Web Application**: Frontend application interface +- **API Application**: Backend REST API services + +### Domain Configuration + +- **Wildcard Domain**: Support for subdomains +- **Root Domain**: Primary domain access +- **TLS**: Automated certificate management + +## Technology Stack + +- **API Gateway**: Enterprise API Gateway Solution +- **Control Plane**: Centralized management interface +- **Data Plane**: High-performance request processing +- **Container Orchestration**: Kubernetes +- **Ingress Controller**: External traffic management +- **Certificate Management**: Automated TLS certificates +- **CI/CD**: Automated deployment pipeline +- **Applications**: Microservices architecture +- **Documentation**: Technical documentation system + +## Repository Structure + +**Components**: +- Web application container images +- API service container images +- Configuration management +- Infrastructure as Code + +## Getting Help + +For issues or questions: + +1. Check the [Troubleshooting Guide](troubleshooting.md) +2. Review the gateway documentation +3. Check application logs in the container platform + +--- + +*Documentation Version: 1.0* diff --git a/web/docs/kubernetes-resources.md b/web/docs/kubernetes-resources.md new file mode 100644 index 0000000..e3526fd --- /dev/null +++ b/web/docs/kubernetes-resources.md @@ -0,0 +1,446 @@ +# Kubernetes Resources + +Complete reference of all Kubernetes resources for the API Gateway deployment. + +## Namespace Overview + +**Namespace**: Dedicated namespace for gateway components +**Environment Separation**: Development, Staging, Production +**Resource Organization**: Logical grouping by function + +## Helm Releases + +### Control Plane Release + +**Release Components**: +- **Chart**: Control plane helm chart +- **Status**: Deployed +- **Management**: Dashboard, Portal, Data Plane Manager + +**Key Configuration**: +```yaml +dashboard_configuration: + database: + dsn: postgres://username:***@postgresql-service:5432/dbname + +postgresql: + auth: + password: *** + primary: + persistence: + size: 10Gi + readReplicas: + persistence: + size: 10Gi +``` + +### Data Plane Release + +**Release Components**: +- **Chart**: Gateway data plane helm chart +- **Status**: Deployed +- **Function**: Request processing and routing + +**Key Configuration**: +```yaml +gateway: + extraEnvVars: + - name: GATEWAY_GROUP_ID + value: default + replicaCount: 3 + +configuration: + auth: + tls: + enabled: true + existingSecret: gateway-tls-secret + verify: true + endpoint: + - https://control-plane-endpoint:port + +service: + type: ClusterIP + tls: + existingCASecret: gateway-tls-secret +``` + +## Deployments + +### Dashboard + +**Specification**: +```yaml +Replicas: 1 (configurable) +Selector: app=dashboard +Ports: Management ports (HTTP/HTTPS) +``` + +### Developer Portal + +**Specification**: +```yaml +Replicas: 1 (configurable) +Selector: app=developer-portal +Ports: Web service port +``` + +### Data Plane Manager + +**Specification**: +```yaml +Replicas: 1 (configurable) +Selector: app=dp-manager +Ports: Management and proxy ports +``` + +### Gateway Data Plane + +**Specification**: +```yaml +Replicas: 3+ (highly available) +Strategy: RollingUpdate (25% max unavailable) +Selector: app.kubernetes.io/name=gateway +Ports: 9080 (HTTP), 9443 (HTTPS) + +Volumes: +- gateway-config (ConfigMap) +- tls-certificates (Secret) +- client-certificates (Secret) + +Environment: +- GATEWAY_GROUP_ID: default + +Readiness Probe: + tcp-socket: 9080 + initialDelay: 10s + period: 10s +``` + +### Monitoring Server + +**Specification**: +```yaml +Replicas: 1 +Image: prometheus:latest +Ports: 9090 +Volume: Persistent storage for metrics +``` + +### Backend Applications + +**Generic Application Template**: +```yaml +Replicas: Based on load requirements +Ports: Application-specific +Service: ClusterIP for internal access +``` + +## StatefulSets + +### PostgreSQL Database + +**Specification**: +```yaml +Replicas: 1 (can be scaled for HA) +Image: postgres:latest +Ports: 5432 +Storage: Configurable persistent volume + +Environment: +- POSTGRES_USER: gateway_user +- POSTGRES_PASSWORD: *** (from secret) +- POSTGRES_DB: gateway_db +``` + +**Persistent Storage**: Data persistence across pod restarts + +## Services + +### Control Plane Services + +#### Dashboard Service +```yaml +Type: ClusterIP +Ports: +- HTTP Management Port +- HTTPS Management Port +Selector: app=dashboard +``` + +#### Developer Portal Service +```yaml +Type: ClusterIP +Ports: +- Web Service Port +Selector: app=developer-portal +``` + +#### Data Plane Manager Service +```yaml +Type: ClusterIP +Ports: +- Management API Port +- Configuration Proxy Port +Selector: app=dp-manager +``` + +#### PostgreSQL Service +```yaml +Type: ClusterIP +Ports: +- 5432/TCP +Selector: app=postgresql +``` + +#### PostgreSQL Headless Service +```yaml +Type: ClusterIP (None) +Ports: +- 5432/TCP +Purpose: StatefulSet DNS resolution +``` + +#### Monitoring Service +```yaml +Type: ClusterIP +Ports: +- 9090/TCP +Selector: app=prometheus +``` + +### Gateway Service + +```yaml +Type: ClusterIP +Ports: +- name: http-gateway + port: 80 + targetPort: 9080 +- name: https-gateway + port: 443 + targetPort: 9443 +Selector: + app.kubernetes.io/name: gateway +``` + +### Backend Application Services + +```yaml +Type: ClusterIP +Ports: Application-specific +Selector: app= +``` + +## Ingress Resources + +### Dashboard Ingress +```yaml +Class: nginx +Hosts: +- dashboard.domain.com + +TLS: +- hosts: [dashboard.domain.com] + secretName: dashboard-tls-secret + +Backend: + Service: dashboard-service + Port: Management Port + +Annotations: + nginx.ingress.kubernetes.io/backend-protocol: HTTPS + nginx.ingress.kubernetes.io/proxy-body-size: 10m +``` + +### Developer Portal Ingress +```yaml +Class: nginx +Hosts: +- portal.domain.com + +TLS: +- hosts: [portal.domain.com] + secretName: portal-tls-secret + +Backend: + Service: developer-portal-service + Port: Web Port +``` + +### Data Plane Manager Ingress +```yaml +Class: nginx +Hosts: +- dp-manager.domain.com + +TLS: +- hosts: [dp-manager.domain.com] + secretName: dp-manager-tls-secret + +Backend: + Service: dp-manager-service + Port: Management Port +``` + +### Gateway Ingress +```yaml +Class: nginx + +Hosts: +- *.domain.com +- domain.com + +TLS: +- hosts: [*.domain.com, domain.com] + secretName: wildcard-tls-secret + +Rules: +- host: "*.domain.com" + backend: + service: gateway-service + port: 80 +- host: domain.com + backend: + service: gateway-service + port: 80 +``` + +## ConfigMaps + +### Monitoring Configuration +- Prometheus server configuration +- Alert rules and thresholds + +### Dashboard Configuration +- Dashboard application settings +- UI customization + +### Developer Portal Configuration +- Portal settings +- API documentation configuration + +### Data Plane Manager Configuration +- Manager settings +- Gateway group configurations + +### Gateway Configuration +- Gateway runtime settings +- Backend connection configuration + +### Certificate Authority +- Kubernetes root CA certificate +- Trust chain configuration + +## Secrets + +### TLS Certificates + +**Control Plane Certificates**: +- Dashboard TLS certificates +- Developer Portal TLS certificates +- Data Plane Manager TLS certificates + +**Gateway Certificates**: +- Gateway mutual TLS certificates +- Internal communication certificates +- Public-facing TLS certificates + +**Application Certificates**: +- Backend service certificates +- Wildcard domain certificates + +### Database Credentials + +```yaml +Type: Opaque +Data: +- database-password: *** +- user-password: *** +``` + +### Helm Release Secrets + +- Helm release versioning secrets +- Configuration state storage + +## Persistent Volume Claims + +### Database Storage + +```yaml +Size: 10Gi+ (configurable) +Storage Class: Distributed storage +Access Mode: RWO +Purpose: Database persistence +``` + +### Monitoring Storage + +```yaml +Size: 100Gi+ (based on retention) +Storage Class: Local or network storage +Access Mode: RWO +Purpose: Metrics retention +``` + +### Configuration Storage + +```yaml +Size: Based on requirements +Storage Class: High-performance storage +Access Mode: RWO/RWX as needed +Purpose: Configuration persistence +``` + +## Resource Management + +### Useful Commands + +**List all resources**: +```bash +kubectl get all -n +``` + +**Get specific resource details**: +```bash +kubectl describe deployment -n +kubectl get svc -n -o yaml +``` + +**Check pod logs**: +```bash +kubectl logs -n +kubectl logs -n -f # Follow logs +``` + +**Access services locally**: +```bash +# Forward dashboard to local port +kubectl port-forward -n svc/dashboard-service 7080:7080 + +# Forward gateway to local port +kubectl port-forward -n svc/gateway-service 8080:80 +``` + +**Scale deployments**: +```bash +kubectl scale deployment -n --replicas= +``` + +**Check Helm releases**: +```bash +helm list -n +helm get values -n +helm status -n +``` + +**Troubleshooting**: +```bash +kubectl get events -n +kubectl top pods -n +kubectl describe pod -n +``` + +--- + +*Complete Kubernetes resource reference for API Gateway infrastructure deployment.* diff --git a/web/docs/mkdocs.yml b/web/docs/mkdocs.yml new file mode 100644 index 0000000..5d675db --- /dev/null +++ b/web/docs/mkdocs.yml @@ -0,0 +1,72 @@ +site_name: API7 Enterprise Demo Documentation +site_description: Complete documentation for API7 Enterprise Gateway demo deployment +site_author: CommandWare +site_url: https://demo.commandware.it/docs + +theme: + name: material + palette: + - scheme: default + primary: indigo + accent: indigo + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - scheme: slate + primary: indigo + accent: indigo + toggle: + icon: material/brightness-4 + name: Switch to light mode + features: + - navigation.tabs + - navigation.sections + - navigation.expand + - navigation.top + - search.suggest + - search.highlight + - content.code.copy + icon: + repo: fontawesome/brands/git-alt + +repo_name: demos/api7-demo +repo_url: https://git.commandware.com/demos/api7-demo + +nav: + - Home: index.md + - Getting Started: getting-started.md + - Architecture: + - Overview: architecture.md + - Kubernetes Resources: kubernetes-resources.md + - Configuration: + - API7 Gateway: api7-configuration.md + - CI/CD Pipeline: cicd-pipeline.md + - Troubleshooting: troubleshooting.md + +markdown_extensions: + - admonition + - pymdownx.details + - pymdownx.superfences + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.tabbed: + alternate_style: true + - tables + - attr_list + - md_in_html + - toc: + permalink: true + +plugins: + - search + +extra: + social: + - icon: fontawesome/brands/git-alt + link: https://git.commandware.com/demos/api7-demo + version: + provider: mike + +copyright: Copyright © 2025 CommandWare diff --git a/web/docs/troubleshooting.md b/web/docs/troubleshooting.md new file mode 100644 index 0000000..59fd026 --- /dev/null +++ b/web/docs/troubleshooting.md @@ -0,0 +1,702 @@ +# Troubleshooting Guide + +Common issues and solutions for API Gateway deployment. + +## Gateway Issues + +### Gateway Pods Not Starting + +**Symptoms**: +- Gateway pods in `CrashLoopBackOff` or `Error` state +- Pods continuously restarting + +**Diagnosis**: +```bash +# Check pod status +kubectl get pods -n -l app.kubernetes.io/name=gateway + +# View pod logs +kubectl logs -n + +# Describe pod for events +kubectl describe pod -n +``` + +**Common Causes & Solutions**: + +**1. Configuration Store Connection Failure** +```bash +# Check Data Plane Manager is running +kubectl get pods -n -l app=dp-manager + +# Verify configuration endpoint +kubectl get configmap -n -o yaml | grep endpoint + +# Expected: Configuration store endpoint URL +``` + +**2. TLS Certificate Issues** +```bash +# Verify TLS secret exists +kubectl get secret -n + +# Check certificate validity +kubectl get secret -n -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +``` + +**3. Configuration Error** +```bash +# Check gateway ConfigMap +kubectl get configmap -n -o yaml + +# Validate YAML syntax +kubectl get configmap -n -o yaml | yq eval '.' +``` + +### Gateway Returns 404 for All Routes + +**Symptoms**: +- All requests return HTTP 404 +- Routes configured but not working + +**Diagnosis**: +```bash +# Check if routes are published in Dashboard +# Navigate: Services β†’ β†’ Routes +# Verify: Route status shows "Published" + +# Check gateway logs for route loading +kubectl logs -n -l app.kubernetes.io/name=gateway --tail=100 | grep -i route +``` + +**Solutions**: + +**1. Routes Not Published** +- Routes synced via CLI are NOT active until published +- Publish each route in Dashboard: + - Services β†’ Select service β†’ Routes tab + - Click "Publish" for each route + - Select appropriate gateway group + +**2. Wrong Gateway Group** +```bash +# Verify gateway group +kubectl get deployment -n -o yaml | grep GATEWAY_GROUP + +# Expected: Configured group name +``` + +**3. Host Header Mismatch** +```bash +# Test with correct Host header +curl -H "Host: app.domain.com" http:/// + +# Check route configuration + dump --server --token +``` + +### Gateway Service Unavailable (503) + +**Symptoms**: +- Requests return HTTP 503 +- Gateway is running but can't reach backends + +**Diagnosis**: +```bash +# Check backend service exists +kubectl get svc -n + +# Check backend endpoints +kubectl get endpoints -n + +# Check gateway logs +kubectl logs -n -l app.kubernetes.io/name=gateway --tail=100 | grep -i "503\|upstream" +``` + +**Solutions**: + +**1. Backend Service Not Found** +```bash +# Verify service exists +kubectl get svc -n + +# Check service name in route config matches + dump --server --token | grep -A 5 upstream +``` + +**2. No Healthy Endpoints** +```bash +# Check if pods are running +kubectl get pods -n -l app= + +# Verify endpoints exist +kubectl get endpoints -n + +# If empty, check service selector +kubectl get svc -n -o yaml | grep -A 3 selector +kubectl get pods -n --show-labels | grep