Kubernetes 入口重写

Kubernetes ingress rewrite

我目前正在将一个 PHP 整体移植到 Kubernetes 中,我在 URL 重写 nginx-ingress 中遇到了一些问题。

系统使用 phroute,一切正常。问题是设置 nginx ingress 以发挥作用。

旧系统重写规则如下:

try_files $uri $uri/ @rewrite;

location @rewrite {
  rewrite ^/(.*)$ /index.php?_url=/;
}

location / {
  try_files $uri $uri/ =404;
}

location ~ \.php$ {
  try_files $uri =404;
  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  fastcgi_pass 1.2.3.4:9000;
  fastcgi_index index.php;
  include fastcgi_params;
  fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  fastcgi_param PATH_INFO $fastcgi_path_info;
}

location ~* \.(js|css|png|jpg|jpeg|gif|svg)$ {
  expires max;
  log_not_found off;
  rewrite "/[a-z0-9]{40}/([^.]+)\.(js|css|png|jpg|jpeg|gif|svg)$" /assets/.;
}

我已经为我的 nginx ingress 尝试了以下注释:

ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /index.php?_url=/
  hosts:
    - site.kube
  paths: [
    /(.*),
    /[a-z0-9]{40}/([^.]+)\.(js|css|png|jpg|jpeg|gif|svg)$
  ]

以下是我的问题:

请告诉我是否可以提供更多信息。谢谢。


编辑

为了回应评论中的问题,这里是一些版本输出。

Kubernetes(最新的 Minikube,在撰写本文时):

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.3", GitCommit:"b3cbbae08ec52a7fc73d334838e18d17e8512749", GitTreeState:"clean", BuildDate:"2019-11-14T04:24:29Z", GoVersion:"go1.12.13", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:09:08Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}

nginx-ingress (built in to minikube):

$ kubectl describe pod nginx-ingress-controller-6fc5bcc8c9-qnmz2 -n kube-system
{
    [ ... ]
    Image:         quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1,
    [ ... ]
}

我找到了解决方案!

原因是未处理根 server { ... }-块的 try_files。这与将请求从 nginx ingress 正确传播到我的部署中的 nginx pod 所需的以下行有关,此行需要作为入口注释:

nginx.ingress.kubernetes.io/rewrite-target: /

为了让它工作,我所做的就是以下内容:

  1. 在我的 nginx 配置映射中,我从 server { ... }-块中删除了 try_files

  2. location / { ... } 块中,我将 try_files 更改为:

    try_files $uri $uri/ =404;
    

    至:

    try_files $uri $uri/ @rewrite;
    

这解决了问题,因为 rewrite-target 使所有传入 nginx 的请求最终都在 location / { ... } 块中,从而绕过了服务器的 try_files.