一、从逻辑上理解Ingress和Ingress控制器

在传统的业务系统中,应用微服务化后,需要一个统一的入口来将各个服务进行整合,这个入口可以是Nginx、Apache、HAproxy等等。而在K8s中,同样需要一个工具来将应用的各个service整合到统一的入口,这个工具就叫Ingress控制器,Ingress的中文翻译即为“入口”。


ingress controller 禁止cors ingress controller 原理_nginx

传统业务与k8s业务简化对比图

实现Ingress控制器的方式同样有多种,有基于Apache实现的,有基于Haproxy实现的,有Kubernetes社区基于Nginx实现的(kubernetes/ingress-nginx),也有Nginx公司基于Nginx实现的(nginxinc/kubernetes-ingress),后文所讲的Nginx Ingress Controller均指Nginx公司开发的Ingress Contrloller。

在传统的业务系统中,我们通过编辑配置文件如nginx.conf来控制Nginx服务器的行为,而在k8s中,Ingress控制器以pod形式运行(如上图所示,Nginx Ingress Controller pod由单一容器构成,容器中运行有Ingress Controller和Nginx两个程序),通常我们是不应该直接编辑容器中的文件的,所以k8s提供了一个叫做Ingress的资源,通过配置该资源,即可控制Ingress控制器的行为。下图左侧为nginx.conf配置,右侧为ingress配置,可以做一下简单对比。


ingress controller 禁止cors ingress controller 原理_Ingress控制器_02

nginx.conf与Ingress对比

二、Nginx Ingress Controller工作流程

上文中我们提到,Nginx Ingress Controller容器中运行主要了Ingress Controller(下面简称IC)和Nginx两个程序,官方文档中非常详细地介绍了其工作原理:How NGINX Ingress Controller Works。下面截取了其中一张图: 

ingress controller 禁止cors ingress controller 原理_ingress_03

1、IC会为每种其感兴趣的资源类型(如Ingress、VirtualServer、VirtualServerRoute及其关联资源)创建一个Informer,每个Informer包括一个存储该类型资源的store。Informer会通过Kubernetes API监视其对应资源类型的变化情况,来使store中内容保持最新。

2、IC会为每个Informer注册一个处理程序Handler。当用户创建或者更新了资源时(如创建了一个Ingress资源),Informer会更新其store并调用其它对应的Handler。

3、Handler会在工作队列Workqueue中为发生改变的资源创建一个条目,工作队列的元素包括资源的类型及其命名空间和名称,如(Ingress,default,cafe)。

4、Workqueue总是会试图清空队列中的元素,如果队列前面有一个元素,Workqueue将移除该元素并通过调用回调函数将其发送给控制器Controller。

5、Controller是IC中的主要组件,代表控制回路。Controller在接收到Workqueue发送的信息后(即变更的资源),将从store中获取相关资源的最新版本。

6、Controller根据获取的资源,生成相应的nginx配置文件,写入容器的文件系统,然后reload nginx,并通过Kubernetes API将reload结果更新到资源的status和event。 

三、标准部署方案

在使用Helm进行部署时,Nginx Ingress Controller支持使用Deployment或者DaemonSet方式部署,支持使用hostNetwork方式或者service方式暴露Ingress Controller Pod。如果在云上使用时,最标准的部署方式就是通过LoadBalancer类型的service暴露Ingress Controller Pod。

而如果在自有的k8s环境中,则可以使用hostNetwork方式或者NodePort类型的服务暴露Ingress Controller Pod,然后k8s集群外部配置一个四层的负载均衡器(如用nginx+keepalived)作为应用的入口。

使用hostNetwork暴露时,部署逻辑可为如下之一:

ingress controller 禁止cors ingress controller 原理_k8s_04

使用NodePort service和外部负载均衡器暴露时,部署逻辑如下,在自有环境下,推荐使用:

ingress controller 禁止cors ingress controller 原理_Nginx_05

 四、配置方法

文档的配置部分我做了简单翻译,需要的可以看一下:

Nginx Ingress Controller 中文文档