# KEDA HTTP Add-on 自动缩容到 0 配置指南 本指南说明如何使用 KEDA HTTP Add-on 实现应用在无流量时自动缩容到 0,有访问时自动启动。 ## 前提条件 1. K3s 集群已安装 2. KEDA 已安装 3. KEDA HTTP Add-on 已安装 4. Traefik 作为 Ingress Controller ### 检查 KEDA HTTP Add-on 是否已安装 ```bash kubectl get pods -n keda | grep http ``` 应该看到类似输出: ``` keda-add-ons-http-controller-manager-xxx 1/1 Running keda-add-ons-http-external-scaler-xxx 1/1 Running keda-add-ons-http-interceptor-xxx 1/1 Running ``` ### 如果未安装,执行以下命令安装 ```bash helm repo add kedacore https://kedacore.github.io/charts helm repo update helm install http-add-on kedacore/keda-add-ons-http --namespace keda ``` ## 配置步骤 ### 1. 准备应用的基础资源 确保你的应用已经有以下资源: - Deployment - Service - Namespace 示例: ```yaml apiVersion: v1 kind: Namespace metadata: name: myapp --- apiVersion: apps/v1 kind: Deployment metadata: name: myapp namespace: myapp spec: replicas: 1 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: your-image:tag ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: myapp namespace: myapp spec: selector: app: myapp ports: - port: 80 targetPort: 80 ``` ### 2. 创建 HTTPScaledObject 这是实现自动缩容到 0 的核心配置。 ```yaml apiVersion: http.keda.sh/v1alpha1 kind: HTTPScaledObject metadata: name: myapp-http-scaler namespace: myapp # 必须与应用在同一个 namespace spec: hosts: - myapp.example.com # 你的域名 pathPrefixes: - / # 匹配的路径前缀 scaleTargetRef: name: myapp # Deployment 名称 kind: Deployment apiVersion: apps/v1 service: myapp # Service 名称 port: 80 # Service 端口 replicas: min: 0 # 空闲时缩容到 0 max: 10 # 最多扩容到 10 个副本 scalingMetric: requestRate: granularity: 1s targetValue: 100 # 每秒 100 个请求时扩容 window: 1m scaledownPeriod: 300 # 5 分钟(300秒)无流量后缩容到 0 ``` **重要参数说明:** - `hosts`: 你的应用域名 - `scaleTargetRef.name`: 你的 Deployment 名称 - `scaleTargetRef.service`: 你的 Service 名称 - `scaleTargetRef.port`: 你的 Service 端口 - `replicas.min: 0`: 允许缩容到 0 - `scaledownPeriod`: 无流量后多久缩容(秒) ### 3. 创建 Traefik IngressRoute **重要:IngressRoute 必须在 keda namespace 中创建**,因为它需要引用 keda namespace 的拦截器服务。 ```yaml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: myapp-ingress namespace: keda # 注意:必须在 keda namespace spec: entryPoints: - web # HTTP 入口 # - websecure # 如果需要 HTTPS,添加这个 routes: - match: Host(`myapp.example.com`) # 你的域名 kind: Rule services: - name: keda-add-ons-http-interceptor-proxy port: 8080 ``` **如果需要 HTTPS,添加 TLS 配置:** ```yaml apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: myapp-ingress namespace: keda spec: entryPoints: - websecure routes: - match: Host(`myapp.example.com`) kind: Rule services: - name: keda-add-ons-http-interceptor-proxy port: 8080 tls: certResolver: letsencrypt # 你的证书解析器 ``` ### 4. 完整配置文件模板 将以下内容保存为 `myapp-keda-scaler.yaml`,并根据你的应用修改相应的值: ```yaml --- # HTTPScaledObject - 实现自动缩容到 0 apiVersion: http.keda.sh/v1alpha1 kind: HTTPScaledObject metadata: name: myapp-http-scaler namespace: myapp # 改为你的 namespace spec: hosts: - myapp.example.com # 改为你的域名 pathPrefixes: - / scaleTargetRef: name: myapp # 改为你的 Deployment 名称 kind: Deployment apiVersion: apps/v1 service: myapp # 改为你的 Service 名称 port: 80 # 改为你的 Service 端口 replicas: min: 0 max: 10 scalingMetric: requestRate: granularity: 1s targetValue: 100 window: 1m scaledownPeriod: 300 # 5 分钟无流量后缩容 --- # Traefik IngressRoute - 路由流量到 KEDA 拦截器 apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: myapp-ingress namespace: keda # 必须在 keda namespace spec: entryPoints: - web routes: - match: Host(`myapp.example.com`) # 改为你的域名 kind: Rule services: - name: keda-add-ons-http-interceptor-proxy port: 8080 ``` ### 5. 应用配置 ```bash kubectl apply -f myapp-keda-scaler.yaml ``` ### 6. 验证配置 ```bash # 查看 HTTPScaledObject 状态 kubectl get httpscaledobject -n myapp # 应该看到 READY = True # NAME TARGETWORKLOAD TARGETSERVICE MINREPLICAS MAXREPLICAS AGE READY # myapp-http-scaler apps/v1/Deployment/myapp myapp:80 0 10 10s True # 查看 IngressRoute kubectl get ingressroute -n keda # 查看当前 Pod 数量 kubectl get pods -n myapp ``` ## 工作原理 1. **有流量时**: - 用户访问 `myapp.example.com` - Traefik 将流量路由到 KEDA HTTP 拦截器 - 拦截器检测到请求,通知 KEDA 启动 Pod - Pod 启动后(5-10秒),拦截器将流量转发到应用 - 用户看到正常响应(首次访问可能有延迟) 2. **无流量时**: - 5 分钟(scaledownPeriod)无请求后 - KEDA 自动将 Deployment 缩容到 0 - 不消耗任何计算资源 ## 常见问题排查 ### 1. 访问返回 404 **检查 IngressRoute 是否在 keda namespace:** ```bash kubectl get ingressroute -n keda | grep myapp ``` 如果不在,删除并重新创建: ```bash kubectl delete ingressroute myapp-ingress -n myapp # 删除错误的 kubectl apply -f myapp-keda-scaler.yaml # 重新创建 ``` ### 2. HTTPScaledObject READY = False **查看详细错误信息:** ```bash kubectl describe httpscaledobject myapp-http-scaler -n myapp ``` **常见错误:** - `workload already managed by ScaledObject`: 删除旧的 ScaledObject ```bash kubectl delete scaledobject myapp-scaler -n myapp ``` ### 3. Pod 没有自动缩容到 0 **检查是否有旧的 ScaledObject 阻止缩容:** ```bash kubectl get scaledobject -n myapp ``` 如果有,删除它: ```bash kubectl delete scaledobject -n myapp ``` ### 4. 查看 KEDA 拦截器日志 ```bash kubectl logs -n keda -l app.kubernetes.io/name=keda-add-ons-http-interceptor --tail=50 ``` ### 5. 测试拦截器是否工作 ```bash # 获取拦截器服务 IP kubectl get svc keda-add-ons-http-interceptor-proxy -n keda # 直接测试拦截器 curl -H "Host: myapp.example.com" http://:8080 ``` ## 调优建议 ### 调整缩容时间 根据你的应用特点调整 `scaledownPeriod`: - **频繁访问的应用**:设置较长时间(如 600 秒 = 10 分钟) - **偶尔访问的应用**:设置较短时间(如 180 秒 = 3 分钟) - **演示/测试环境**:可以设置很短(如 60 秒 = 1 分钟) ```yaml scaledownPeriod: 600 # 10 分钟 ``` ### 调整扩容阈值 根据应用负载调整 `targetValue`: ```yaml scalingMetric: requestRate: targetValue: 50 # 每秒 50 个请求时扩容(更敏感) ``` ### 调整最大副本数 ```yaml replicas: min: 0 max: 20 # 根据你的资源和需求调整 ``` ## 监控和观察 ### 实时监控 Pod 变化 ```bash watch -n 2 'kubectl get pods -n myapp' ``` ### 查看 HTTPScaledObject 事件 ```bash kubectl describe httpscaledobject myapp-http-scaler -n myapp ``` ### 查看 Deployment 副本数变化 ```bash kubectl get deployment myapp -n myapp -w ``` ## 完整示例:navigation 应用 参考 `navigation-complete.yaml` 文件,这是一个完整的工作示例。 ## 注意事项 1. **首次访问延迟**:Pod 从 0 启动需要 5-10 秒,用户首次访问会有延迟 2. **数据库连接**:确保应用能够快速重新建立数据库连接 3. **会话状态**:不要在 Pod 中存储会话状态,使用 Redis 等外部存储 4. **健康检查**:配置合理的 readinessProbe,确保 Pod 就绪后才接收流量 5. **资源限制**:设置合理的 resources limits,避免启动过慢 ## 参考资源 - KEDA 官方文档: https://keda.sh/ - KEDA HTTP Add-on: https://github.com/kedacore/http-add-on - Traefik IngressRoute: https://doc.traefik.io/traefik/routing/providers/kubernetes-crd/