[INFRA-011] infra: Set up load balancing
This commit is contained in:
parent
3cf385cdf2
commit
9bd3ec8fec
8 changed files with 1080 additions and 3 deletions
|
|
@ -11640,8 +11640,16 @@
|
|||
"description": "Configure load balancer for high availability",
|
||||
"owner": "devops",
|
||||
"estimated_hours": 4,
|
||||
"status": "todo",
|
||||
"files_involved": [],
|
||||
"status": "completed",
|
||||
"files_involved": [
|
||||
"k8s/load-balancing/README.md",
|
||||
"k8s/load-balancing/services-with-lb.yaml",
|
||||
"k8s/load-balancing/ingress-with-lb.yaml",
|
||||
"k8s/load-balancing/cloud-load-balancers/aws-alb.yaml",
|
||||
"k8s/load-balancing/cloud-load-balancers/gcp-lb.yaml",
|
||||
"k8s/load-balancing/cloud-load-balancers/azure-lb.yaml",
|
||||
"k8s/load-balancing/pod-disruption-budget.yaml"
|
||||
],
|
||||
"implementation_steps": [
|
||||
{
|
||||
"step": 1,
|
||||
|
|
@ -11661,7 +11669,17 @@
|
|||
"Unit tests",
|
||||
"Integration tests"
|
||||
],
|
||||
"notes": ""
|
||||
"notes": "",
|
||||
"completed_at": "2025-12-25T21:41:39.502140",
|
||||
"validation": {
|
||||
"documentation": "Comprehensive load balancing guide created",
|
||||
"kubernetes_services": "Enhanced services with session affinity and load balancing",
|
||||
"ingress_config": "Enhanced ingress with load balancing algorithms and health checks",
|
||||
"cloud_load_balancers": "Configurations for AWS ALB, GCP LB, and Azure LB",
|
||||
"pod_disruption_budgets": "Pod Disruption Budgets for high availability",
|
||||
"health_checks": "Health check configurations for all services",
|
||||
"best_practices": "Load balancing strategies and best practices documented"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "INFRA-012",
|
||||
|
|
|
|||
512
k8s/load-balancing/README.md
Normal file
512
k8s/load-balancing/README.md
Normal file
|
|
@ -0,0 +1,512 @@
|
|||
# Load Balancing Configuration for Veza Platform
|
||||
|
||||
This directory contains configurations for load balancing across the Veza platform to ensure high availability, scalability, and optimal performance.
|
||||
|
||||
## Overview
|
||||
|
||||
Veza uses multiple layers of load balancing:
|
||||
|
||||
1. **Kubernetes Services**: Internal load balancing using kube-proxy
|
||||
2. **Ingress Controllers**: Nginx Ingress for HTTP/HTTPS traffic
|
||||
3. **Cloud Load Balancers**: AWS ALB, GCP Load Balancer, Azure Load Balancer
|
||||
4. **Application-Level**: Session affinity, health checks, circuit breakers
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Internet Users │
|
||||
└────────────────────┬──────────────────────────────────────┘
|
||||
│
|
||||
┌────────────▼────────────┐
|
||||
│ Cloud Load Balancer │
|
||||
│ (AWS ALB / GCP LB) │
|
||||
└────────────┬─────────────┘
|
||||
│
|
||||
┌────────────▼────────────┐
|
||||
│ Ingress Controller │
|
||||
│ (Nginx Ingress) │
|
||||
└────────────┬─────────────┘
|
||||
│
|
||||
┌────────────▼────────────┐
|
||||
│ Kubernetes Services │
|
||||
│ (ClusterIP) │
|
||||
└────────────┬─────────────┘
|
||||
│
|
||||
┌────────────▼────────────┐
|
||||
│ Application Pods │
|
||||
│ (Backend, Frontend) │
|
||||
└─────────────────────────┘
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
### 1. Kubernetes Services
|
||||
|
||||
Kubernetes Services provide internal load balancing using different algorithms:
|
||||
|
||||
- **Round Robin** (default): Distributes requests evenly
|
||||
- **Session Affinity**: Sticky sessions for stateful applications
|
||||
- **Least Connections**: Routes to pod with fewest connections
|
||||
- **IP Hash**: Consistent hashing based on client IP
|
||||
|
||||
### 2. Ingress Controller
|
||||
|
||||
Nginx Ingress Controller provides:
|
||||
- SSL/TLS termination
|
||||
- Path-based routing
|
||||
- Rate limiting
|
||||
- WebSocket support
|
||||
- Load balancing algorithms
|
||||
|
||||
### 3. Cloud Load Balancers
|
||||
|
||||
Cloud provider load balancers provide:
|
||||
- Global load balancing
|
||||
- Health checks
|
||||
- SSL/TLS termination
|
||||
- DDoS protection
|
||||
- Geographic routing
|
||||
|
||||
## Configuration
|
||||
|
||||
### Service Load Balancing
|
||||
|
||||
#### Basic Service (Round Robin)
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-backend-api
|
||||
spec:
|
||||
type: ClusterIP
|
||||
sessionAffinity: None # Round robin (default)
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: veza-backend-api
|
||||
```
|
||||
|
||||
#### Session Affinity (Sticky Sessions)
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-backend-api
|
||||
spec:
|
||||
type: ClusterIP
|
||||
sessionAffinity: ClientIP
|
||||
sessionAffinityConfig:
|
||||
clientIP:
|
||||
timeoutSeconds: 3600 # 1 hour
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: veza-backend-api
|
||||
```
|
||||
|
||||
### Ingress Load Balancing
|
||||
|
||||
#### Nginx Ingress with Load Balancing
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: veza-ingress
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri" # Consistent hashing
|
||||
nginx.ingress.kubernetes.io/load-balance: "round_robin" # Load balancing algorithm
|
||||
nginx.ingress.kubernetes.io/upstream-keepalive-connections: "64"
|
||||
nginx.ingress.kubernetes.io/upstream-keepalive-timeout: "60"
|
||||
nginx.ingress.kubernetes.io/upstream-keepalive-requests: "100"
|
||||
spec:
|
||||
rules:
|
||||
- host: api.veza.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: veza-backend-api
|
||||
port:
|
||||
number: 8080
|
||||
```
|
||||
|
||||
#### Load Balancing Algorithms
|
||||
|
||||
Available algorithms for Nginx Ingress:
|
||||
|
||||
- `round_robin`: Default, distributes requests evenly
|
||||
- `least_conn`: Routes to backend with fewest connections
|
||||
- `ip_hash`: Consistent hashing based on client IP
|
||||
- `hash $request_uri`: Consistent hashing based on request URI
|
||||
|
||||
### Cloud Load Balancer Configuration
|
||||
|
||||
#### AWS Application Load Balancer (ALB)
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-backend-api
|
||||
annotations:
|
||||
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
|
||||
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
|
||||
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
|
||||
service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "10"
|
||||
service.beta.kubernetes.io/aws-load-balancer-healthcheck-timeout: "5"
|
||||
service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: "2"
|
||||
service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: "3"
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: veza-backend-api
|
||||
```
|
||||
|
||||
#### GCP Load Balancer
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-backend-api
|
||||
annotations:
|
||||
cloud.google.com/load-balancer-type: "Internal"
|
||||
cloud.google.com/backend-config: '{"default": "veza-backend-config"}'
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: veza-backend-api
|
||||
---
|
||||
apiVersion: cloud.google.com/v1
|
||||
kind: BackendConfig
|
||||
metadata:
|
||||
name: veza-backend-config
|
||||
spec:
|
||||
healthCheck:
|
||||
checkIntervalSec: 10
|
||||
timeoutSec: 5
|
||||
healthyThreshold: 2
|
||||
unhealthyThreshold: 3
|
||||
type: HTTP
|
||||
requestPath: /health
|
||||
sessionAffinity:
|
||||
affinityType: "CLIENT_IP"
|
||||
affinityCookieTtlSec: 3600
|
||||
```
|
||||
|
||||
#### Azure Load Balancer
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-backend-api
|
||||
annotations:
|
||||
service.beta.kubernetes.io/azure-load-balancer-internal: "false"
|
||||
service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: "/health"
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: veza-backend-api
|
||||
```
|
||||
|
||||
## Health Checks
|
||||
|
||||
### Service Health Checks
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-backend-api
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: veza-backend-api
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: veza-backend-api
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: veza-backend-api
|
||||
image: veza-backend-api:latest
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 8080
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
```
|
||||
|
||||
### Ingress Health Checks
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: veza-ingress
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/health-check: "true"
|
||||
nginx.ingress.kubernetes.io/health-check-path: "/health"
|
||||
nginx.ingress.kubernetes.io/health-check-interval: "10s"
|
||||
nginx.ingress.kubernetes.io/health-check-timeout: "5s"
|
||||
nginx.ingress.kubernetes.io/health-check-expected-status: "200"
|
||||
```
|
||||
|
||||
## Load Balancing Strategies
|
||||
|
||||
### 1. Round Robin (Default)
|
||||
|
||||
**Use Case**: Stateless applications, API services
|
||||
|
||||
**Configuration**:
|
||||
```yaml
|
||||
sessionAffinity: None
|
||||
```
|
||||
|
||||
**Pros**:
|
||||
- Simple and fair distribution
|
||||
- No state management needed
|
||||
|
||||
**Cons**:
|
||||
- May not account for server load
|
||||
- No session persistence
|
||||
|
||||
### 2. Session Affinity (Sticky Sessions)
|
||||
|
||||
**Use Case**: Stateful applications, user sessions
|
||||
|
||||
**Configuration**:
|
||||
```yaml
|
||||
sessionAffinity: ClientIP
|
||||
sessionAffinityConfig:
|
||||
clientIP:
|
||||
timeoutSeconds: 3600
|
||||
```
|
||||
|
||||
**Pros**:
|
||||
- Maintains user sessions
|
||||
- Better for stateful applications
|
||||
|
||||
**Cons**:
|
||||
- Uneven load distribution
|
||||
- Single point of failure if pod crashes
|
||||
|
||||
### 3. Least Connections
|
||||
|
||||
**Use Case**: Long-lived connections, WebSocket
|
||||
|
||||
**Configuration**:
|
||||
```yaml
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/load-balance: "least_conn"
|
||||
```
|
||||
|
||||
**Pros**:
|
||||
- Better load distribution
|
||||
- Accounts for active connections
|
||||
|
||||
**Cons**:
|
||||
- More complex than round robin
|
||||
- Requires connection tracking
|
||||
|
||||
### 4. Consistent Hashing
|
||||
|
||||
**Use Case**: Caching, distributed systems
|
||||
|
||||
**Configuration**:
|
||||
```yaml
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"
|
||||
```
|
||||
|
||||
**Pros**:
|
||||
- Predictable routing
|
||||
- Better cache utilization
|
||||
|
||||
**Cons**:
|
||||
- Uneven distribution if hash keys are skewed
|
||||
- More complex configuration
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Health Checks
|
||||
|
||||
- **Liveness Probe**: Detects and restarts unhealthy pods
|
||||
- **Readiness Probe**: Removes pods from load balancer if not ready
|
||||
- **Startup Probe**: Allows slow-starting applications time to initialize
|
||||
|
||||
### 2. Resource Limits
|
||||
|
||||
Set appropriate resource limits to prevent resource exhaustion:
|
||||
|
||||
```yaml
|
||||
resources:
|
||||
requests:
|
||||
cpu: "100m"
|
||||
memory: "128Mi"
|
||||
limits:
|
||||
cpu: "500m"
|
||||
memory: "512Mi"
|
||||
```
|
||||
|
||||
### 3. Pod Disruption Budgets
|
||||
|
||||
Ensure minimum availability during updates:
|
||||
|
||||
```yaml
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: veza-backend-api-pdb
|
||||
spec:
|
||||
minAvailable: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: veza-backend-api
|
||||
```
|
||||
|
||||
### 4. Horizontal Pod Autoscaling
|
||||
|
||||
Automatically scale based on load:
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: veza-backend-api-hpa
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: veza-backend-api
|
||||
minReplicas: 3
|
||||
maxReplicas: 10
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
```
|
||||
|
||||
### 5. Circuit Breakers
|
||||
|
||||
Implement circuit breakers for resilience:
|
||||
|
||||
```yaml
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/upstream-max-fails: "3"
|
||||
nginx.ingress.kubernetes.io/upstream-fail-timeout: "30s"
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Metrics to Monitor
|
||||
|
||||
- **Request Rate**: Requests per second per backend
|
||||
- **Response Time**: P50, P95, P99 latencies
|
||||
- **Error Rate**: 4xx and 5xx error rates
|
||||
- **Connection Count**: Active connections per backend
|
||||
- **Health Check Status**: Success/failure rates
|
||||
|
||||
### Prometheus Queries
|
||||
|
||||
```promql
|
||||
# Request rate per backend
|
||||
rate(nginx_ingress_controller_requests[5m])
|
||||
|
||||
# Response time percentiles
|
||||
histogram_quantile(0.95, rate(nginx_ingress_controller_request_duration_seconds_bucket[5m]))
|
||||
|
||||
# Error rate
|
||||
rate(nginx_ingress_controller_requests{status=~"5.."}[5m])
|
||||
|
||||
# Active connections
|
||||
nginx_ingress_controller_connections
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Uneven Load Distribution
|
||||
|
||||
```bash
|
||||
# Check pod distribution across nodes
|
||||
kubectl get pods -n veza-production -o wide
|
||||
|
||||
# Check service endpoints
|
||||
kubectl get endpoints veza-backend-api -n veza-production
|
||||
|
||||
# Check load balancer statistics
|
||||
kubectl exec -it nginx-ingress-controller-pod -n ingress-nginx -- \
|
||||
curl http://localhost:10254/nginx_status
|
||||
```
|
||||
|
||||
### Health Check Failures
|
||||
|
||||
```bash
|
||||
# Check pod health
|
||||
kubectl get pods -n veza-production
|
||||
|
||||
# Check health check logs
|
||||
kubectl logs deployment/veza-backend-api -n veza-production | grep health
|
||||
|
||||
# Test health endpoint manually
|
||||
kubectl exec -it deployment/veza-backend-api -n veza-production -- \
|
||||
curl http://localhost:8080/health
|
||||
```
|
||||
|
||||
### Session Affinity Issues
|
||||
|
||||
```bash
|
||||
# Check session affinity configuration
|
||||
kubectl get service veza-backend-api -n veza-production -o yaml | grep -A 5 sessionAffinity
|
||||
|
||||
# Test session persistence
|
||||
for i in {1..10}; do
|
||||
curl -H "Cookie: session=test" https://api.veza.com/api/v1/tracks
|
||||
done
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [Kubernetes Services Documentation](https://kubernetes.io/docs/concepts/services-networking/service/)
|
||||
- [Nginx Ingress Controller](https://kubernetes.github.io/ingress-nginx/)
|
||||
- [AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller/)
|
||||
- [GCP Load Balancer](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress)
|
||||
|
||||
92
k8s/load-balancing/cloud-load-balancers/aws-alb.yaml
Normal file
92
k8s/load-balancing/cloud-load-balancers/aws-alb.yaml
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# AWS Application Load Balancer Configuration
|
||||
# This configuration uses the AWS Load Balancer Controller
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-backend-api-alb
|
||||
namespace: veza-production
|
||||
annotations:
|
||||
# Use AWS Load Balancer Controller
|
||||
service.beta.kubernetes.io/aws-load-balancer-type: "external"
|
||||
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
|
||||
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
|
||||
|
||||
# Cross-zone load balancing
|
||||
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
|
||||
|
||||
# Health checks
|
||||
service.beta.kubernetes.io/aws-load-balancer-healthcheck-interval: "10"
|
||||
service.beta.kubernetes.io/aws-load-balancer-healthcheck-timeout: "5"
|
||||
service.beta.kubernetes.io/aws-load-balancer-healthcheck-healthy-threshold: "2"
|
||||
service.beta.kubernetes.io/aws-load-balancer-healthcheck-unhealthy-threshold: "3"
|
||||
service.beta.kubernetes.io/aws-load-balancer-healthcheck-path: "/health"
|
||||
|
||||
# Connection draining
|
||||
service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled: "true"
|
||||
service.beta.kubernetes.io/aws-load-balancer-connection-draining-timeout: "60"
|
||||
|
||||
# SSL/TLS
|
||||
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:region:account:certificate/cert-id"
|
||||
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
|
||||
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
|
||||
|
||||
# Access logs
|
||||
service.beta.kubernetes.io/aws-load-balancer-access-log-enabled: "true"
|
||||
service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-name: "veza-alb-logs"
|
||||
service.beta.kubernetes.io/aws-load-balancer-access-log-s3-bucket-prefix: "alb"
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
- name: https
|
||||
port: 443
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: veza-backend-api
|
||||
---
|
||||
# Ingress for ALB (using AWS Load Balancer Controller)
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: veza-ingress-alb
|
||||
namespace: veza-production
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: alb
|
||||
alb.ingress.kubernetes.io/scheme: internet-facing
|
||||
alb.ingress.kubernetes.io/target-type: ip
|
||||
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]'
|
||||
alb.ingress.kubernetes.io/ssl-redirect: "443"
|
||||
alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:region:account:certificate/cert-id"
|
||||
alb.ingress.kubernetes.io/load-balancer-attributes: |
|
||||
idle_timeout.timeout_seconds=60,
|
||||
routing.http2.enabled=true,
|
||||
access_logs.s3.enabled=true,
|
||||
access_logs.s3.bucket=veza-alb-logs,
|
||||
access_logs.s3.prefix=alb
|
||||
alb.ingress.kubernetes.io/healthcheck-path: "/health"
|
||||
alb.ingress.kubernetes.io/healthcheck-interval-seconds: "10"
|
||||
alb.ingress.kubernetes.io/healthcheck-timeout-seconds: "5"
|
||||
alb.ingress.kubernetes.io/healthy-threshold-count: "2"
|
||||
alb.ingress.kubernetes.io/unhealthy-threshold-count: "3"
|
||||
alb.ingress.kubernetes.io/target-group-attributes: |
|
||||
stickiness.enabled=true,
|
||||
stickiness.type=lb_cookie,
|
||||
stickiness.lb_cookie.duration_seconds=3600
|
||||
spec:
|
||||
rules:
|
||||
- host: api.veza.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: veza-backend-api
|
||||
port:
|
||||
number: 8080
|
||||
|
||||
72
k8s/load-balancing/cloud-load-balancers/azure-lb.yaml
Normal file
72
k8s/load-balancing/cloud-load-balancers/azure-lb.yaml
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Azure Load Balancer Configuration
|
||||
# This configuration uses Azure-native load balancing
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-backend-api-lb
|
||||
namespace: veza-production
|
||||
annotations:
|
||||
# Use Azure Load Balancer
|
||||
service.beta.kubernetes.io/azure-load-balancer-internal: "false"
|
||||
service.beta.kubernetes.io/azure-load-balancer-internal-subnet: "subnet-name"
|
||||
|
||||
# Health probe
|
||||
service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: "/health"
|
||||
service.beta.kubernetes.io/azure-load-balancer-health-probe-interval: "10"
|
||||
service.beta.kubernetes.io/azure-load-balancer-health-probe-num-of-probe: "3"
|
||||
service.beta.kubernetes.io/azure-load-balancer-health-probe-timeout: "5"
|
||||
|
||||
# Load balancing algorithm
|
||||
service.beta.kubernetes.io/azure-load-balancer-mode: "Standard" # or "Basic"
|
||||
|
||||
# Session affinity
|
||||
service.beta.kubernetes.io/azure-load-balancer-tcp-idle-timeout: "240"
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
- name: https
|
||||
port: 443
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: veza-backend-api
|
||||
---
|
||||
# Ingress for Azure (using Nginx Ingress with Azure Application Gateway)
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: veza-ingress-azure
|
||||
namespace: veza-production
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: azure/application-gateway
|
||||
appgw.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
appgw.ingress.kubernetes.io/backend-protocol: "http"
|
||||
appgw.ingress.kubernetes.io/health-probe-path: "/health"
|
||||
appgw.ingress.kubernetes.io/health-probe-interval: "10"
|
||||
appgw.ingress.kubernetes.io/health-probe-timeout: "5"
|
||||
appgw.ingress.kubernetes.io/health-probe-unhealthy-threshold: "3"
|
||||
appgw.ingress.kubernetes.io/cookie-based-affinity: "true"
|
||||
appgw.ingress.kubernetes.io/request-timeout: "60"
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- api.veza.com
|
||||
- app.veza.com
|
||||
secretName: veza-tls
|
||||
rules:
|
||||
- host: api.veza.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: veza-backend-api
|
||||
port:
|
||||
number: 8080
|
||||
|
||||
113
k8s/load-balancing/cloud-load-balancers/gcp-lb.yaml
Normal file
113
k8s/load-balancing/cloud-load-balancers/gcp-lb.yaml
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
# Google Cloud Load Balancer Configuration
|
||||
# This configuration uses GCP-native load balancing
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-backend-api-lb
|
||||
namespace: veza-production
|
||||
annotations:
|
||||
# Use GCP Load Balancer
|
||||
cloud.google.com/load-balancer-type: "Internal" # or "External"
|
||||
cloud.google.com/backend-config: '{"default": "veza-backend-config"}'
|
||||
cloud.google.com/neg: '{"ingress": true}'
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: veza-backend-api
|
||||
---
|
||||
# BackendConfig for GCP Load Balancer
|
||||
apiVersion: cloud.google.com/v1
|
||||
kind: BackendConfig
|
||||
metadata:
|
||||
name: veza-backend-config
|
||||
namespace: veza-production
|
||||
spec:
|
||||
# Health checks
|
||||
healthCheck:
|
||||
checkIntervalSec: 10
|
||||
timeoutSec: 5
|
||||
healthyThreshold: 2
|
||||
unhealthyThreshold: 3
|
||||
type: HTTP
|
||||
requestPath: /health
|
||||
port: 8080
|
||||
|
||||
# Session affinity
|
||||
sessionAffinity:
|
||||
affinityType: "CLIENT_IP"
|
||||
affinityCookieTtlSec: 3600
|
||||
|
||||
# Connection draining
|
||||
connectionDraining:
|
||||
drainingTimeoutSec: 60
|
||||
|
||||
# Timeout
|
||||
timeoutSec: 60
|
||||
|
||||
# IAP (Identity-Aware Proxy) - optional
|
||||
# iap:
|
||||
# enabled: true
|
||||
# oauthclientCredentials:
|
||||
# secretName: iap-oauth-credentials
|
||||
|
||||
# CDN - optional
|
||||
# cdn:
|
||||
# enabled: true
|
||||
# cachePolicy:
|
||||
# includeHost: true
|
||||
# includeProtocol: true
|
||||
# includeQueryString: true
|
||||
---
|
||||
# FrontendConfig for SSL policies
|
||||
apiVersion: networking.gke.io/v1beta1
|
||||
kind: FrontendConfig
|
||||
metadata:
|
||||
name: veza-frontend-config
|
||||
namespace: veza-production
|
||||
spec:
|
||||
sslPolicy: "modern"
|
||||
redirectToHttps:
|
||||
enabled: true
|
||||
responseCodeName: "MOVED_PERMANENTLY_DEFAULT"
|
||||
---
|
||||
# Ingress for GCP Load Balancer
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: veza-ingress-gcp
|
||||
namespace: veza-production
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: "gce"
|
||||
kubernetes.io/ingress.global-static-ip-name: "veza-static-ip"
|
||||
networking.gke.io/managed-certificates: "veza-ssl-cert"
|
||||
networking.gke.io/v1beta1.FrontendConfig: "veza-frontend-config"
|
||||
spec:
|
||||
rules:
|
||||
- host: api.veza.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: veza-backend-api
|
||||
port:
|
||||
number: 8080
|
||||
---
|
||||
# ManagedCertificate for automatic SSL
|
||||
apiVersion: networking.gke.io/v1
|
||||
kind: ManagedCertificate
|
||||
metadata:
|
||||
name: veza-ssl-cert
|
||||
namespace: veza-production
|
||||
spec:
|
||||
domains:
|
||||
- api.veza.com
|
||||
- app.veza.com
|
||||
|
||||
119
k8s/load-balancing/ingress-with-lb.yaml
Normal file
119
k8s/load-balancing/ingress-with-lb.yaml
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# Enhanced Ingress with Load Balancing Configuration
|
||||
# This ingress includes load balancing annotations and optimizations
|
||||
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: veza-ingress
|
||||
namespace: veza-production
|
||||
annotations:
|
||||
# Ingress class
|
||||
kubernetes.io/ingress.class: nginx
|
||||
|
||||
# SSL/TLS
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.2 TLSv1.3"
|
||||
nginx.ingress.kubernetes.io/ssl-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384"
|
||||
nginx.ingress.kubernetes.io/ssl-prefer-server-ciphers: "true"
|
||||
|
||||
# Load Balancing
|
||||
nginx.ingress.kubernetes.io/load-balance: "round_robin" # Options: round_robin, least_conn, ip_hash
|
||||
# nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri" # For consistent hashing
|
||||
|
||||
# Connection Keep-Alive
|
||||
nginx.ingress.kubernetes.io/upstream-keepalive-connections: "64"
|
||||
nginx.ingress.kubernetes.io/upstream-keepalive-timeout: "60"
|
||||
nginx.ingress.kubernetes.io/upstream-keepalive-requests: "100"
|
||||
|
||||
# Health Checks
|
||||
nginx.ingress.kubernetes.io/health-check: "true"
|
||||
nginx.ingress.kubernetes.io/health-check-path: "/health"
|
||||
nginx.ingress.kubernetes.io/health-check-interval: "10s"
|
||||
nginx.ingress.kubernetes.io/health-check-timeout: "5s"
|
||||
nginx.ingress.kubernetes.io/health-check-expected-status: "200"
|
||||
|
||||
# Circuit Breaker
|
||||
nginx.ingress.kubernetes.io/upstream-max-fails: "3"
|
||||
nginx.ingress.kubernetes.io/upstream-fail-timeout: "30s"
|
||||
|
||||
# Rate Limiting
|
||||
nginx.ingress.kubernetes.io/limit-rps: "100"
|
||||
nginx.ingress.kubernetes.io/limit-connections: "10"
|
||||
|
||||
# Timeouts
|
||||
nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
|
||||
|
||||
# WebSocket Support (for chat and stream)
|
||||
nginx.ingress.kubernetes.io/proxy-set-headers: "veza-ws-headers"
|
||||
nginx.ingress.kubernetes.io/websocket-services: "veza-chat-server,veza-stream-server"
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "86400" # 24 hours for WebSocket
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "86400"
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- app.veza.com
|
||||
- api.veza.com
|
||||
- chat.veza.com
|
||||
- stream.veza.com
|
||||
secretName: veza-tls
|
||||
rules:
|
||||
# Frontend
|
||||
- host: app.veza.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: veza-frontend
|
||||
port:
|
||||
number: 80
|
||||
# Backend API
|
||||
- host: api.veza.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: veza-backend-api
|
||||
port:
|
||||
number: 8080
|
||||
# Chat Server (WebSocket)
|
||||
- host: chat.veza.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: veza-chat-server
|
||||
port:
|
||||
number: 8081
|
||||
# Stream Server
|
||||
- host: stream.veza.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: veza-stream-server
|
||||
port:
|
||||
number: 8080
|
||||
---
|
||||
# ConfigMap for custom headers
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: veza-ws-headers
|
||||
namespace: veza-production
|
||||
data:
|
||||
X-Forwarded-Proto: "https"
|
||||
X-Real-IP: "$remote_addr"
|
||||
X-Forwarded-For: "$proxy_add_x_forwarded_for"
|
||||
|
||||
52
k8s/load-balancing/pod-disruption-budget.yaml
Normal file
52
k8s/load-balancing/pod-disruption-budget.yaml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Pod Disruption Budgets for High Availability
|
||||
# These ensure minimum availability during voluntary disruptions (updates, node maintenance)
|
||||
|
||||
---
|
||||
# Backend API Pod Disruption Budget
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: veza-backend-api-pdb
|
||||
namespace: veza-production
|
||||
spec:
|
||||
minAvailable: 2 # At least 2 pods must be available
|
||||
selector:
|
||||
matchLabels:
|
||||
app: veza-backend-api
|
||||
---
|
||||
# Frontend Pod Disruption Budget
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: veza-frontend-pdb
|
||||
namespace: veza-production
|
||||
spec:
|
||||
minAvailable: 1 # At least 1 pod must be available
|
||||
selector:
|
||||
matchLabels:
|
||||
app: veza-frontend
|
||||
---
|
||||
# Chat Server Pod Disruption Budget
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: veza-chat-server-pdb
|
||||
namespace: veza-production
|
||||
spec:
|
||||
minAvailable: 1 # At least 1 pod must be available
|
||||
selector:
|
||||
matchLabels:
|
||||
app: veza-chat-server
|
||||
---
|
||||
# Stream Server Pod Disruption Budget
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: veza-stream-server-pdb
|
||||
namespace: veza-production
|
||||
spec:
|
||||
minAvailable: 1 # At least 1 pod must be available
|
||||
selector:
|
||||
matchLabels:
|
||||
app: veza-stream-server
|
||||
|
||||
99
k8s/load-balancing/services-with-lb.yaml
Normal file
99
k8s/load-balancing/services-with-lb.yaml
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
# Enhanced Services with Load Balancing Configuration
|
||||
# These services include session affinity, health checks, and load balancing optimizations
|
||||
|
||||
---
|
||||
# Backend API Service with Session Affinity
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-backend-api
|
||||
namespace: veza-production
|
||||
labels:
|
||||
app: veza-backend-api
|
||||
annotations:
|
||||
# Optional: For cloud load balancers
|
||||
# service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
|
||||
# service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
|
||||
spec:
|
||||
type: ClusterIP
|
||||
# Session affinity for stateful operations (optional)
|
||||
# Uncomment if needed for sticky sessions
|
||||
# sessionAffinity: ClientIP
|
||||
# sessionAffinityConfig:
|
||||
# clientIP:
|
||||
# timeoutSeconds: 3600 # 1 hour
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: veza-backend-api
|
||||
---
|
||||
# Frontend Service
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-frontend
|
||||
namespace: veza-production
|
||||
labels:
|
||||
app: veza-frontend
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 80
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: veza-frontend
|
||||
---
|
||||
# Chat Server Service with WebSocket Support
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-chat-server
|
||||
namespace: veza-production
|
||||
labels:
|
||||
app: veza-chat-server
|
||||
spec:
|
||||
type: ClusterIP
|
||||
# Session affinity recommended for WebSocket connections
|
||||
sessionAffinity: ClientIP
|
||||
sessionAffinityConfig:
|
||||
clientIP:
|
||||
timeoutSeconds: 3600 # 1 hour for WebSocket sessions
|
||||
ports:
|
||||
- name: http
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
protocol: TCP
|
||||
- name: ws
|
||||
port: 8082
|
||||
targetPort: 8082
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: veza-chat-server
|
||||
---
|
||||
# Stream Server Service
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: veza-stream-server
|
||||
namespace: veza-production
|
||||
labels:
|
||||
app: veza-stream-server
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
- name: ws
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: veza-stream-server
|
||||
|
||||
Loading…
Reference in a new issue