Kubernetes ingress SPA应用程序(Vue、React、Angular)在Kubernetes上的Nginx入口控制器后工作不正常

Kubernetes ingress SPA应用程序(Vue、React、Angular)在Kubernetes上的Nginx入口控制器后工作不正常,kubernetes-ingress,nginx-location,nginx-config,nginx-ingress,azure-aks,Kubernetes Ingress,Nginx Location,Nginx Config,Nginx Ingress,Azure Aks,我们正在将AKS(Azure Kubernetes服务)用于托管Kubernetes群集,在很大程度上,我们对该平台带来的好处感到高兴,但我们也面临一些问题 在AKS上,如果您托管LoadBalancer类型的服务,它会自动创建新的动态IP地址(Azure资源)并将其分配给该服务。如果您想要白名单,这不是非常理想,而且根本没有意义,因此我们切换到Nginx入口控制器(没有特别的理由选择Nginx)。我们有很多应用程序—API、SPA、一个用于整个集群的入口控制器以及每个环境的独立集群—QA/St

我们正在将AKS(Azure Kubernetes服务)用于托管Kubernetes群集,在很大程度上,我们对该平台带来的好处感到高兴,但我们也面临一些问题

在AKS上,如果您托管LoadBalancer类型的服务,它会自动创建新的动态IP地址(Azure资源)并将其分配给该服务。如果您想要白名单,这不是非常理想,而且根本没有意义,因此我们切换到Nginx入口控制器(没有特别的理由选择Nginx)。我们有很多应用程序—API、SPA、一个用于整个集群的入口控制器以及每个环境的独立集群—QA/Sta/Prod等。。因此,我们需要以某种方式管理路由,入口路径参数就是我们要做的。例如:

其中学生课程是入口路径,然后您可以添加/api/student,例如访问特定的api。结果将是,这不是完美的,但现在做的工作

入口是这样的:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: students-api-ingress
  namespace: university
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - host: https://region.azurecloud.com
      http:
        paths:
          - backend:
              serviceName: students-api-service
              servicePort: 8001
            path: /students(/|$)(.*)
# build environment
FROM node:12.2.0-alpine as build
WORKDIR /app
COPY package*.json /app/
RUN npm install --silent
COPY . /app
RUN npm run build

# production environment
FROM nginx:1.16.0-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
但是,这在SPA应用程序(如React、Vue或Angular)中效果不佳。不管技术如何,我们都面临同样的问题。它们位于docker中Nginx的后面,因此Dockerfile的外观如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: students-api-ingress
  namespace: university
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - host: https://region.azurecloud.com
      http:
        paths:
          - backend:
              serviceName: students-api-service
              servicePort: 8001
            path: /students(/|$)(.*)
# build environment
FROM node:12.2.0-alpine as build
WORKDIR /app
COPY package*.json /app/
RUN npm install --silent
COPY . /app
RUN npm run build

# production environment
FROM nginx:1.16.0-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
这是nginx.conf文件:

server {
  listen 80;

  location / {
    root /usr/share/nginx/html;
    try_files $uri $uri/ /index.html =404;
    index  index.html index.htm;

  error_page 500 502 503 504  /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }

    if ($request_method = 'OPTIONS') {
          add_header 'Access-Control-Allow-Origin: $http_origin');
          add_header 'Access-Control-Allow-Origin: GET, POST, DELETE, PUT, PATCH, OPTIONS');
          add_header 'Access-Control-Allow-Credentials: true');
          add_header 'Vary: Origin');

      }

       add_header 'Access-Control-Allow-Origin' "$http_origin" always;
       add_header 'Access-Control-Allow-Credentials' 'true' always;
       add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE, OPTIONS' always;
       add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
  }

  include /etc/nginx/extra-conf.d/*.conf;
}
当应用程序访问.js文件或图像等资产时,就会出现问题。它以ingres.host/asset.name格式创建url,例如,而不是包括入口路径 结果是所有资产都出现404 not found错误

如果入口路径仅设置为/而没有任何重写注释,则应用程序可以正常工作,但这是一个问题,因为不能有多个应用程序使用基本入口主机。一种解决方案是为每个SPA应用程序使用一个单独的入口控制器,但这让我们回到了负载平衡器的初始问题—每个SPA应用程序都有单独的负载平衡器和IP地址,这正是我们希望避免的

我想我不是唯一一个在Kubernetes上的nginx ingress controller后面托管SPA应用程序的人,但我设法找到的所有类似主题几乎都没有结果,没有明确的解决方案应该做什么,或者建议对我们不起作用。我想知道问题是从哪里来的-nginxweb服务器还是入口控制器,入口控制器通常是管理Kubernetes上应用程序路由的方式吗。如果您能在这方面提供帮助或建议,我将不胜感激

谢谢,,
R

我通常处理SPA的方法是为每个SPA使用不同的主机名。例如,在一个非生产集群中,有两个名为
学生门户
教师门户
的SPA,我将为
学生门户.mydomain.com
教师门户.mydomain.com
创建DNS记录,指向集群负载平衡器的公共IP

将域名包括在入口资源的规则中


我发现这是最有效的方法,避免了需要单独处理每个SPA框架。

感谢您的建议。看起来这样确实更容易。