百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

Nginx Ingress Controller 工作原理

off999 2025-03-03 19:43 18 浏览 0 评论



前言

本文目的是阐述 Nginx Ingress 控制器的工作原理,尤其是 NGINX模型 的构建方式以及为什么需要这个模型。

Nginx 配置

Nginx Ingress 控制器的目标是构建(nginx.conf)配置文件。主要含义是在配置文件中进行任何更改后都需要重新加载 Nginx。不过需要特别注意的是,在只有 upstream 配置变更的时候我们不需要重新加载 Nginx(即当你部署的应用 Endpoints 变更时)。我们使用 lua-nginx-module 实现这一目标。请查看下面的内容,以了解有关操作方法的更多信息。

Nginx 模型

通常,Kubernetes 控制器利用同步循环模式来检查控制器中所需的状态是否已更新或需要更改。为此,我们需要使用集群中放入不同对象来构建模型,特别是 Ingresses、Services、Endpoints、Secrets 以及 Configmaps 来生成反映集群状态时间点的配置文件。

为了从集群中获取该对象,我们使用了Kubernetes Informers,尤其是 FilteredSharedInformer。当一个新的对象添加、修改或者删除的时候,informers 允许通过 回调 针对单个变更进行响应。不幸的是,没有办法知道特定的更改是否会影响最终的配置文件。因此,每次更改时,我们都必须根据集群的状态从头开始重建一个新模型,并将其与当前模型进行比较。如果新模型等于当前模型,那么我们避免生成新的Nginx配置并触发重新加载。否则,我们就通过 Endpoints 来检查不同,然后使用 HTTP POST 请求一个新的 Endpoints 列表发送给运行在 Nginx 中的 Lua 程序并且避免重新生成一个新的 NGINX 配置以及触发重新加载。如果运行的模型和当前的差异不仅仅是 Endpoints,我们则基于新的模型创建一个新的 NGINX 配置文件,替代当前的模型并触发一次重新加载。

该模型的用途之一是在状态没有变化时避免不必要的重新加载,并检测定义中的冲突。

Nginx 配置的最终表示是从 Go template 生成的,使用新模型作为模板所需变量的输入。

构建 Nginx 模型

建立模型是一项昂贵的操作,因此,必须使用同步循环。通过使用工作队列,可以不丢失变更并通过 sync.Mutex 移除来强制执行一次同步循环,此外,还可以在同步循环的开始和结束之间创建一个时间窗口,从而允许我们丢弃不必要的更新。重要的是要理解,集群中的任何变更都会生成事件,然后 informer 会发送给控制器,这也是使用 工作队列 的原因之一。

建立模型的操作方式:

  • 按 CreationTimestamp 字段对 Ingress 规则排序,即先创建的规则优先。
  • 如果在多个 Ingress 中为同一主机定义了相同路径,则先创建的规则优先。
  • 如果多个 Ingress 包含同一 host 的 TLS 部分,则先创建的规则优先。
  • 如果多个 Ingress 定义了一个 annotation 影响到 Server 块配置,则先创建的规则优先。
  • 创建一个 NGINX Servers 列表(按主机名)。
  • 创建一个 NGINX Upstreams 列表。
  • 如果多个 Ingres Servers 定义了同一个 host 的不同路径,则 Ingress 控制器将合并这些规则。
  • Annotations 被应用于这个 Ingress 的所有路径。
  • 多个 Ingress 可以定义不同的 Annotations。这些定义在 Ingress 之间不共享。

重新加载

下面的列表描述了需要重新加载的情况:

  • 已创建新的 Ingress 资源。
  • TLS 部分已添加到现有 Ingress。
  • Ingress annotations 的更改不仅仅影响 upstream 配置。例如,load-balance annotation 不需要重新加载。
  • 已从 Ingress 添加/删除路径。
  • 一个 Ingress、Service、Secret 被移除。
  • 一些 Ingress 缺少可用的引用对象时,例如 Service 或 Secret。
  • Secret 已更新。

避免重新加载

在某些情况下,有可能避免重新加载,尤其是在 endpoints 发生变化(即,Pod 启动 或 被替换)时。完全删除重新加载超出了Ingress 控制器的范围。这将需要大量工作,并且在某些时候没有任何意义。仅当 Nginx 更改了读取新配置的方式时,这时才可以更改,基本上,新的更改不会替代工作进程。

避免 Endpoints 变更时重新加载

在每个 endpoint 更改上,控制器从所有能看到的服务上获取 endpoints 并生成相应的后端对象。然后,将这些对象发送到在 Nginx 内部运行的 Lua 处理程序。Lua 代码又将这些后端存储在共享内存区域中。然后,对于在 balancer_by_lua 上下文中运行的每个请求,Lua代码将检测它应从哪些 endpoints 中选择对应 upstream 并应用已经配置的负载均衡算法。然后 Nginx 负责其余的工作。这样,我们避免在 endpoints 更改时重新加载 Nginx。请注意,这也包括仅影响 Nginx upstream 配置的 annoations 变更。

