veza/k8s/cdn/README.md

271 lines
6.2 KiB
Markdown

# CDN Configuration
This directory contains Kubernetes configurations for Content Delivery Network (CDN) setup to optimize delivery of static assets and audio files.
## Overview
CDN configuration provides:
- **Faster asset delivery** through edge caching
- **Reduced origin server load**
- **Better global performance** with geographically distributed caching
- **Optimized caching** for different asset types
## Components
### nginx-cdn-config
- Optimized nginx configuration for CDN integration
- Long cache headers for static assets
- CORS headers for cross-origin requests
- Range request support for audio/video streaming
### cdn-configmap
- General CDN configuration
- Provider selection
- Cache TTL settings
- Feature toggles
### Provider-Specific Configs
- **cloudflare-config.yaml**: Cloudflare CDN configuration
- **cloudfront-config.yaml**: AWS CloudFront CDN configuration
## Supported CDN Providers
### Cloudflare
- **Pros**: Easy setup, free tier, DDoS protection, global network
- **Cons**: Limited customization on free tier
- **Best for**: Small to medium deployments
### AWS CloudFront
- **Pros**: Highly customizable, integrates with AWS services, pay-per-use
- **Cons**: More complex setup, AWS account required
- **Best for**: AWS-based infrastructure
### Generic CDN
- **Pros**: Works with any CDN provider
- **Cons**: Manual configuration required
- **Best for**: Custom CDN solutions
## Deployment
### 1. Apply nginx CDN Configuration
```bash
kubectl apply -f k8s/cdn/nginx-cdn-config.yaml
```
Update frontend deployment to use this config:
```yaml
volumeMounts:
- name: nginx-cdn-config
mountPath: /etc/nginx/conf.d/cdn.conf
subPath: nginx-cdn.conf
volumes:
- name: nginx-cdn-config
configMap:
name: nginx-cdn-config
```
### 2. Apply CDN ConfigMap
```bash
kubectl apply -f k8s/cdn/cdn-configmap.yaml
```
### 3. Configure CDN Provider
#### Cloudflare
1. Update `cloudflare-config.yaml` with your zone ID
2. Create secret with API token:
```bash
kubectl create secret generic cloudflare-secrets \
--from-literal=api-token=your-api-token \
-n veza-production
```
3. Apply configuration:
```bash
kubectl apply -f k8s/cdn/cloudflare-config.yaml
```
#### AWS CloudFront
1. Update `cloudfront-config.yaml` with your distribution ID
2. Create secret with AWS credentials:
```bash
kubectl create secret generic aws-secrets \
--from-literal=access-key-id=your-key \
--from-literal=secret-access-key=your-secret \
-n veza-production
```
3. Apply configuration:
```bash
kubectl apply -f k8s/cdn/cloudfront-config.yaml
```
## Configuration
### Cache TTL Settings
Edit `cdn-configmap.yaml` to adjust cache TTLs:
```yaml
# Static assets (JS, CSS, images, fonts)
cdn-cache-ttl: "31536000" # 1 year
# Audio files
cdn-audio-cache-ttl: "2592000" # 30 days
```
### Enable/Disable CDN Features
```yaml
# Enable CDN for static assets
cdn-assets-enabled: "true"
# Enable CDN for audio files
cdn-audio-enabled: "true"
# Enable CDN for images
cdn-images-enabled: "true"
```
## Integration with Services
### Frontend
The frontend should use CDN URLs for static assets. Update environment variables:
```bash
VITE_CDN_URL=https://cdn.veza.com
VITE_CDN_ENABLED=true
```
### Backend API
The backend CDN service (`internal/services/cdn_service.go`) can generate CDN URLs:
```go
cdnService := services.NewCDNService(services.CDNConfig{
Provider: services.CDNProviderCloudflare,
BaseURL: "https://cdn.veza.com",
Enabled: true,
})
assetURL := cdnService.GetAssetURL("images", "logo.png")
audioURL := cdnService.GetAudioURL("track-123", "song.mp3")
```
## Cache Invalidation
### Manual Invalidation
```bash
# Invalidate specific paths
kubectl exec -it deployment/veza-backend-api -n veza-production -- \
/app/veza-api cdn invalidate /static/js/app.js /audio/track-123/song.mp3
```
### Automatic Invalidation
The backend CDN service supports automatic cache invalidation on content updates. Configure in `cdn-configmap.yaml`:
```yaml
cdn-invalidation-on-update: "true"
```
## Testing
### Verify CDN Headers
```bash
# Check static asset headers
curl -I https://cdn.veza.com/static/js/app.js
# Should see:
# Cache-Control: public, immutable, max-age=31536000
# X-CDN-Cache-Status: HIT
```
### Test CORS
```bash
# Test CORS for audio files
curl -H "Origin: https://app.veza.com" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: Range" \
-X OPTIONS \
https://cdn.veza.com/audio/track-123/song.mp3
```
### Check Cache Status
```bash
# View CDN cache headers
curl -I https://cdn.veza.com/static/css/app.css | grep -i cache
```
## Monitoring
### CDN Metrics
Monitor CDN performance:
- Cache hit ratio
- Origin requests
- Bandwidth usage
- Response times
### Set Up Alerts
Alert on:
- Low cache hit ratio (< 80%)
- High origin requests
- CDN errors
## Best Practices
1. **Use long cache TTLs** for immutable assets (JS, CSS with hashes)
2. **Use shorter TTLs** for dynamic content
3. **Enable compression** (gzip, brotli) at CDN level
4. **Use CDN for audio/video** to reduce origin load
5. **Monitor cache hit rates** and adjust TTLs accordingly
6. **Invalidate cache** when deploying new versions
7. **Use versioned URLs** for assets (e.g., `/static/js/app-v1.2.3.js`)
## Troubleshooting
### Assets Not Loading from CDN
1. Check CDN configuration:
```bash
kubectl get configmap cdn-config -n veza-production -o yaml
```
2. Verify CDN base URL is correct
3. Check DNS resolution for CDN domain
4. Verify CORS headers are set correctly
### Cache Not Working
1. Check cache headers in response:
```bash
curl -I https://cdn.veza.com/static/js/app.js
```
2. Verify CDN provider settings
3. Check cache TTL configuration
4. Verify CDN is enabled in configmap
### CORS Issues
1. Check CORS headers in nginx config
2. Verify `Access-Control-Allow-Origin` is set
3. Check preflight OPTIONS requests are handled
4. Verify allowed methods and headers
## Additional Resources
- [Cloudflare CDN Documentation](https://developers.cloudflare.com/cache/)
- [AWS CloudFront Documentation](https://docs.aws.amazon.com/cloudfront/)
- [nginx CDN Configuration](https://nginx.org/en/docs/http/ngx_http_headers_module.html)