无法通过/api访问本地K8s部署的Django API问题排查
问题分析与解决方案
问题场景
在Windows本地Kubernetes环境部署Django API后,通过http://localhost/api/my-api-endpoint访问时提示服务器未找到,但直接访问https://localhost/my-api-endpoint可正常连接。
原始配置文件
Service与Ingress配置
# START Service apiVersion: v1 kind: Service metadata: name: peopledb-api-service labels: app: peopledb-api-service spec: type: LoadBalancer ports: - port: 80 # Service对外暴露的端口 targetPort: 8000 # Pod中应用接收请求的端口 selector: name: peopledb-api-deployment # END SERVICE --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: django-api-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx rules: - host: localhost - http: paths: - path: /api pathType: Prefix backend: service: name: peopledb-api-service port: number: 80
Dockerfile配置
FROM python:3.9.7-slim ENV PYTHONUNBUFFERED=1 WORKDIR /api COPY requirements.txt /api/ RUN pip install -r requirements.txt COPY . /api/ EXPOSE 8000 CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
错误原因分析
- Ingress规则格式错误:原始Ingress的
rules部分写法有误,- host: localhost和- http:被拆分为两个独立规则条目,导致/api路径规则未绑定到localhost主机,请求无法匹配到对应Ingress规则。 - 路径重写逻辑不匹配:
rewrite-target: /会将/api/my-api-endpoint重写为/my-api-endpoint转发给Django,但当时Django的URL配置未包含api/前缀,无法匹配该路径,因此返回404。
解决方案
方案1:调整Ingress配置(无需修改Django代码)
通过正则匹配实现路径重写,同时修正规则绑定格式:
--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: django-api-ingress annotations: nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/rewrite-target: /$1 spec: ingressClassName: nginx rules: - host: localhost http: paths: - path: /api/(.*) pathType: Prefix backend: service: name: peopledb-api-service port: number: 80
该配置会将/api/my-api-endpoint重写为/my-api-endpoint转发给Django,适配原本无前缀的URL配置。
方案2:修改Django URL配置(配合已验证的Ingress)
如果不想调整Ingress重写规则,可在Django的URL配置中统一添加api/前缀:
- 更新前:
endoint_url = get_token
- 更新后:
endoint_url = 'api/get_token'
同时使用你已验证可行的Ingress配置:
--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: django-api-ingress annotations: nginx.ingress.kubernetes.io/use-regex: "true" spec: ingressClassName: nginx rules: - host: localhost http: paths: - path: /api/.* pathType: Prefix backend: service: name: peopledb-api-service port: number: 80
此配置会直接将/api/my-api-endpoint转发给Django,而Django URL已包含api/前缀,可正确匹配路径。
额外说明
- 无需自定义Nginx配置,通过Ingress官方注解即可实现路径匹配与重写需求。
- 若选择方案1,无需修改Django的
settings.py或URL配置;若选择方案2,建议在根URL配置中通过include统一指定前缀,避免逐个修改端点URL。
内容的提问来源于stack exchange,提问作者Ali Hamza
相关产品推荐
相关产品推荐

