first commit
Some checks failed
Build and Push Docker Images / build-web (push) Failing after 1m3s
Build and Push Docker Images / build-api (push) Failing after 1m1s

This commit is contained in:
d.viti
2025-10-03 01:20:15 +02:00
commit a2eef9efde
20 changed files with 4272 additions and 0 deletions

View File

@@ -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

492
README.md Normal file
View File

@@ -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:<branch-name>`
- `git.commandware.com/demos/api7-demo/api:<branch-name>`
### 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-----
<YOUR_CERTIFICATE>
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
<YOUR_KEY>
-----END PRIVATE KEY-----
```
### Sync Configuration
```bash
adc sync -f api7-routes.yaml \
--backend api7ee \
--server https://api7-dashboard.yourdomain.com \
--token <YOUR_API7_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=<API7_NAMESPACE>: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 <cert-name>
# 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=<USERNAME> \
--docker-password=<TOKEN> \
-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

16
api/.dockerignore Normal file
View File

@@ -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

15
api/Dockerfile Normal file
View File

@@ -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"]

87
api/README.md Normal file
View File

@@ -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"
```

123
api/main.py Normal file
View File

@@ -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)

3
api/requirements.txt Normal file
View File

@@ -0,0 +1,3 @@
fastapi==0.104.1
uvicorn[standard]==0.24.0
pydantic==2.5.0

20
web/.dockerignore Normal file
View File

@@ -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/

22
web/Dockerfile Normal file
View File

@@ -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"]

168
web/README.md Normal file
View File

