Angular return 错误的 MIME 类型的 Kubernetes NGINX Ingress

Kubernetes NGINX Ingress with Angular return wrong MIME-Type

我使用 kubernetes ingress controller 将 Angular 应用程序部署到 kubernetes。一种是单节点集群设置,另一种是多节点集群设置。两种设置都会出现 MIME 类型问题,但单节点可以很快解决它,而在多节点上,延迟是不可接受的。

在多节点集群上,Time To First Byte 大约需要 5 秒用于:

在正常时间范围内有效的是:

我的集群设置如下:

Angular 应用程序中的 index.html 包含:

<base href="/">

多节点的入口:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: multi-node-ingress
  namespace: non-default-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: example.com
    http:
      paths:
        - path: /?(.*)
          backend:
            serviceName: ng-app-name
            servicePort: 80

在我的 DNS 提供商处,我向我的两个工作节点添加了 A 条目,以直接将所有流量转发给它们。第 4 层未进行负载均衡。

在 Open Shift 的 tutorial 的帮助下,我能够获得 .pcap 捕获,我可以在 wireshark 中对其进行分析。 Content-Typetext/html 用于调用例如http://example.com/favicon.svg,这会导致 404 Not Found。然而,大约 5 秒后(永远不会低于该阈值)它有时会得到解决。

我的容器 nginx-config 如下所示:

user  nginx;
worker_processes  auto;
...

events {
  worker_connections  1024;
}

http {
  include       /etc/nginx/mime.types;

  server {
    listen 80;

    location / {
      root /usr/share/nginx/html;
      try_files $uri $uri/ /index.html;
    }

    gzip on;
  }
}

我注意到,如果我删除 include /etc/nginx/mime.types; 行,页面加载将完全失败并出现 Wrong MIME-Type 错误。但如果它存在,则需要大约 5.02 到 5.15 秒(绝不会低于 5 秒)才能找到资源。

github 上有一个 issue,这可能与我的问题有关,但问题是根本没有加载任何内容(错误的 MIME 类型)。我确实加载了页面,只是速度太慢了。

上述 Github 问题的一个建议是添加自定义类型 module 我用 Config Map 做的:

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  http-snippet: |
    types {
      text/javascript .js;
      module .js;
    }
  default-type: application/octet-stream

类型已添加到入口控制器的 nginx.conf,但没有任何效果。
默认类型未被拾取,仍然是 text/html.

版本:

DNS 响应通常被缓存,因此如果您连续执行两个请求并且第二个请求仍然具有相同的 Time to first Byte,您可以消除 DNS 延迟。您可以通过 Wireshark 验证 DNS 延迟。

不同的命名空间几乎没有什么区别。

你没有说任何关于云提供商的细节,但我假设有负载平衡器(可能卸载 SSL 解密)平衡 2 个工作节点(入口侦听)之间的请求。您肯定可以启用某种日志记录。

您的 nginx ingress 也在保存访问日志,因此您可以检查它们 kubectl logs <nginx-ingress-pod> -n nginx-ingress - 您必须 运行 在每个工作节点(或每个节点 pods 位于)。在这些日志中,您会发现 nginx 从您的 Angular App pod 接收响应需要多长时间。

结合使用 Wireshark、负载平衡器日志、nginx 入口日志和 Angular 日志(也许您需要提高日志记录级别才能看到每个 HTTP 请求)您应该能够查明问题出在哪里.

问题是文件不是从同一个节点加载的,重试机制大约需要 5 秒。这可以通过添加 node-affinity 注释来解决,如下所示:

nginx.ingress.kubernetes.io/affinity-mode: "persistent"
nginx.ingress.kubernetes.io/affinity: "cookie"

有了这个注解,每个后续请求都会命中同一个节点。这对于高流量网站来说可能是个问题,但对我们来说效果很好。

有关更多详细信息,请参阅有关 node-affinity 的 nginx 文档。