first commit
This commit is contained in:
492
README.md
Normal file
492
README.md
Normal 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
|
||||
Reference in New Issue
Block a user