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 秒用于:
- 初次调用 example.com
- 运行时-es2015.js
- polyfills-es2015.js
- appConfig.json(自定义配置文件)
- favicon.ico
- 各种png/svg个文件
在正常时间范围内有效的是:
- 主要-es2015.js
- scripts.js
- styles.css
- ng-validate.js
我的集群设置如下:
- 2 个控制平面节点
- 2 个工作节点
- 带 canal 的集群网络
- 集群是使用 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: /
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-Type
是 text/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
.
版本:
- Kubernetes 1.18
- Angular 10
- nginx:1.19.3-alpine 用于在容器内托管 Angular 应用程序
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 文档。
我使用 kubernetes ingress controller 将 Angular 应用程序部署到 kubernetes。一种是单节点集群设置,另一种是多节点集群设置。两种设置都会出现 MIME 类型问题,但单节点可以很快解决它,而在多节点上,延迟是不可接受的。
在多节点集群上,Time To First Byte 大约需要 5 秒用于:
- 初次调用 example.com
- 运行时-es2015.js
- polyfills-es2015.js
- appConfig.json(自定义配置文件)
- favicon.ico
- 各种png/svg个文件
在正常时间范围内有效的是:
- 主要-es2015.js
- scripts.js
- styles.css
- ng-validate.js
我的集群设置如下:
- 2 个控制平面节点
- 2 个工作节点
- 带 canal 的集群网络
- 集群是使用 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: /
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-Type
是 text/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
.
版本:
- Kubernetes 1.18
- Angular 10
- nginx:1.19.3-alpine 用于在容器内托管 Angular 应用程序
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 文档。