Files
k3s/009-基础设施/007-keda/readme.md
2026-02-05 00:11:05 +08:00

459 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# KEDA 自动扩缩容
## 功能说明
KEDA (Kubernetes Event Driven Autoscaling) 为 K3s 集群提供基于事件驱动的自动扩缩容能力。
### 核心功能
- **按需启动/停止服务**:空闲时自动缩容到 0节省资源
- **基于指标自动扩缩容**:根据实际负载动态调整副本数
- **多种触发器支持**CPU、内存、Prometheus 指标、数据库连接等
- **与 Prometheus 集成**:利用现有监控数据进行扩缩容决策
## 部署方式
```bash
cd /home/fei/k3s/009-基础设施/007-keda
bash deploy.sh
```
## 已配置的服务
### 1. Navigation 导航服务 ✅
- **最小副本数**: 0空闲时完全停止
- **最大副本数**: 10
- **触发条件**:
- HTTP 请求速率 > 10 req/min
- CPU 使用率 > 60%
- **冷却期**: 3 分钟
**配置文件**: `scalers/navigation-scaler.yaml`
### 2. Redis 缓存服务 ⏳
- **最小副本数**: 0空闲时完全停止
- **最大副本数**: 5
- **触发条件**:
- 有客户端连接
- CPU 使用率 > 70%
- **冷却期**: 5 分钟
**配置文件**: `scalers/redis-scaler.yaml`
**状态**: 待应用(需要先为 Redis 添加 Prometheus exporter
### 3. PostgreSQL 数据库 ❌
**不推荐使用 KEDA 扩展 PostgreSQL**
原因:
- PostgreSQL 是有状态服务,多个副本会导致存储冲突
- 需要配置主从复制才能安全扩展
- 建议使用 PostgreSQL Operator 或 PgBouncer + KEDA
详细说明:`scalers/postgresql-说明.md`
## 应用 ScaledObject
### 部署所有 Scaler
```bash
# 应用 Navigation Scaler
kubectl apply -f scalers/navigation-scaler.yaml
# 应用 Redis Scaler需要先配置 Redis exporter
kubectl apply -f scalers/redis-scaler.yaml
# ⚠️ PostgreSQL 不推荐使用 KEDA 扩展
# 详见: scalers/postgresql-说明.md
```
### 查看 ScaledObject 状态
```bash
# 查看所有 ScaledObject
kubectl get scaledobject -A
# 查看详细信息
kubectl describe scaledobject navigation-scaler -n navigation
kubectl describe scaledobject redis-scaler -n redis
kubectl describe scaledobject postgresql-scaler -n postgresql
```
### 查看自动创建的 HPA
```bash
# KEDA 会自动创建 HorizontalPodAutoscaler
kubectl get hpa -A
```
## 支持的触发器类型
### 1. Prometheus 指标
```yaml
triggers:
- type: prometheus
metadata:
serverAddress: http://kube-prometheus-stack-prometheus.monitoring.svc.cluster.local:9090
metricName: custom_metric
query: sum(rate(http_requests_total[1m]))
threshold: "100"
```
### 2. CPU/内存使用率
```yaml
triggers:
- type: cpu
metadata:
type: Utilization
value: "70"
- type: memory
metadata:
type: Utilization
value: "80"
```
### 3. Redis 队列长度
```yaml
triggers:
- type: redis
metadata:
address: redis.redis.svc.cluster.local:6379
listName: mylist
listLength: "5"
```
### 4. PostgreSQL 查询
```yaml
triggers:
- type: postgresql
metadata:
connectionString: postgresql://user:pass@host:5432/db
query: "SELECT COUNT(*) FROM tasks WHERE status='pending'"
targetQueryValue: "10"
```
### 5. Cron 定时触发
```yaml
triggers:
- type: cron
metadata:
timezone: Asia/Shanghai
start: 0 8 * * * # 每天 8:00 扩容
end: 0 18 * * * # 每天 18:00 缩容
desiredReplicas: "3"
```
## 为新服务添加自动扩缩容
### 步骤 1: 确保服务配置正确
服务的 Deployment 必须配置 `resources.requests`
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
# 不要设置 replicas由 KEDA 管理
template:
spec:
containers:
- name: myapp
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
```
### 步骤 2: 创建 ScaledObject
```yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: myapp-scaler
namespace: myapp
spec:
scaleTargetRef:
name: myapp
minReplicaCount: 0
maxReplicaCount: 10
pollingInterval: 30
cooldownPeriod: 300
triggers:
- type: prometheus
metadata:
serverAddress: http://kube-prometheus-stack-prometheus.monitoring.svc.cluster.local:9090
metricName: myapp_requests
query: sum(rate(http_requests_total{app="myapp"}[1m]))
threshold: "50"
```
### 步骤 3: 应用配置
```bash
kubectl apply -f myapp-scaler.yaml
```
## 监控和调试
### 查看 KEDA 日志
```bash
# Operator 日志
kubectl logs -n keda -l app.kubernetes.io/name=keda-operator -f
# Metrics Server 日志
kubectl logs -n keda -l app.kubernetes.io/name=keda-metrics-apiserver -f
```
### 查看扩缩容事件
```bash
# 查看 HPA 事件
kubectl describe hpa -n <namespace>
# 查看 Pod 事件
kubectl get events -n <namespace> --sort-by='.lastTimestamp'
```
### 在 Prometheus 中查询 KEDA 指标
访问 https://prometheus.u6.net3w.com查询
```promql
# KEDA Scaler 活跃状态
keda_scaler_active
# KEDA Scaler 错误
keda_scaler_errors_total
# 当前指标值
keda_scaler_metrics_value
```
### 在 Grafana 中查看 KEDA 仪表板
1. 访问 https://grafana.u6.net3w.com
2. 导入 KEDA 官方仪表板 ID: **14691**
3. 查看实时扩缩容状态
## 测试自动扩缩容
### 测试 Navigation 服务
**测试缩容到 0**
```bash
# 1. 停止访问导航页面,等待 3 分钟
sleep 180
# 2. 检查副本数
kubectl get deployment navigation -n navigation
# 预期输出READY 0/0
```
**测试从 0 扩容:**
```bash
# 1. 访问导航页面
curl https://dh.u6.net3w.com
# 2. 监控副本数变化
kubectl get deployment navigation -n navigation -w
# 预期:副本数从 0 变为 1约 10-30 秒)
```
### 测试 Redis 服务
**测试基于连接数扩容:**
```bash
# 1. 连接 Redis
kubectl run redis-client --rm -it --image=redis:7-alpine -- redis-cli -h redis.redis.svc.cluster.local
# 2. 在另一个终端监控
kubectl get deployment redis -n redis -w
# 预期:有连接时副本数从 0 变为 1
```
### 测试 PostgreSQL 服务
**测试基于连接数扩容:**
```bash
# 1. 创建多个数据库连接
for i in {1..15}; do
kubectl run pg-client-$i --image=postgres:16-alpine --restart=Never -- \
psql -h postgresql-service.postgresql.svc.cluster.local -U postgres -c "SELECT pg_sleep(60);" &
done
# 2. 监控副本数
kubectl get statefulset postgresql -n postgresql -w
# 预期:连接数超过 10 时,副本数从 1 增加到 2
```
## 故障排查
### ScaledObject 未生效
**检查 ScaledObject 状态:**
```bash
kubectl describe scaledobject <name> -n <namespace>
```
**常见问题:**
1. **Deployment 设置了固定 replicas**
- 解决:移除 Deployment 中的 `replicas` 字段
2. **缺少 resources.requests**
- 解决:为容器添加 `resources.requests` 配置
3. **Prometheus 查询错误**
- 解决:在 Prometheus UI 中测试查询语句
### 服务无法缩容到 0
**可能原因:**
1. **仍有活跃连接或请求**
- 检查:查看 Prometheus 指标值
2. **cooldownPeriod 未到**
- 检查:等待冷却期结束
3. **minReplicaCount 设置错误**
- 检查:确认 `minReplicaCount: 0`
### 扩容速度慢
**优化建议:**
1. **减少 pollingInterval**
```yaml
pollingInterval: 15 # 从 30 秒改为 15 秒
```
2. **降低 threshold**
```yaml
threshold: "5" # 降低触发阈值
```
3. **使用多个触发器**
```yaml
triggers:
- type: prometheus
# ...
- type: cpu
# ...
```
## 最佳实践
### 1. 合理设置副本数范围
- **无状态服务**`minReplicaCount: 0`,节省资源
- **有状态服务**`minReplicaCount: 1`,保证可用性
- **关键服务**`minReplicaCount: 2`,保证高可用
### 2. 选择合适的冷却期
- **快速响应服务**`cooldownPeriod: 60-180`1-3 分钟)
- **一般服务**`cooldownPeriod: 300`5 分钟)
- **数据库服务**`cooldownPeriod: 600-900`10-15 分钟)
### 3. 监控扩缩容行为
- 定期查看 Grafana 仪表板
- 设置告警规则
- 分析扩缩容历史
### 4. 测试冷启动时间
- 测量从 0 扩容到可用的时间
- 优化镜像大小和启动脚本
- 考虑使用 `minReplicaCount: 1` 避免冷启动
## 配置参考
### ScaledObject 完整配置示例
```yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: example-scaler
namespace: example
spec:
scaleTargetRef:
name: example-deployment
kind: Deployment # 可选Deployment, StatefulSet
apiVersion: apps/v1 # 可选
minReplicaCount: 0 # 最小副本数
maxReplicaCount: 10 # 最大副本数
pollingInterval: 30 # 轮询间隔(秒)
cooldownPeriod: 300 # 缩容冷却期(秒)
idleReplicaCount: 0 # 空闲时的副本数
fallback: # 故障回退配置
failureThreshold: 3
replicas: 2
advanced: # 高级配置
restoreToOriginalReplicaCount: false
horizontalPodAutoscalerConfig:
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus:9090
metricName: custom_metric
query: sum(rate(metric[1m]))
threshold: "100"
```
## 卸载 KEDA
```bash
# 删除所有 ScaledObject
kubectl delete scaledobject --all -A
# 卸载 KEDA
helm uninstall keda -n keda
# 删除命名空间
kubectl delete namespace keda
```
## 参考资源
- KEDA 官方文档: https://keda.sh/docs/
- KEDA Scalers: https://keda.sh/docs/scalers/
- KEDA GitHub: https://github.com/kedacore/keda
- Grafana 仪表板: https://grafana.com/grafana/dashboards/14691
---
**KEDA 让您的 K3s 集群更智能、更高效!** 🚀