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

Nginx Ingress Controller 工作原理

off999 2025-03-03 19:43 22 浏览 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设计模式 第 13 章 中介者模式(Mediator Pattern)

在行为型模式中,中介者模式是解决“多对象间网状耦合”问题的核心模式。它就像“机场调度中心”——多个航班(对象)无需直接沟通起飞、降落时间,只需通过调度中心(中介者)协调,避免航班间的冲突与混乱...

1.3.1 python交互式模式的特点和用法

什么是Python交互模式Python交互模式,也叫Python交互式编程,是一种在Python解释器中运行的模式,它允许用户在解释器窗口中输入单个Python语句,并立即查看结果,而不需要编写整个程...

Python设计模式 第 8 章 装饰器模式(Decorator Pattern)

在结构型模式中,装饰器模式是实现“动态功能扩展”的核心模式。它就像“手机壳与手机的关系”——手机(原始对象)具备通话、上网等基础功能,手机壳(装饰器)可在不改变手机本身的前提下,为其新增保护、...

python设计模式 综合应用与实战指南

经过前面16章的学习,我们已系统掌握创建型模式(单例、工厂、建造者、原型)、结构型模式(适配器、桥接、组合、装饰器、外观、享元、代理)、行为型模式(责任链、命令、迭代器、中介者、观察者、状态、策略...

Python入门学习教程:第 16 章 图形用户界面(GUI)编程

16.1什么是GUI编程?图形用户界面(GraphicalUserInterface,简称GUI)是指通过窗口、按钮、菜单、文本框等可视化元素与用户交互的界面。与命令行界面(CLI)相比,...

Python 中 必须掌握的 20 个核心:str()

str()是Python中用于将对象转换为字符串表示的核心函数,它在字符串处理、输出格式化和对象序列化中扮演着关键角色。本文将全面解析str()函数的用法和特性。1.str()函数的基本用法1.1...

Python偏函数实战:用functools.partial减少50%重复代码的技巧

你是不是经常遇到这样的场景:写代码时同一个函数调用了几十次,每次都要重复传递相同的参数?比如处理文件时总要用encoding='utf-8',调用API时固定传Content-Type...

第2节.变量和数据类型【第29课-输出总结】

同学们,关于输出的知识点讲解完成之后,把重点性的知识点做一个总结回顾。·首先对于输出这一章节讲解的比如有格式化符号,格式化符号这里需要同学们额外去多留意的是不是百分号s格式化输出字符串。当然课上也说百...

AI最火语言python之json操作_python json.loads()

JSON(JavaScriptObjectNotation,JavaScript对象表示法)是一种开放标准的文件格式和数据交换格式,它易于人阅读和编写。JSON是一种常用的数据格式,比如对接各种第...

python中必须掌握的20个核心函数—split()详解

split()是Python字符串对象的方法,用于将字符串按照指定的分隔符拆分成列表。它是文本处理中最常用的函数之一。一、split()的基本用法1.1基本语法str.split(sep=None,...

实用方法分享:pdf文件分割方法 横向A3分割成纵向A4

今天在街上打印店给儿子打印试卷时,我在想:能不能,把它分割成A4在家中打印,这样就不需要跑到街上的打印店打印卷子了。原来,老师发的作业,是电子稿,pdf文件,A3格式的试卷。可是家中的打印机只能打印A...

20道常考Python面试题大总结_20道常考python面试题大总结免费

20道常考Python面试题大总结关于Python的面试经验一般来说,面试官会根据求职者在简历中填写的技术及相关细节来出面试题。一位拿了大厂技术岗SpecialOffer的网友分享了他总结的面试经...

Kotlin Data Classes 快速上手_kotlin快速入门

引言在日常开发中,我们常常需要创建一些只用来保存数据的类。问题是,这样的类往往需要写一堆模板化的方法:equals()、hashCode()、toString()……每次都重复,既枯燥又容易出错。//...

python自动化RobotFramework中Collections字典关键字使用(五)

前言介绍安装好robotframework库后,跟之前文章介绍的BuiltIn库一样BuiltIn库使用介绍,在“python安装目录\Lib\site-packages\robot\librarie...

Python中numpy数据分析库知识点总结

Python中numpy数据分析库知识点总结二、对已读取数据的处理②指定一个值,并对该值双边进行修改③指定两个值,并对第一个值的左侧和第二个值的右侧进行修改2.4数组的拼接和行列交换①竖直拼接(np...

取消回复欢迎 发表评论: