配置GCE Ingress时HTTPS后端(Django)健康检查失败求助
解决GCE Ingress中Django应用HTTPS健康检查失败的问题
我之前也碰到过一模一样的坑!核心问题有两个:一是GCE Ingress的健康检查默认不会自动适配HTTPS后端的配置,二是手动修改GCE控制台的健康检查会被Kubernetes覆盖,再加上Django全局强制HTTPS的逻辑,会把健康检查请求(哪怕是HTTPS请求)触发301重定向,直接导致健康检查判定为失败。下面给你一步步解决的方案:
第一步:用BackendConfig定义HTTPS健康检查(关键!)
GCE Ingress需要通过BackendConfig这个K8s资源来配置健康检查细节,手动改GCE控制台的配置完全没用——Kubernetes会定期同步配置并覆盖你的修改。先创建这个配置文件:
apiVersion: cloud.google.com/v1 kind: BackendConfig metadata: name: app-backend-config spec: healthCheck: checkIntervalSec: 10 timeoutSec: 5 healthyThreshold: 2 unhealthyThreshold: 3 type: HTTPS port: 12345 # 这里要和你Service里的port字段一致,不是容器的targetPort! requestPath: "/healthz" # 必须用一个Django不强制HTTPS的专属路径
第二步:给Django加一个无HTTPS强制的健康检查接口
因为你的Django全局开启了HTTPS强制,哪怕GCE用HTTPS发送健康检查请求,如果用根路径还是可能触发重定向逻辑(比如HSTS规则),所以最好单独加一个跳过HTTPS强制的健康检查视图:
在Django的views文件中添加:
from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_GET @csrf_exempt @require_GET def health_check(request): # 不要添加任何会触发HTTPS重定向的装饰器 return HttpResponse("OK", status=200)
然后在urls.py中注册路由:
path('healthz/', health_check, name='health_check'),
第三步:修正你的Service配置
你的Service里有个明显的冲突:同时声明了type: NodePort和type: LoadBalancer,必须删掉type: LoadBalancer(Ingress只需要NodePort类型的服务),还要加上注解关联刚才创建的BackendConfig:
apiVersion: v1 kind: Service metadata: name: app annotations: service.alpha.kubernetes.io/app-protocols: '{"app-https":"HTTPS"}' # 关联BackendConfig,让K8s自动同步健康检查配置到GCE cloud.google.com/backend-config: '{"default": "app-backend-config"}' labels: component: app role: web spec: type: NodePort ports: - port: 12345 targetPort: 8000 protocol: TCP name: app-https selector: component: app role: web
第四步:调整Ingress配置(可选但推荐)
给Ingress添加注解强制所有HTTP请求重定向到HTTPS,同时确认后端配置关联正确:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress annotations: kubernetes.io/tls-acme: "true" kubernetes.io/ingress.global-static-ip-name: web-static-ip # 强制HTTP请求重定向到HTTPS nginx.ingress.kubernetes.io/ssl-redirect: "true" # 关联BackendConfig(部分GCE Ingress版本需要这个配置,加上更稳妥) cloud.google.com/backend-config: '{"default": "app-backend-config"}' spec: tls: - hosts: - foo.domain.it secretName: production-tls backend: serviceName: app servicePort: app-https
最后一步:应用配置并验证
按顺序执行以下命令:
kubectl apply -f backend-config.yaml kubectl apply -f service.yaml kubectl apply -f ingress.yaml
等待5-10分钟让GCE同步配置,然后进行验证:
- 查看Django应用日志,应该能看到
/healthz的HTTPS请求,且返回状态码为200 - 用
gcloud compute health-checks list找到对应健康检查,再用gcloud compute health-checks describe [健康检查名称]确认配置为HTTPS类型且请求路径是/healthz - 查看Ingress状态:
kubectl get ingress,等待ADDRESS字段出现且状态正常
避坑提醒
- 绝对不要手动修改GCE控制台的健康检查,Kubernetes会自动覆盖你的修改
- 健康检查路径必须跳过Django的HTTPS强制逻辑,GCE会把301重定向判定为不健康状态
- BackendConfig中的
port必须对应Service的port字段,而非容器的targetPort,因为健康检查请求是发送到Service端口上的
内容的提问来源于stack exchange,提问作者Girbons
相关产品推荐
相关产品推荐

