本文介绍关于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.conf 文件的其他Nginx原生参数,则仍会触发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=5Debug调试模式。
负载均衡算法
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的全局超时配置:
| 配置项 | 描述 | 取值类型 | 默认值 | 
| 
 | 设置与代理服务器建立连接的超时时间,单位为秒(s)。 | int | 
 建议不超过75 | 
| 
 | 设置从代理服务器读取响应的超时。该超时仅在两个连续的读取操作之间设置,而不是为整个响应的传输设置,单位为秒(s)。 | int | 
 | 
| 
 | 设置向代理服务器传输请求的超时。该超时只在两个连续的写操作之间设置,而不是为整个请求的传输设置,单位为秒(s)。 | int | 
 | 
| 
 | 限制允许将连接传递到下一个服务器的时间,设置为 | string | 
 | 
| 
 | 设置客户端或代理服务器连接上两个连续的读或写操作之间的超时时间。如果在这个时间内没有数据传输,连接就会关闭。 | string | 
 | 
| 
 | 设置一个超时时间,在这个时间内,与上游服务器的空闲连接将保持开放,单位为秒(s)。 | int | 
 | 
| 
 | 设置优雅停机的超时时间。 | string | 
 | 
| 
 | 设置接收代理协议头文件的超时值。默认的5秒可以防止TLS直通处理程序无限期地等待一个中断的连接。 | string | 
 | 
| 
 | 设置 SSL 会话缓存中的会话参数的有效时间。会话过期时间是相对于创建时间而言的。每个会话缓存会占用大约0.25MB的空间。 | string | 
 | 
| 
 | 定义读取客户端请求正文的超时,单位为秒(s)。 | int | 
 | 
| 
 | 定义读取客户端请求头的超时,单位为秒(s)。 | int | 
 | 
特定的资源自定义超时配置
以下是特定的资源自定义超时配置,以及相关的参数配置。
| 配置项 | 描述 | 
| 
 | 设置代理连接超时时间。 | 
| 
 | 设置代理发送超时时间。 | 
| nginx.ingress.kubernetes.io/proxy-read-timeout | 设置代理读取超时时间。 | 
| 
 | 配置重试策略或者重试条件,可以使用多个组合用空格分隔,例如设置为 
 | 
| 
 | 如果满足重试条件,则可用的重试次数。 | 
| 
 | 是否启用请求缓冲功能。 
 | 
通用全局配置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高级用法。