本文介绍关于Nginx基础知识点,Nginx Ingress Controller实现原理,以及相关运维能力。
Nginx基础知识点
Nginx Ingress Controller
实现原理
Nginx Ingress Controller是一个集控制平面和数据平面于一体的实现方案。每个Pod下有一个Controller进程,同时也包含Nginx相关进程。
Nginx Ingress数据面相关核心模块
第三方模块:
ACK Nginx Ingress集成了该模块,可以实现同ARMS Trace服务的集成。了解更多详情,请参见实现Nginx Ingress Controller组件的链路追踪。
Nginx Ingress可以通过Configmap配置开启该模块。
data: enable-opentelemetry: "true" otlp-collector-host: "otel-coll-collector.otel.svc" ## open telemetry 地址
了解更多模块详情,请参见Nginx官方文档。
配置同步原理
了解配置同步的工作原理之后,我们便能够掌握如何减少配置Reload的频率,以及在何种情况下需要执行配置Reload。
Nginx Ingress Controller通过Watch Ingress、Service、Pod、Endpoint相关资源,将配置更新到nginx.conf
或者lua table
下。Lua部分主要包含了Upstream端点、灰度发布和证书部分,对应Nginx本身其他的相关变量参数,若修改了还是会导致nginx.conf
发生变更,触发Reload。详细信息,请参见Nginx ingress社区文档部分《When a reload is required》。
Nginx Ingress控制面配置
启动参数说明
了解更多启动参数详情,请参见Ingress控制器命令行参数。
查看Nginx Ingress对应的Deployment或者Pod Spec可以看到Nginx-ingress对应的Container的启动参数,大致如下:
containers:
- args:
- /nginx-ingress-controller
- --election-id=ingress-controller-leader-nginx
- --ingress-class=nginx
- --watch-ingress-without-class
- --controller-class=k8s.io/ingress-nginx
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --annotations-prefix=nginx.ingress.kubernetes.io
- --publish-service=$(POD_NAMESPACE)/nginx-ingress-lb
- --enable-annotation-validation
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
- --v=2
其中-v
指定日志级别:
--v=2
使用Diff显示有关Nginx中配置更改的详细信息。--v=3
显示有关服务、入口规则、端点更改的详细信息,并以JSON格式转储Nginx配置。--v=5
Debug调试模式。
负载均衡算法
Ingress Nginx允许设置全局默认的负载均衡算法,主要提供了Round_robin和Ewma两种选项,默认使用Round_robin。Round_robin算法循环遍历后端工作负载,使请求均匀分配,但如果后端性能差异较大,可能会出现负载不均衡。相反,Ewma算法可以将请求发送到加权平均负载最低的工作负载上,加权负载指数会随着请求的到来而逐渐变化,使得负载均衡更加均衡。
要使用IP或其他变量的一致哈希进行负载平衡,请考虑使用nginx.ingress.kubernetes.io/upstream-hash-by
注释。要使用会话Cookie进行负载平衡,请考虑使用nginx.ingress.kubernetes.io/affinity
注释。
相关实现:
相关超时配置
全局超时配置
可通过以下配置项进行Ingress Nginx的全局超时配置:
配置项 | 描述 | 默认值 |
| 设置与代理服务器建立连接的超时时间。 | 默认5s,但通常不能超过75s。 |
| 设置从代理服务器读取响应的超时。该超时仅在两个连续的读取操作之间设置,而不是为整个响应的传输设置。 | 60s |
| 设置向代理服务器传输请求的超时。该超时只在两个连续的写操作之间设置,而不是为整个请求的传输设置。 | 60s |
| 限制允许将连接传递到下一个服务器的时间。 | 默认为 600s,设置为0值则关闭此限制。 |
| 设置客户端或代理服务器连接上两个连续的读或写操作之间的超时。如果在这个时间内没有传输数据,连接就会关闭 | 600s |
| 设置一个超时时间,在这个时间内,与上游服务器的空闲连接将保持开放。 | 60s |
| 设置优雅停机的超时时间。 | 240s |
| 设置接收代理协议头文件的超时值。默认的5秒可以防止TLS直通处理程序无限期地等待一个中断的连接。 | 5s |
| 设置 SSL 会话缓存中的会话参数的有效时间。会话过期时间是相对于创建时间而言的。每个会话缓存会占用大约0.25MB的空间。 | 10m |
| 定义读取客户端请求正文的超时。 | 60s |
| 定义读取客户端请求头的超时。 | 60s |
特定的资源自定义超时配置
以下是特定的资源自定义超时配置,以及相关的参数配置。
配置项 | 描述 |
| 设置代理连接超时时间。 |
| 设置代理发送超时时间。 |
| 设置代理读取超时时间。 |
| 配置重试策略或者重试条件,可以使用多个组合用空格分隔,例如设置为
|
| 如果满足重试条件,则可用的重试次数。 |
| 是否启用请求缓冲功能。
|
通用全局配置ConfigMap
了解更多详情信息,请参见Nginx-configuration_configmap。
其他Annotation
了解更多详情信息,请参见Nginx-configuration_annotations。
自定义配置snippet
nginx.ingress.kubernetes.io/configuration-snippet
:对应配置会生效到Location块下。nginx.ingress.kubernetes.io/server-snippet
:对应配置会生效到Server块下。nginx.ingress.kubernetes.io/stream-snippet
:对应配置会生效到Stream块下。
Nginx Ingress数据面配置
Nginx Ingress的数据平面是通过结合Nginx和ngx_lua
模块(即OpenResty)来实现的。Nginx采用多模块化设计,把HTTP请求处理切分成多个阶段,允许多个模块协同工作,其中每个模块负责处理一个独立且简单的功能。使得处理更高效、更可靠,并提高了系统的可扩展性。
OpenResty依托NGINX的处理阶段,在Rewrite/Access阶段、Content阶段和Log阶段注入了自定义的Handler。加上系统启动的初始阶段,即Master阶段,总计OpenResty提供了11个阶段,这些阶段赋予了 Lua脚本在HTTP请求处理过程中介入的能力。接下来是OpenResty主要可用阶段的图示描述:
HTTP块
http {
lua_package_path "/etc/nginx/lua/?.lua;;";
lua_shared_dict balancer_ewma 10M;
lua_shared_dict balancer_ewma_last_touched_at 10M;
lua_shared_dict balancer_ewma_locks 1M;
lua_shared_dict certificate_data 20M;
lua_shared_dict certificate_servers 5M;
lua_shared_dict configuration_data 20M;
lua_shared_dict global_throttle_cache 10M;
lua_shared_dict ocsp_response_cache 5M;
...
}
init_by_lua_block
初始化加载了Lua相关模块:
configuration
balancer
monitor
certificate
plugins
init_worker_by_lua_block
init_worker_by_lua_block {
lua_ingress.init_worker()
balancer.init_worker()
monitor.init_worker(10000)
plugins.run()
}
upstream和balancer_by_lua_block
upstream upstream_balancer {
### Attention!!!
#
# We no longer create "upstream" section for every backend.
# Backends are handled dynamically using Lua. If you would like to debug
# and see what backends ingress-nginx has in its memory you can
# install our kubectl plugin https://kubernetes.github.io/ingress-nginx/kubectl-plugin.
# Once you have the plugin you can use "kubectl ingress-nginx backends" command to
# inspect current backends.
#
###
server 0.0.0.1; # placeholder
balancer_by_lua_block {
balancer.balance()
}
keepalive 8000;
keepalive_time 1h;
keepalive_timeout 60s;
keepalive_requests 10000;
}
Stream块
日志相关
access_log off;
error_log /var/log/nginx/error.log notice;
关闭了
access_log
。错误日志级别设置为了
notice
, 还可以设置为debug
(debug_core
、debug_alloc
、debug_event
、debug_http
、...) 、info
、warn
、error
、crit
、alert
、emerg
等值,级别越高记录的信息越少。
执行以下命令,可以通过查看Nginx Ingress Pod日志是否有相关报错信息。
kubectl logs -f <nginx-ingress-pod-name> -n kube-system |grep -E '^[WE]'
相关文档
关于Nginx Ingress的配置,请参见社区文档。
关于Nginx Ingress排查方法,请参见常见检查方法。
关于Nginx Ingress高级用法,请参见Nginx Ingress高级用法。