最近发现好多人问Ingress,同时一直也没去用Nginx的Ingress,索性捣鼓一把,发现跟原来确实有了点变化,在这里写篇文章记录一下

一、Ingress介绍

Kubernetes暴露服务的方式目前只有三种:LoadBalancer Service、NodePort Service、Ingress;前两种估计都应该很熟悉,具体的可以参考下 这篇文章;下面想写介绍一下这个Ingress。

1.1 Ingress是个什么玩意

可能从大致印象上Ingress就是能利用Nginx、Haproxy啥的负载均衡器暴露集群内服务的工具;那么问题来了,集群内服务想要暴露出去面临着几个问题:

1.2、Pod漂移问题

众所周知Kubernetes具有强大的副本控制能力,能保证在任意副本(Pod)挂掉时自动从其他机器启动一个新的,还可以动态扩容等,总之一句话,这个Pod可能在任何时刻出现在任何节点上,也可能在任何时刻死在任何节点上;那么自然随着Pod的创建和销毁,Pod IP肯定会动态变化;那么如何把这个动态的Pod IP暴露出去?这里借助于Kubernetes的Service机制,Service可以以标签的形式选定一组带有指定标签的Pod,并监控和自动负载他们的Pod IP,那么我们向外暴露只暴露Service IP就行了;这就是NodePort模式:即在每个节点上开启一个端口,然后转发到内部Pod IP上,如下图所示:

Kubernetes Nginx Ingress教程

1.3、端口管理问题

采用NodePort方式暴露服务面临着一个坑爹的问题是,服务一旦多起来,NodePort在每个节点上开启的端口会及其庞大,而且难以维护;这时候引出的思考问题是"能不能使用Nginx啥的只监听一个端口,比如80,然后按照域名向后转发?"这思路很好,简单的实现就是使用DaemonSet在每个node上监听80,然后写好规则,因为Nginx外面绑定了宿主机80端口(就像NodePort),本身又在集群内,那么向后直接转发到相应Service IP就行了,如下图所示:

Kubernetes Nginx Ingress教程

1.4、域名分配及动态更新问题

从上面的思路,采用Nginx似乎已经解决了问题,但是其实这里面有一个很大缺陷:每次有新服务加入怎么改Nginx配置?总不能手动改或者来个Rolling Update前端Nginx Pod吧?这时候"伟大而又正直勇敢的"Ingress"登场,如果不算上面的Nginx,Ingress只有两大组件:Ingress Controller和Ingress

 

Ingress这个玩意,简单的理解就是你原来要改Nginx配置,然后配置各种域名对应哪个Service,现在把这个动作抽象出来,变成一个Ingress对象,你可以用yml创建,每次不要去改Nginx了,直接改yml然后创建/更新就行了;那么问题来了“Nginx咋整?”

Ingress Controller这东西就是解决"Nginx咋整"的;Ingress Controller通过与Kubernetes API交互,动态的去感知集群中Ingress规则变化,然后读取他,按照他自己模板生成一段Nginx配置,再写到Nginx Pod里,最后reload一下,工作流程如下图

Kubernetes Nginx Ingress教程

当然在实际应用中,最新版本Kubernetes已经将Nginx与Ingress Controller合并为一个组件,所以Nginx无需单独部署,只需要部署Ingress Controller即可

 

 

相关文章: