在 AKS 后面使用 nginx-ingress 托管 django 应用

我正在尝试使用 Azure Kubernetes 服务在 nginx-ingress 后面托管 django 网站,并希望我的 django 网站在路径下显示。

例如,默认管理站点的访问应该是 http://example.com/django/admin,而不是 http://example.com/admin

我尝试了如下配置,当我访问 http://example.com/django/admin 时,它会将我重定向到 http://example.com/admin,并显示默认的 ingress 后端的 404 错误,因为我将 django debug 设置为 True,所以我认为这意味着 ingress 没有将我的请求发送到 django 服务

# path example
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: django-ingress
  labels:
    app: django
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: django-service
          servicePort: 80
        path: /django(/|$)(.*)

因此,我尝试使用 curl -I -k http://example.com/django/admin,并显示如下信息

HTTP/1.1 301 Moved Permanently
Server: openresty/1.15.8.2
Date: Wed, 06 Nov 2019 04:14:14 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Location: /admin/

相同的事情发生在站点的任何有效页面上,如果我使用 curl -I -k http://example.com/django/any_valid_page 它会显示如下所示:

HTTP/1.1 301 Moved Permanently
Server: openresty/1.15.8.2
Date: Wed, 06 Nov 2019 04:14:14 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: keep-alive
Location: /any_valid_page/

我想知道这是由于我使用默认的 django 开发 web 服务器进行测试引起的吗?(即 python manage.py runserver

如果我尝试像下面这样托管它在根目录下,一切都很好...

# root example
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: django-ingress
  labels:
    app: django
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: django-service
          servicePort: 80
        path: /
点赞
用户5525824
用户5525824

试着添加以下内容:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: django-ingress
  labels:
    app: django
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    ingress.kubernetes.io/rewrite-target: /django
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: django-service
          servicePort: 80
        path: /django
2019-11-06 04:42:37
用户11300382
用户11300382

从版本0.22.0开始,使用注释nginx.ingress.kubernetes.io/rewrite-target的入口定义与之前的版本不兼容。在0.22.0及以上版本中,需要传递到重写路径中的请求URI中的任何子字符串必须在捕获组中明确定义。因此,请确保您使用正确的版本。

当在集群外使用SSL卸载时,即使没有可用的TLS证书,强制重定向到HTTPS可能是有用的。这可以通过在特定资源中使用nginx.ingress.kubernetes.io/force-ssl-redirect:“true”注释来实现。

我认为您的Ingress配置文件应如下所示:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: django-ingress
  labels:
    app: django
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect:“false”
    nginx.ingress.kubernetes.io/force-ssl-redirect:“false”
    nginx.ingress.kubernetes.io/rewrite-target:/$2
规格:
  rules:
    - host:example.com
      http:
        paths:
          - path:/django(/|$)(.*)
            后端:
              serviceName:django-service
              servicePort:80

如果出现404错误,则有可能解决方案:

请将curl命令中的https更改为http:

curl--resolve your-host:80:xx.xxx.xx.xxxhttp://my-host:80

要从kubectl get ing命令获取IP,必须启用报告Ingress状态功能。看一下: reporting-ingress-状态

Ingress控制器中有默认服务器。对于未定义Ingress规则的域的所有请求,它都将返回带有404状态代码的“未找到”页面。这些请求未显示在访问日志中。

由于您收到了404,这意味着您请求的主机标头与Ingress资源中的主机字段不匹配。要在curl中设置主机标题,请参见上一个curl命令。另外,您还可以执行以下操作:

curl http://<ip> -H“host:example.com”

请参见[ngnix-ingress](https://kubernetes.github.io/ingress-nginx/examples/rewrite/), [server-side-https-enforcement-nginx](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#server-side-https-enforcement-through-redirect)。

2019-11-06 11:05:10
用户12330448
用户12330448

这是 Django 的一个问题。每当管理员未登录时,/django/admin 就会重定向到 /admin/。在这种情况下,如果你只是在浏览器 URL 栏中将 /django/admin/ 替换为 /django/admin/,它就能工作并打开 Django 管理员登录页面。

因此基本上 Django 内置的重定向与 Ingress 的重写模块发生了冲突。

2022-03-23 19:45:36