在具有频繁部署应用程序的相对较大的群集中,此功能可以节省大量 Nginx 重载,否则会影响响应延迟,负载平衡质量(每次重载Nginx 都会重置负载平衡状态)等等。

避免因错误的配置而中断

因为 ingress nginx 使用同步循环模式工作,所以它将配置应用于所有匹配的对象。如果某些Ingress 对象的配置损坏,例如
nginx.ingress.kubernetes.io/configuration-snippet annotation 中的语法错误,则生成的配置将变得无效,不会重新加载,因此将不再考虑其他 Ingress。

为了防止这种情况的发生,nginx ingress 控制器可以选择公开一个验证的 准入Webhook服务器,以确保传入的ingress对象的可靠性。此 Webhook 将传入的 ingress 对象追加到 ingresses 列表中,生成配置并调用 nginx 以确保配置没有语法错误。

相关推荐

Python钩子函数实现事件驱动系统(created钩子函数)

钩子函数(HookFunction)是现代软件开发中一个重要的设计模式,它允许开发者在特定事件发生时自动执行预定义的代码。在Python生态系统中,钩子函数广泛应用于框架开发、插件系统、事件处理和中...

Python函数(python函数题库及答案)

定义和基本内容def函数名(传入参数):函数体return返回值注意:参数、返回值如果不需要,可以省略。函数必须先定义后使用。参数之间使用逗号进行分割,传入的时候,按照顺序传入...

Python技能:Pathlib面向对象操作路径,比os.path更现代!

在Python编程中,文件和目录的操作是日常中不可或缺的一部分。虽然,这么久以来,钢铁老豆也还是习惯性地使用os、shutil模块的函数式API,这两个模块虽然功能强大,但在某些情况下还是显得笨重,不...

使用Python实现智能物流系统优化与路径规划

阅读文章前辛苦您点下“关注”,方便讨论和分享,为了回馈您的支持,我将每日更新优质内容。在现代物流系统中,优化运输路径和提高配送效率是至关重要的。本文将介绍如何使用Python实现智能物流系统的优化与路...

Python if 语句的系统化学习路径(python里的if语句案例)

以下是针对Pythonif语句的系统化学习路径,从零基础到灵活应用分为4个阶段,包含具体练习项目和避坑指南:一、基础认知阶段(1-2天)目标:理解条件判断的逻辑本质核心语法结构if条件:...

[Python] FastAPI基础:Path路径参数用法解析与实例

查询query参数(上一篇)路径path参数(本篇)请求体body参数(下一篇)请求头header参数本篇项目目录结构:1.路径参数路径参数是URL地址的一部分,是必填的。路径参...

Python小案例55- os模块执行文件路径

在Python中,我们可以使用os模块来执行文件路径操作。os模块提供了许多函数,用于处理文件和目录路径。获取当前工作目录(CurrentWorkingDirectory,CWD):使用os....

python:os.path - 常用路径操作模块

应该是所有程序都需要用到的路径操作,不废话,直接开始以下是常用总结,当你想做路径相关时,首先应该想到的是这个模块,并知道这个模块有哪些主要功能,获取、分割、拼接、判断、获取文件属性。1、路径获取2、路...

原来如此:Python居然有6种模块路径搜索方式

点赞、收藏、加关注,下次找我不迷路当我们使用import语句导入模块时,Python是怎么找到这些模块的呢?今天我就带大家深入了解Python的6种模块路径搜索方式。一、Python模块...

每天10分钟,python进阶(25)(python进阶视频)

首先明确学习目标,今天的目标是继续python中实例开发项目--飞机大战今天任务进行面向对象版的飞机大战开发--游戏代码整编目标:完善整串代码,提供完整游戏代码历时25天,首先要看成品,坚持才有收获i...

python 打地鼠小游戏(打地鼠python程序设计说明)

给大家分享一段AI自动生成的代码(在这个游戏中,玩家需要在有限时间内打中尽可能多的出现在地图上的地鼠),由于我现在用的这个电脑没有安装sublime或pycharm等工具,所以还没有测试,有兴趣的朋友...

python线程之十:线程 threading 最终总结

小伙伴们,到今天threading模块彻底讲完。现在全面总结threading模块1、threading模块有自己的方法详细点击【threading模块的方法】threading模块:较低级...

Python信号处理实战:使用signal模块响应系统事件

信号是操作系统用来通知进程发生了某个事件的一种异步通信方式。在Python中,标准库的signal模块提供了处理这些系统信号的机制。信号通常由外部事件触发,例如用户按下Ctrl+C、子进程终止或系统资...

Python多线程:让程序 “多线作战” 的秘密武器

一、什么是多线程?在日常生活中,我们可以一边听音乐一边浏览新闻,这就是“多任务处理”。在Python编程里,多线程同样允许程序同时执行多个任务,从而提升程序的执行效率和响应速度。不过,Python...

用python写游戏之200行代码写个数字华容道

今天来分析一个益智游戏,数字华容道。当初对这个游戏颇有印象还是在最强大脑节目上面,何猷君以几十秒就完成了这个游戏。前几天写2048的时候,又想起了这个游戏,想着来研究一下。游戏玩法用尽量少的步数,尽量...

取消回复欢迎 发表评论: