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