一文详解Nginx-ingress控制器

举报
kaliarch 发表于 2022/06/11 12:13:49 2022/06/11
【摘要】 一 背景Kubernetes 引入了资源对象 Ingress,Ingress 为 Service 提供了可直接被集群外部访问的虚拟主机、负载均衡、SSL 代理、HTTP 路由等应用层转发功能。ingress-nginx为Kubernetes官方提供的基于nginx实现的ingress。nginx-ingress则为nginx官方提供的实现K8s ingress资源的方案。 二 高层次理解让...

一 背景

Kubernetes 引入了资源对象 Ingress,Ingress 为 Service 提供了可直接被集群外部访问的虚拟主机、负载均衡、SSL 代理、HTTP 路由等应用层转发功能。

ingress-nginx为Kubernetes官方提供的基于nginx实现的ingress。nginx-ingress则为nginx官方提供的实现K8s ingress资源的方案。

二 高层次理解

让我们从对入口控制器(IC)的高级检查开始。下图描述了IC如何向Internet上的客户端公开在Kubernetes集群中运行的两个web应用程序的示例:

图中展示如下信息:

  • 一个K8s集群
  • 集群用户管理、用户A和用户B,它们通过Kubernetes API使用集群。
  • 客户端A和客户端B,它们连接到相应用户部署的应用程序A和B。
  • IC,由Admin部署在名称空间nginx-ingress中的pod中,并通过ConfigMap nginx-ingress进行配置。为了简单起见,我们只描绘了一个IC吊舱;但是,Admin通常部署至少两个POD以实现冗余。IC使用Kubernetes API获取集群中创建的最新入口资源,然后根据这些资源配置NGINX。
  • 应用程序A由用户A在命名空间A中部署了两个吊舱。为了通过主机A.example.com向其客户机(客户机A)公开应用程序,用户A创建入口A。
  • 用户B在命名空间B中部署了一个pod的应用程序B。为了通过主机B.example.com向其客户机(客户机B)公开应用程序,用户B创建VirtualServer B。
  • 公共端点,它位于IC吊舱前面。这通常是一个TCP负载均衡器(云、软件或硬件),或者这种负载均衡器与NodePort服务的组合。客户端A和B通过公共端点连接到他们的应用程序。

黄色和紫色箭头表示与客户端通信量相关的连接,黑色箭头表示对Kubernetes API的访问。

为了简单起见,没有显示许多必要的Kubernetes资源,如部署和服务,管理员和用户也需要创建这些资源。

三 Ingress Controller Pod

IC POD由一个容器组成,该容器又包括以下内容:

  • IC进程,它根据Ingress和集群中创建的其他资源配置NGINX。
  • NGINX主进程,它控制NGINX辅助进程。
  • NGINX工作进程,它处理客户端通信量并对后端应用程序的通信量进行负载平衡。

下面是一个架构图,它显示了这些流程如何在一起交互,以及如何与一些外部流程/实体交互:

IC POD

下面的编号列表用花括号描述了每个连接的类型:

  1. (HTTP)Prometheus通过IC公开的HTTP端点获取IC和NGINX指标。默认值为:9113/metrics。注意:普罗米修斯不是IC所需要的,端点可以关闭。
  2. (HTTPS)IC读取Kubernetes API以获取集群中资源的最新版本,并写入API以更新已处理资源的状态并发出事件。
  3. (HTTP)Kubelet探测IC就绪探针(默认值为:8081/nginx-ready),以考虑IC吊舱就绪。
  4. (文件I/O)当IC启动时,它从文件系统中读取配置生成所需的配置模板。模板位于容器的/目录中,扩展名为。tmpl。
  5. (文件I/O)IC将日志写入容器运行时收集的stdout和stderr。
  6. (文件I/O)IC根据集群中创建的资源生成NGINX配置(有关资源列表,请参阅Ingress Controller is a Kubernetes Controller部分),并将其写入/etc/NGINX文件夹中的文件系统。配置文件的扩展名为.conf。
  7. (文件I/O)IC将TLS证书和密钥从入口和其他资源中引用的任何TLS机密写入文件系统。
  8. (HTTP)IC通过UNIX:/var/lib/NGINX/nginx-status.sock UNIX套接字获取NGINX指标,并将其转换为#1中使用的普罗米修斯格式。
  9. (HTTP)为考虑配置重新加载成功,IC确保至少有一个NGINX工作人员具有新配置。为此,IC通过UNIX:/var/lib/nginx/nginx-config-version.sock UNIX套接字检查特定端点。
  10. (N/A)为了启动NGINX,IC运行NGINX命令,该命令启动NGINX主机。
  11. (信号)为了重新加载NGINX,IC运行nginx-s reload命令,该命令验证配置并将重新加载信号发送给NGINX主机。
  12. (信号)为了关闭NGINX,IC执行nginx-s quit命令,该命令将优美的关闭信号发送给NGINX主机。
  13. (文件I/O)NGINX主服务器将日志发送到它的stdout和stderr,这两个日志由容器运行时收集。
  14. (文件I/O)NGINX主机在启动或重新加载时读取配置中引用的TLS证书和密钥。
  15. (文件I/O)NGINX主机在启动时或重新加载期间读取配置文件。
  16. (信号)NGINX主程序控制NGINX员工的生命周期,它使用新配置创建员工,并使用旧配置关闭员工。
  17. (文件I/O)NGINX工作人员将日志写入容器运行时收集的stdout和stderr。
  18. (UDP)NGINX工作人员通过UNIX套接字/var/lib/NGINX/nginx-syslog.sock通过Syslog协议将HTTP上游服务器响应延迟日志发送到IC。反过来,IC分析并将日志转换为普罗米修斯度量。
  19. (HTTP、HTTPS、TCP、UDP)客户端向端口80和443以及GlobalConfiguration资源公开的任何其他端口上的任何NGINX工作端口发送通信量,并从其接收通信量。
  20. (HTTP、HTTPS、TCP、UDP)NGINX工作器向后端发送通信量,并从后端接收通信量。
  21. (HTTP)管理员可以通过NGINX工作器使用端口8080连接到NGINX stub_status。注意:默认情况下,NGINX只允许来自本地主机的连接。

NGINX Plus的差异

  • 上面的图表描述了带有Nginx的IC。该IC还支持NGINX Plus,但有以下重要区别:

  • 为了配置NGINX Plus,除了重新加载配置外,IC还使用NGINX Plus API,该API允许IC动态更改上游服务器的上游服务器。

  • 不使用存根状态度量,而是使用扩展度量,这些度量可以通过NGINX Plus API获得。
    除了TLS证书和密钥之外,IC还从类型NGINX.org/jwk的秘密中写入JWK,NGINX工作人员读取它们。

四Ingress Controller进程

  • IC如何处理用户创建的新入口资源。
  • IC如何工作以及它如何与Kubernetes控制器相关的摘要。
  • IC工艺的不同组成部分。

4.1 处理一个新的Ingress Resource

下图描述了IC如何处理新的入口资源。为了简单起见,我们将NGINX主进程和辅助进程表示为一个矩形NGINX。另外,请注意,VirtualServer和VirtualServerRoute资源的处理类似。

处理一个新的入口资源涉及以下步骤,其中每个步骤对应于关系图上具有相同数字的箭头:

  • 用户创建新的入口资源。
  • IC进程具有集群中资源的缓存。缓存仅包括IC感兴趣的资源,如入口。缓存通过监视资源的更改与Kubernetes API保持同步。
  • 一旦缓存有了新的入口资源,它就会通知控制循环有关更改的资源。
  • 控制循环从缓存获取入口资源的最新版本。由于入口资源引用其他资源,例如TLS机密,因此控制循环也会获取任何引用资源的最新版本。
  • 控制循环从TLS机密生成TLS证书和密钥,并将它们写入文件系统。
  • 控制循环生成并写入与入口资源相对应的NGINX配置文件,并将其写入文件系统。
  • 控制循环重新加载NGINX并等待NGINX成功重新加载。作为重新加载的一部分:
  • NGINX读取TLS证书和密钥。
  • NGINX读取配置文件。
  • 控制循环为入口资源发出事件并更新其状态。如果重新加载失败,事件将包含错误消息。

4.2 Ingress Controller 是一个 Kubernetes 控制器

根据上一节的示例,我们可以概括IC的工作方式:
IC不断地处理集群中的新资源和对现有资源的更改。因此,NGINX配置与集群中的资源保持最新状态。
该IC是Kubernetes控制器的一个示例:该IC运行一个控制循环,确保NGINX根据所需的状态(入口和其他资源)进行配置。
所需的状态集中在以下内置的Kubernetes资源和自定义资源中:

  • 第7层负载平衡配置:
    • Ingresses
    • VirtualServers(CR)
    • VirtualSerlockes(CR)
  • Layer 7 policies:
    • Policies (CR)
  • Layer 4 load balancing configuration:
    • TransportServers (CR)
  • Service discovery:
    • Services
    • Endpoints
    • Pods
  • Secret configuration:
    • Secrets
  • Global Configuration:
    • ConfigMap (only one resource)
    • GlobalConfiguration (CR, only one resource)

IC可以监视其他自定义资源,这些资源不太常见,默认情况下不启用:

  • NGINX应用程序保护资源(APPolicies、APLogConfs、APUserSigs)
  • IngressLink资源(只有一个资源)

在下一节中,我们将研究IC工艺的不同组成部分。

五 Ingress Controller进程组件

5.1 资源缓存

在处理一个新的入口资源一节中,我们提到了IC在集群中有一个资源缓存,通过监视资源的更改,该缓存与Kubernetes API保持同步。我们还提到,一旦缓存被更新,它就会通知控制循环关于更改的资源。
缓存实际上是一个告密者的集合。下图显示了IC如何处理对资源的更改。

IC 进程组件

  • 对于IC监视的每一种资源类型,它都会创建一个告密者。告密者包括一个存储该类型的资源的存储区。为了使存储区与集群中资源的最新版本保持同步,告密者调用该资源类型的Watch and List Kubernetes API(参见关系图上的箭头1.Watch and List)。
  • 当集群中发生更改(例如,创建了一个新资源)时,告密者更新其存储并为该告密者调用处理程序(请参见箭头2.Invoke)。
  • IC为每个告密者注册处理程序。大多数情况下,处理程序在Workqueue中为受影响的资源创建一个条目,其中Workqueue元素包括资源的类型及其命名空间和名称。(见箭头3.放。)
  • 工作队列总是试图耗尽自己:如果前面有一个元素,队列将通过调用回调函数移除该元素并将其发送给控制器。(见箭头4.发送。)
  • 控制器是IC中的主要部件,代表控制回路。我们在控制循环部分解释组件。现在,只要知道要处理workqueue元素,Controller组件就可以从存储中获取最新版本的资源(请参见箭头5.Get),根据资源重新配置NGINX(请参见箭头6.Reconfigure),更新资源状态,并通过Kubernetes API发出事件(请参见箭头7.Update status and emit event)。

5.2 控制循环

5.2.1 控制器

  • 运行IC控制回路。
  • 实例化告密者、处理程序、工作队列和其他帮助器组件。
  • 包括sync方法(请参见下一节),Workqueue调用该方法来处理已更改的资源。
  • 将更改的资源传递给Configurator以重新配置Nginx。

5.2.2 配置器

  • 基于Kubernetes资源生成NGINX配置文件、TLS和证书密钥以及JWK。
  • 使用Manager写入生成的文件并重新加载Nginx。

5.2.3 管理器

  • 控制NGINX的生命周期(启动、重新加载、退出)。
  • 管理配置文件、TLS密钥和证书以及JWK。

下图显示了这三个组件是如何相互作用的:

控制器同步方法
Controller sync方法由Workqueue调用以处理资源的更改。该方法确定资源的类型,并调用适当的同步方法(例如,syncIngress for Ingress)。
我们不是展示所有不同的同步方法是如何工作的,而是关注最重要的一个–syncIngress方法–并查看它如何处理新的Ingress资源,如下图所示。

  • Workqueue调用sync方法,并向它传递一个Workqueue元素,其中包括已更改的资源种类和键(键是资源名称空间/名称,如“default/cafe-ingress”)。

  • 使用kind,sync方法调用适当的sync方法并传递资源键。对于入口,该方法是SyncIngress。

  • Syncingres使用密钥从入口存储中获取入口资源。存储由入口信息者控制,如资源缓存一节所述。注意:在代码中,我们使用包装存储的helper storeToIngressLister类型。

  • syncIngress调用配置的AddOrUpdateIngress,并传递入口。配置是一个组件,它表示负载平衡配置资源(Ingress、VirtualServers、VirtualServerRoutes、TransportServers)的有效集合,可以转换为NGINX配置(有关更多详细信息,请参见配置部分)。AddOrUpdateIngress返回ResourceChanges列表,该列表必须反映在NGINX配置中。通常,对于新的入口资源,配置只返回一个ResourceChange。

  • syncIngress调用processChanges,后者处理单个入口ResourceChange。
    processChanges创建一个扩展入口资源(IngressEx)以生成NGINX配置,该资源包括原始入口资源及其依赖项(如端点和机密)。为了简单起见,我们没有在图表上显示这一步。
    processChanges调用配置器的AddOrUpdateIngress并传递扩展的Ingress资源。

  • Configurator根据扩展入口资源生成NGINX配置文件,然后:
    调用Manager的CreateConfig()来更新入口资源的配置。
    调用Manager的Reload()来重新加载Nginx。
    重新加载状态从Manager传播到ProcessChanges。状态是成功或失败并带有错误消息。
    processChanges调用updateRegularIngressStatusAndEvent来更新入口资源的状态,并发出具有重新加载状态的事件。两者都涉及对Kubernetes API进行API调用。

参考链接

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200