@@ -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:<branch>`
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._

View File

@@ -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
<cli-tool> version
```
### Configuration Structure
```yaml
services:
- name: <service-name>
upstream:
name: <upstream-name>
scheme: http|https
type: roundrobin|chash|least_conn|ewma
# Option 1: Static nodes
nodes:
- host: <hostname>
port: <port>
weight: <1-100>
# Option 2: Service discovery
discovery_type: kubernetes
service_name: <namespace>/<service-name>:<port-name>
routes:
- name: <route-name>
priority: <number>
uris:
- <path-pattern>
hosts:
- <hostname>
methods:
- GET|POST|PUT|DELETE|...
plugins:
<plugin-name>:
<plugin-config>
ssls:
- snis:
- <domain>
certificates:
- certificate: |
<pem-certificate>
key: |
<pem-key>
```
## Service Discovery
### Kubernetes Service Discovery
**Prerequisites**:
1. Service registry configured in Dashboard
2. RBAC permissions for gateway service account
3. Service ports must have `name` field
**Configuration**:
**Via Dashboard**:
1. **Settings → Service Registry → Add Service Registry**
2. Select: **Kubernetes**
3. Configure:
```
Name: kubernetes-cluster
API Server: https://kubernetes.default.svc.cluster.local:443
Token Path: /var/run/secrets/kubernetes.io/serviceaccount/token
Namespace Filter: <namespace>
```
**RBAC Setup**:
```bash
kubectl create clusterrolebinding gateway-discovery \
--clusterrole=view \
--serviceaccount=<namespace>:default
```
**Service Configuration**:
```yaml
upstream:
discovery_type: kubernetes
service_name: <namespace>/<service-name>:<port-name>
# Format: <namespace>/<service-name>:<port-name>
```
### Static Nodes (No Service Discovery)
```yaml
upstream:
nodes:
- host: web-service.<namespace>.svc.cluster.local
port: 80
weight: 100
- host: <cluster-ip>
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: <namespace>/api-service:http
routes:
- name: api-route
priority: 10 # Higher priority = evaluated first
uris:
- /api
- /api/*
hosts:
- app.domain.com
plugins:
redirect:
http_to_https: true
proxy-rewrite:
regex_uri:
- ^/api/(.*)
- /$1 # Strip /api prefix
- name: web-service
upstream:
discovery_type: kubernetes
service_name: <namespace>/web-service:http
routes:
- name: web-route
priority: 1 # Lower priority = fallback
uris:
- /*
hosts:
- app.domain.com
```
**Traffic Flow**:
- `app.domain.com/api/users` → api-service (receives `/users`)
- `app.domain.com/anything-else` → web-service
### Wildcard Host Matching
```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.<namespace>.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-----
<CERTIFICATE_CONTENT>
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
<KEY_CONTENT>
-----END PRIVATE KEY-----
```
### Extract from Kubernetes Secret
```bash
# Extract certificate
kubectl get secret tls-secret -n <namespace> -o jsonpath='{.data.tls\.crt}' | base64 -d
# Extract key
kubectl get secret tls-secret -n <namespace> -o jsonpath='{.data.tls\.key}' | base64 -d
```
## Configuration Examples
### Multiple Service Routes
**Configuration**:
```yaml
services:
- name: frontend-service
upstream:
name: frontend-upstream
scheme: http
type: roundrobin
nodes:
- host: frontend-service.<namespace>.svc.cluster.local
port: 80
weight: 100
routes:
- name: frontend-route
uris:
- /*
hosts:
- app.domain.com
plugins:
redirect:
http_to_https: true
- name: root-route
priority: 1
uris:
- /
- /~*
hosts:
- domain.com
plugins:
redirect:
http_to_https: true
- name: api-service
upstream:
name: api-upstream
scheme: http
type: roundrobin
nodes:
- host: api-service.<namespace>.svc.cluster.local
port: 80
weight: 100
routes:
- name: api-route
priority: 10
uris:
- /api
- /api/*
hosts:
- domain.com
plugins:
redirect:
http_to_https: true
proxy-rewrite:
regex_uri:
- ^/api/(.*)
- /$1
```
**Traffic Flow**:
- `app.domain.com/*` → Frontend Service
- `domain.com/api/*` → API Service (with `/api` prefix stripped)
- `domain.com/*` → Frontend Service
## Syncing Configuration
### Via CLI Tools
**Sync configuration**:
```bash
<cli-tool> sync -f config.yaml \
--server <dashboard-url> \
--token <api-token> \
--gateway-group default
```
**Dump current configuration**:
```bash
<cli-tool> dump \
--server <dashboard-url> \
--token <api-token> > current-config.yaml
```
**Validate configuration**:
```bash
<cli-tool> validate -f config.yaml
```
### Publishing Routes
**⚠️ Important**: Routes synced via CLI may need to be published via Dashboard.
**Steps**:
1. Access Dashboard
2. Navigate: **Services** → Select service
3. Go to: **Routes** tab
4. For each route:
- Click: **Publish**
- Select: Gateway group
- Confirm
**Route Status**:
- **Unpublished**: Synced but not active
- **Published**: Active on gateway
## Advanced Configurations
### Multi-Environment Setup
**Development Gateway Group**:
```bash
# Sync to dev gateway group
<cli-tool> sync -f config.yaml \
--gateway-group dev \
--server <dashboard-url> \
--token <token>
```
**Production Gateway Group**:
```bash
# Sync to prod gateway group
<cli-tool> sync -f config.yaml \
--gateway-group prod \
--server <dashboard-url> \
--token <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 <namespace> 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 <namespace> -l app.kubernetes.io/name=gateway --tail=100
```
### Service Discovery Not Working
**Check**:
1. ✅ Service registry configured in Dashboard
2. ✅ Service registry status is "Connected"
3. ✅ RBAC permissions granted
4. ✅ Service has named ports
```bash
# Verify service
kubectl get svc -n <namespace> <service-name>
# Check endpoints
kubectl get endpoints -n <namespace> <service-name>
```
### Configuration Not Applied
**Check**:
1. ✅ CLI sync succeeded
2. ✅ Routes are published
3. ✅ Gateway group matches
```bash
# Dump and compare
<cli-tool> dump --server <URL> --token <TOKEN> > current.yaml
diff config.yaml current.yaml
```
---
*Complete configuration reference for API Gateway infrastructure.*

283
web/docs/architecture.md Normal file
View File

@@ -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.*

477
web/docs/cicd-pipeline.md Normal file
View File

@@ -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
↓ ↓
<registry>/web:<branch>
<registry>/api:<branch>
```
## 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: <registry-url>
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Extract metadata for web image
id: meta-web
uses: docker/metadata-action@v5
with:
images: <registry>/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=<registry>/web:buildcache
cache-to: type=registry,ref=<registry>/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 <branch-name>
```
Images tagged with branch name:
- `<registry>/web:<branch-name>`
- `<registry>/api:<branch-name>`
### 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**: `<registry>/<namespace>/<app>:<tag>`
**Examples**:
- `<registry>/web:main`
- `<registry>/web:develop`
- `<registry>/web:feature-xyz`
- `<registry>/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=<registry-url> \
--docker-username=<USERNAME> \
--docker-password=<TOKEN> \
-n <namespace>
```
### 2. Update Deployment
**deployment.yaml**:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: <namespace>
spec:
template:
spec:
imagePullSecrets:
- name: registry-secret
containers:
- name: web
image: <registry>/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 <namespace>
kubectl rollout restart deployment/api -n <namespace>
# Check rollout status
kubectl rollout status deployment/web -n <namespace>
```
**Or update image explicitly**:
```bash
kubectl set image deployment/web \
web=<registry>/web:main \
-n <namespace>
kubectl set image deployment/api \
api=<registry>/api:main \
-n <namespace>
```
## Docker Layer Caching
The pipeline uses Docker layer caching to speed up builds:
**Cache Configuration**:
```yaml
cache-from: type=registry,ref=<registry>/web:buildcache
cache-to: type=registry,ref=<registry>/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
<cli-tool> list runs
# View specific run logs
<cli-tool> view run <run-id>
```
## 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 <registry-url> -u <USERNAME> -p <TOKEN>
```
### 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 <namespace>
```
2. Check secret is referenced in deployment:
```yaml
spec:
template:
spec:
imagePullSecrets:
- name: registry-secret
```
3. Test manual pull:
```bash
docker pull <registry>/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: <registry>/web:main
# Staging
image: <registry>/web:develop
# Development
image: <registry>/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.*

432
web/docs/getting-started.md Normal file
View File

@@ -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 <repository-url>
cd <project-directory>
```
### 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 <namespace>
# Verify gateway components are running
kubectl get pods -n <namespace>
```
**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: <namespace>
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: <registry>/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: <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 <namespace>
kubectl get pods -n <namespace> -l app=web
```
### 4. Configure Container Registry Access (if needed)
```bash
# Create registry secret
kubectl create secret docker-registry registry-secret \
--docker-server=<registry-server> \
--docker-username=<USERNAME> \
--docker-password=<TOKEN> \
-n <namespace>
# 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: <namespace>/web-service:http
routes:
- name: web-route
uris:
- /*
hosts:
- app.domain.com
plugins:
redirect:
http_to_https: true
```
**2. Sync configuration**:
```bash
<cli-tool> sync -f config.yaml \
--server <dashboard-url> \
--token <api-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: <namespace>
```
- 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: `<namespace>/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: <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:<namespace>:default -n <namespace>
# If needed, create ClusterRoleBinding
kubectl create clusterrolebinding gateway-discovery \
--clusterrole=view \
--serviceaccount=<namespace>:default
```
## Testing the Deployment
### 1. Test DNS Resolution
```bash
# Add to /etc/hosts or configure DNS
echo "<external-ip> 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 <namespace> --replicas=5
# Check endpoints
kubectl get endpoints -n <namespace> 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 <namespace> 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 <namespace>
kubectl rollout restart deployment/api -n <namespace>
# Or update image in deployment
kubectl set image deployment/web web=<registry>/web:latest -n <namespace>
```
## Common Tasks
### View Logs
```bash
# Application logs
kubectl logs -n <namespace> -l app=web --tail=50 -f
# Gateway logs
kubectl logs -n <namespace> -l app.kubernetes.io/name=gateway --tail=50 -f
# Dashboard logs
kubectl logs -n <namespace> -l app=dashboard --tail=50 -f
```
### Check Route Configuration
**Via CLI**:
```bash
<cli-tool> dump \
--server <dashboard-url> \
--token <TOKEN>
```
**Via Dashboard**:
- Navigate: **Services → <service-name> → Routes**
- View route details and publication status
### Update Route Configuration
```bash
# Edit config file
vim config.yaml
# Sync changes
<cli-tool> sync -f config.yaml \
--server <dashboard-url> \
--token <TOKEN> \
--gateway-group default
```
### Monitor Gateway Metrics
**Prometheus**:
```bash
kubectl port-forward -n <namespace> 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!*

82
web/docs/index.md Normal file
View File

@@ -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*

View File

@@ -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=<application-name>
```
## 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 <namespace>
```
**Get specific resource details**:
```bash
kubectl describe deployment <deployment-name> -n <namespace>
kubectl get svc <service-name> -n <namespace> -o yaml
```
**Check pod logs**:
```bash
kubectl logs -n <namespace> <pod-name>
kubectl logs -n <namespace> <pod-name> -f # Follow logs
```
**Access services locally**:
```bash
# Forward dashboard to local port
kubectl port-forward -n <namespace> svc/dashboard-service 7080:7080
# Forward gateway to local port
kubectl port-forward -n <namespace> svc/gateway-service 8080:80
```
**Scale deployments**:
```bash
kubectl scale deployment <deployment-name> -n <namespace> --replicas=<count>
```
**Check Helm releases**:
```bash
helm list -n <namespace>
helm get values <release-name> -n <namespace>
helm status <release-name> -n <namespace>
```
**Troubleshooting**:
```bash
kubectl get events -n <namespace>
kubectl top pods -n <namespace>
kubectl describe pod <pod-name> -n <namespace>
```
---
*Complete Kubernetes resource reference for API Gateway infrastructure deployment.*

72
web/docs/mkdocs.yml Normal file
View File

@@ -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 &copy; 2025 CommandWare

702
web/docs/troubleshooting.md Normal file
View File

@@ -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 <namespace> -l app.kubernetes.io/name=gateway
# View pod logs
kubectl logs -n <namespace> <gateway-pod-name>
# Describe pod for events
kubectl describe pod -n <namespace> <gateway-pod-name>
```
**Common Causes & Solutions**:
**1. Configuration Store Connection Failure**
```bash
# Check Data Plane Manager is running
kubectl get pods -n <namespace> -l app=dp-manager
# Verify configuration endpoint
kubectl get configmap <gateway-configmap> -n <namespace> -o yaml | grep endpoint
# Expected: Configuration store endpoint URL
```
**2. TLS Certificate Issues**
```bash
# Verify TLS secret exists
kubectl get secret <gateway-tls-secret> -n <namespace>
# Check certificate validity
kubectl get secret <gateway-tls-secret> -n <namespace> -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates
```
**3. Configuration Error**
```bash
# Check gateway ConfigMap
kubectl get configmap <gateway-configmap> -n <namespace> -o yaml
# Validate YAML syntax
kubectl get configmap <gateway-configmap> -n <namespace> -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 → <service> → Routes
# Verify: Route status shows "Published"
# Check gateway logs for route loading
kubectl logs -n <namespace> -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 <gateway-deployment> -n <namespace> -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://<gateway-ip>/
# Check route configuration
<cli-tool> dump --server <dashboard-url> --token <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 <namespace> <backend-service-name>
# Check backend endpoints
kubectl get endpoints -n <namespace> <backend-service-name>
# Check gateway logs
kubectl logs -n <namespace> -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 <namespace>
# Check service name in route config matches
<cli-tool> dump --server <URL> --token <TOKEN> | grep -A 5 upstream
```
**2. No Healthy Endpoints**
```bash
# Check if pods are running
kubectl get pods -n <namespace> -l app=<backend-app>
# Verify endpoints exist
kubectl get endpoints -n <namespace> <service-name>
# If empty, check service selector
kubectl get svc <service-name> -n <namespace> -o yaml | grep -A 3 selector
kubectl get pods -n <namespace> --show-labels | grep <label>
```
**3. Service Discovery Not Working**
- See [Service Discovery Issues](#service-discovery-not-working)
## Service Discovery Issues
### Service Registry Not Found
**Error**: `service registry not found` or `discovery failed`
**Diagnosis**:
```bash
# Check service registry in Dashboard
# Navigate: Settings → Service Registry
# Verify: Status shows "Connected" or "Healthy"
# Check gateway logs
kubectl logs -n <namespace> -l app.kubernetes.io/name=gateway | grep -i discovery
```
**Solutions**:
**1. Service Registry Not Configured**
- Dashboard → Settings → Service Registry → Add Service Registry
- Type: Kubernetes
- Configure:
```
Name: kubernetes-cluster
API Server: https://kubernetes.default.svc.cluster.local:443
Token Path: /var/run/secrets/kubernetes.io/serviceaccount/token
```
**2. RBAC Permissions Missing**
```bash
# Check permissions
kubectl auth can-i list endpoints --as=system:serviceaccount:<namespace>:default
# If "no", create ClusterRoleBinding
kubectl create clusterrolebinding gateway-discovery \
--clusterrole=view \
--serviceaccount=<namespace>:default
```
**3. Service Port Not Named**
```bash
# Check service definition
kubectl get svc <service-name> -n <namespace> -o yaml
# Port MUST have a name:
ports:
- port: 80
targetPort: 8000
name: http # ← Required for service discovery
```
### Endpoints Not Discovered
**Symptoms**:
- Service discovery configured but endpoints not updating
- Scaling pods doesn't update gateway
**Diagnosis**:
```bash
# Check service endpoints
kubectl get endpoints -n <namespace> <service-name>
# Scale pods and verify endpoints update
kubectl scale deployment <name> -n <namespace> --replicas=5
kubectl get endpoints -n <namespace> <service-name>
# Check gateway discovers endpoints
kubectl logs -n <namespace> -l app.kubernetes.io/name=gateway | grep -i endpoint
```
**Solutions**:
**1. Check Service Registry Connection**
```bash
# In Dashboard, verify registry status
# Settings → Service Registry → kubernetes-cluster
# Status should be "Connected"
```
**2. Verify Service Name Format**
```yaml
# Format: <namespace>/<service-name>:<port-name>
upstream:
discovery_type: kubernetes
service_name: <namespace>/web-service:http
# NOT: web-service or web-service.<namespace>.svc.cluster.local
```
**3. Restart Gateway Pods**
```bash
kubectl rollout restart deployment/<gateway-deployment> -n <namespace>
```
## Ingress & Certificate Issues
### Certificate Not Trusted / Invalid
**Symptoms**:
- Browser shows "Not Secure" warning
- Certificate errors in logs
**Diagnosis**:
```bash
# Check certificate
kubectl get certificate -n <namespace>
# Describe certificate for errors
kubectl describe certificate <cert-name> -n <namespace>
# Check cert-manager logs
kubectl logs -n cert-manager -l app.kubernetes.io/name=cert-manager --tail=50
# Test certificate
openssl s_client -connect demo.domain.com:443 -servername demo.domain.com < /dev/null 2>/dev/null | openssl x509 -noout -dates -issuer
```
**Solutions**:
**1. Certificate Not Ready**
```bash
# Check certificate status
kubectl get certificate -n <namespace>
# If not "True", check cert-manager logs
kubectl logs -n cert-manager -l app.kubernetes.io/name=cert-manager
```
**2. DNS Challenge Failed**
```bash
# Check ClusterIssuer
kubectl get clusterissuer
# Verify Cloudflare API token
kubectl get secret cloudflare-api-token-secret -n cert-manager
# Check challenge status
kubectl get challenge -A
```
**3. Manual Certificate Creation**
```bash
# If cert-manager fails, use acme.sh
export CF_Token="<CLOUDFLARE_TOKEN>"
~/.acme.sh/acme.sh --issue --dns dns_cf -d "*.domain.com" -d "domain.com"
# Create Kubernetes secret
kubectl create secret tls wildcard-tls \
--cert=~/.acme.sh/*.domain.com_ecc/fullchain.cer \
--key=~/.acme.sh/*.domain.com_ecc/*.domain.com.key \
-n <namespace>
```
### LoadBalancer Stuck in Pending
**Symptoms**:
- Ingress EXTERNAL-IP shows `<pending>`
- Cannot access services externally
**Diagnosis**:
```bash
# Check MetalLB
kubectl get pods -n metallb-system
# Check IPAddressPool
kubectl get ipaddresspool -A
# Check service
kubectl describe svc -n ingress-nginx nginx-ingress-lb-custom
```
**Solutions**:
**1. MetalLB Not Running**
```bash
# Check MetalLB pods
kubectl get pods -n metallb-system
# Restart if needed
kubectl rollout restart deployment -n metallb-system
```
**2. IP Pool Exhausted**
```bash
# Check IP pool configuration
kubectl get ipaddresspool -A -o yaml
# Check allocated IPs
kubectl get svc -A -o wide | grep LoadBalancer
```
**3. Annotation Error**
```bash
# Check MetalLB annotation
kubectl get svc <name> -n <namespace> -o yaml | grep metallb
# Correct format:
metadata:
annotations:
metallb.universe.tf/loadBalancerIPs: "<external-ip>"
```
### Ingress Returns 503 Backend Unavailable
**Symptoms**:
- NGINX Ingress returns 503
- Backend service is running
**Diagnosis**:
```bash
# Check ingress
kubectl describe ingress <name> -n <namespace>
# Check NGINX logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
# Check backend service
kubectl get svc <backend-service> -n <namespace>
```
**Solutions**:
**1. Wrong Backend Service**
```bash
# Verify ingress points to Gateway Gateway, not application
kubectl get ingress <name> -n <namespace> -o yaml | grep -A 5 backend
# Should be:
backend:
service:
name: <gateway-deployment>-gateway
port:
number: 80
```
**2. Service Port Mismatch**
```bash
# Check service ports
kubectl get svc <gateway-deployment>-gateway -n <namespace>
# Ingress should point to port 80, not 9080
```
## Control Plane Issues
### Dashboard Not Accessible
**Symptoms**:
- Cannot access https://<dashboard-url>
- Connection timeout or refused
**Diagnosis**:
```bash
# Check dashboard pod
kubectl get pods -n <namespace> -l app=<namespace>3-dashboard
# Check dashboard service
kubectl get svc -n <namespace> <namespace>3-0-1759339083-dashboard
# Check ingress
kubectl get ingress -n <namespace> <namespace>3-0-1759339083-dashboard
```
**Solutions**:
**1. Pod Not Running**
```bash
# Check pod status
kubectl get pods -n <namespace> -l app=<namespace>3-dashboard
# View logs
kubectl logs -n <namespace> -l app=<namespace>3-dashboard
```
**2. Port Forward as Workaround**
```bash
kubectl port-forward -n <namespace> svc/<namespace>3-0-1759339083-dashboard 7080:7080
# Access at http://localhost:7080
```
### PostgreSQL Connection Failed
**Symptoms**:
- Dashboard/Portal shows database errors
- Logs show "connection refused" to PostgreSQL
**Diagnosis**:
```bash
# Check PostgreSQL pod
kubectl get pods -n <namespace> -l app=postgresql
# Check PostgreSQL service
kubectl get svc -n <namespace> postgresql
# Test connection from dashboard pod
kubectl exec -n <namespace> -it <dashboard-pod> -- psql -h postgresql -U <namespace> -d <namespace>
```
**Solutions**:
**1. PostgreSQL Pod Not Running**
```bash
# Check pod status
kubectl get pods -n <namespace> postgresql-0
# View logs
kubectl logs -n <namespace> postgresql-0
```
**2. Credentials Mismatch**
```bash
# Check credentials in secret
kubectl get secret postgresql -n <namespace> -o jsonpath='{.data.postgres-password}' | base64 -d
# Compare with DSN in dashboard config
kubectl get configmap <namespace>3-0-1759339083-dashboard-config -n <namespace> -o yaml | grep dsn
```
**3. Storage Issues**
```bash
# Check PVC
kubectl get pvc -n <namespace> data-postgresql-0
# If storage full, expand PVC (if storage class supports it)
kubectl patch pvc data-postgresql-0 -n <namespace> -p '{"spec":{"resources":{"requests":{"storage":"20Gi"}}}}'
```
## Application Issues
### Image Pull Errors
**Error**: `ImagePullBackOff` or `ErrImagePull`
**Diagnosis**:
```bash
# Check pod status
kubectl get pods -n <namespace>
# Describe pod
kubectl describe pod <pod-name> -n <namespace> | grep -A 10 Events
# Check image name
kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.containers[0].image}'
```
**Solutions**:
**1. Registry Authentication**
```bash
# Create registry secret
kubectl create secret docker-registry registry-secret \
--docker-server=<registry-url> \
--docker-username=<USERNAME> \
--docker-password=<TOKEN> \
-n <namespace>
# Add to deployment
spec:
template:
spec:
imagePullSecrets:
- name: registry-secret
```
**2. Image Does Not Exist**
```bash
# Verify image exists
docker pull <registry-url>/web:main
# Check available tags via Gitea UI or API
curl -u <username>:<token> https://<registry-url>/api/v1/packages/demos
```
**3. Wrong Image Name**
```bash
# Correct format:
<registry-url>/web:main
# NOT:
<registry-url>:main # Missing /web
```
### Application Crashing
**Symptoms**:
- Pods in `CrashLoopBackOff`
- Application logs show errors
**Diagnosis**:
```bash
# Check pod logs
kubectl logs -n <namespace> <pod-name>
# Check previous pod logs (if restarted)
kubectl logs -n <namespace> <pod-name> --previous
# Check events
kubectl get events -n <namespace> --sort-by='.lastTimestamp' | tail -20
```
**Solutions**:
**1. Port Mismatch**
```bash
# Verify app runs on correct port
# Check Dockerfile CMD or deployment env vars
# Common issue: App runs on 8000, container expects 3000
```
**2. Missing Dependencies**
```bash
# Check application logs for import errors
kubectl logs -n <namespace> <pod-name>
# Rebuild image with correct requirements.txt
```
**3. Resource Limits**
```bash
# Check if OOMKilled
kubectl describe pod <pod-name> -n <namespace> | grep -A 5 "Last State"
# If memory limit too low, increase:
resources:
limits:
memory: 512Mi # Increase from 256Mi
```
## CLI / Configuration Issues
### CLI Sync Fails
**Error**: `failed to sync configuration` or authentication errors
**Diagnosis**:
```bash
# Test CLI connection
<cli-tool>ping \
--backend <namespace> \
--server https://<dashboard-url> \
--token <TOKEN> \
--tls-skip-verify
# Validate configuration file
<cli-tool>validate -f config.yaml
```
**Solutions**:
**1. Invalid Token**
```bash
# Generate new token in Dashboard
# User → API Tokens → Generate Token
# Test with new token
<cli-tool>sync -f config.yaml --server <URL> --token <NEW_TOKEN>
```
**2. YAML Syntax Error**
```bash
# Validate YAML
<cli-tool>validate -f config.yaml
# Or use yq/yamllint
yq eval '.' config.yaml
```
**3. SSL Certificate Error**
```bash
# Use --tls-skip-verify flag (for self-signed certs)
<cli-tool>sync -f config.yaml --server <URL> --token <TOKEN> --tls-skip-verify
```
### Configuration Not Applied
**Symptoms**:
- CLI sync succeeds but changes not visible
- Routes not working as expected
**Diagnosis**:
```bash
# Dump current configuration
<cli-tool>dump --backend <namespace> --server <URL> --token <TOKEN> > current.yaml
# Compare with expected
diff config.yaml current.yaml
```
**Solutions**:
**1. Routes Not Published**
- Synced routes are NOT active until published
- Publish via Dashboard UI
**2. Wrong Gateway Group**
```bash
# Specify correct gateway group
<cli-tool>sync -f config.yaml --gateway-group default
```
**3. Cache Issue**
```bash
# Restart gateway pods to force reload
kubectl rollout restart deployment/<gateway-deployment> -n <namespace>
```
## Useful Debugging Commands
### Check All Resources
```bash
# All resources in namespace
kubectl get all -n <namespace>
# Wide output with more details
kubectl get all -n <namespace> -o wide
# All resource types including configmaps, secrets
kubectl get all,cm,secret,ingress,pvc -n <namespace>
```
### Log Collection
```bash
# All gateway logs
kubectl logs -n <namespace> -l app.kubernetes.io/name=gateway --all-containers=true --tail=200
# Dashboard logs
kubectl logs -n <namespace> -l app=<namespace>3-dashboard --tail=100
# Stream logs in real-time
kubectl logs -n <namespace> -l app.kubernetes.io/name=gateway -f
```
### Network Testing
```bash
# Test from within cluster
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- sh
# Inside pod:
curl http://<gateway-deployment>-gateway.<namespace>.svc.cluster.local
curl http://web-service.<namespace>.svc.cluster.local
```
### Performance Analysis
```bash
# Check resource usage
kubectl top pods -n <namespace>
kubectl top nodes
# Describe for resource limits
kubectl describe pod <pod-name> -n <namespace> | grep -A 5 Limits
```
---
*Comprehensive troubleshooting guide for API Gateway infrastructure deployment.*

137
web/main.py Normal file
View File

@@ -0,0 +1,137 @@
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
import uvicorn
import os
import subprocess
app = FastAPI(title="Web Demo Application")
# Build MkDocs documentation on startup
def build_docs():
docs_dir = os.path.join(os.path.dirname(__file__), "docs")
site_dir = os.path.join(os.path.dirname(__file__), "site")
if os.path.exists(docs_dir):
try:
subprocess.run(
["mkdocs", "build", "-f", os.path.join(docs_dir, "mkdocs.yml"), "-d", site_dir],
check=True,
capture_output=True
)
print(f"✓ Documentation built successfully at {site_dir}")
return True
except subprocess.CalledProcessError as e:
print(f"✗ Failed to build documentation: {e.stderr.decode()}")
return False
except FileNotFoundError:
print("✗ MkDocs not installed. Install with: pip install mkdocs mkdocs-material")
return False
return False
# Build docs on startup
@app.on_event("startup")
async def startup_event():
build_docs()
# Mount static documentation site at /docs
site_dir = os.path.join(os.path.dirname(__file__), "site")
if os.path.exists(site_dir):
app.mount("/docs", StaticFiles(directory=site_dir, html=True), name="docs")
# Simple HTML template inline
HTML_TEMPLATE = """
<!DOCTYPE html>
<html>
<head>
<title>Web Demo</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background-color: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h1 {
color: #333;
border-bottom: 2px solid #4CAF50;
padding-bottom: 10px;
}
.info-box {
background-color: #e8f5e9;
padding: 15px;
margin: 20px 0;
border-left: 4px solid #4CAF50;
border-radius: 4px;
}
.metric {
display: inline-block;
margin: 10px 20px 10px 0;
padding: 10px 20px;
background-color: #2196F3;
color: white;
border-radius: 4px;
}
.doc-link {
display: inline-block;
margin: 20px 10px 0 0;
padding: 12px 24px;
background-color: #673AB7;
color: white;
text-decoration: none;
border-radius: 4px;
transition: background-color 0.3s;
}
.doc-link:hover {
background-color: #512DA8;
}
</style>
</head>
<body>
<div class="container">
<h1>Welcome to Web Demo Application</h1>
<div class="info-box">
<h2>Application Information</h2>
<p><strong>Service:</strong> Web Frontend</p>
<p><strong>Status:</strong> ✓ Running</p>
<p><strong>Version:</strong> 1.0.0</p>
</div>
<h2>Metrics Dashboard</h2>
<div>
<span class="metric">Requests: 1,234</span>
<span class="metric">Uptime: 99.9%</span>
<span class="metric">Users: 567</span>
</div>
<div class="info-box">
<h3>About</h3>
<p>This is a demo FastAPI web application serving HTML content.
It demonstrates a simple web interface with metrics and information display.</p>
</div>
<div>
<a href="/docs/" class="doc-link">📚 View Documentation</a>
<a href="/health" class="doc-link">🏥 Health Check</a>
</div>
</div>
</body>
</html>
"""
@app.get("/", response_class=HTMLResponse)
async def root():
"""Serve the main webpage"""
return HTML_TEMPLATE
@app.get("/health")
async def health():
"""Health check endpoint"""
return {"status": "healthy", "service": "web"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)

4
web/requirements.txt Normal file
View File

@@ -0,0 +1,4 @@
fastapi==0.104.1
uvicorn[standard]==0.24.0
mkdocs==1.5.3
mkdocs-material==9.5.3