【问题标题】:Kubernetes NGINX Ingress with Angular return wrong MIME-Type带有 Angular 的 Kubernetes NGINX 入口返回错误的 MIME 类型
【发布时间】:2021-01-25 21:23:09
【问题描述】:

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

在多节点集群上,第一个字节的时间大约需要 5 秒:

  • 对 example.com 的初始调用
  • runtime-es2015.js
  • polyfills-es2015.js
  • appConfig.json(自定义配置文件)
  • favicon.ico
  • 各种 png/svg 文件

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

  • main-es2015.js
  • scripts.js
  • styles.css
  • ng-validate.js

我的集群设置如下:

  • 2 个控制平面节点
  • 2 个工作节点
  • 与运河的集群网络
  • 集群是使用 RKE 设置的(如果重要的话)

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: /$1
    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 中,但没有效果。
default-type 没有被拾取,仍然是text/html

版本:

  • Kubernetes 1.18
  • 角 10
  • nginx:1.19.3-alpine 用于在容器内托管 Angular 应用程序

【问题讨论】:

    标签: angular nginx kubernetes nginx-ingress


    【解决方案1】:

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

    不同的命名空间几乎没有任何区别。

    您没有透露有关云提供商的任何详细信息,但我假设在 2 个工作节点(入口侦听的位置)之间存在负载平衡器(可能卸载 SSL 解密)平衡请求。您可以确保启用某种日志记录。

    您的 nginx 入口也保留访问日志,因此您可以检查它们kubectl logs &lt;nginx-ingress-pod&gt; -n nginx-ingress - 您必须在每个工作节点(或入口 pod 所在的每个节点)上运行它。在这些日志中,您会发现 nginx 从您的 Angular App pod 接收响应需要多长时间。

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

    【讨论】:

    • 感谢您的提示。关于云提供商,我们将其托管在位于瑞士的 Exoscale 上。没有任何网络负载平衡 atm。
    • 更好。我忘了提到你也可以使用sudo tcpdump -i eth0 port 80 -w capture.pcap 之类的东西直接在worker 上捕获数据包,并在Wireshark 中分析pcap 文件。当谈到 nginx 入口时,我犯了错误,访问日志可以在 nginx-ingress-controller pods 上找到 - 默认日志格式日志 upstream_response_time(== 角度 pod 响应所需的时间)作为后面的第 3 列。 kubectl logs -f -n &lt;namespace&gt; ingress-nginx-controller-&lt;unique-pod-id&gt;
    【解决方案2】:

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

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

    使用此注释,每个后续请求都将到达同一个节点。这对于高流量网站可能是个问题,但对我们来说这很好。

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

    【讨论】:

      猜你喜欢
      • 2020-01-20
      • 2020-11-27
      • 2021-02-17
      • 2016-08-18
      • 2018-09-03
      • 2018-12-16
      • 2018-01-03
      • 2020-12-05
      • 1970-01-01
      相关资源
      最近更新 更多