本文介绍K8S的Ingress的作用。
-----------------------------------------------------------------------------------------------
分享Java真实高频面试题,吊打面试官: Java后端真实面试题大全 - 自学精灵
分享靠谱的Java高级实战,包含:高并发、架构、全局处理等:JavaWeb高级实战 - 自学精灵
-----------------------------------------------------------------------------------------------
Kubernetes 暴露服务的有三种方式:LoadBlancer Service、NodePort Service、Ingress。官网的定义:管理对外服务到集群内服务之间规则的集合。即:将请求转发到服务,实现服务暴露。
Ingress的功能类似Nginx:把集群内 Service 配置成外网能够访问的 URL、流量负载均衡、提供基于域名访问的虚拟主机等。
Ingress由两部分组成:
可以将Ingress比作一张地图,而Ingress Controller则是导航系统,它根据地图上的规则将请求导航到正确的位置。
Ingress在调用流程的位置
K8S集群内服务想要暴露出去面临着几个问题:
K8S在任意副本(Pod)挂掉时自动启动一个新的。这个新节点可能在任何节点上,Pod IP 会变。如何把动态的 Pod IP 暴露出去?
答案:使用K8S的Service,以标签的形式选定带有指定标签的Pod,并监控和自动负载它们的 Pod IP,只向外暴露 Service IP即可。
一般使用NodePort来暴露:创建NodePort类型的Service时,K8S会自动在集群的每个节点上开一个端口,将请求转发到内部 Service IP 上,如下图所示:
用 NodePort 方式暴露服务面临的问题是:如果服务数量很多,NodePort 在每个节点上开启的端口会很多。
思考:能否使用Nginx只监听一个端口,比如80,然后按照域名向后转发?
这思路很好,可以使用 DaemonSet 在每个node上监听80,然后写规则。Nginx 外面绑定了宿主机 80 端口(就像 NodePort),本身又在集群内,那么将请求转发到相应Service IP就行了,如下图所示:
按上面的思路,用 Nginx 似乎已经解决了问题,但是有一个很大缺陷:每次有新服务加入怎么改 Nginx 配置?总不能手动改吧?
Ingress就是为了解决这个问题的。原来要改 Nginx 配置,然后配置各种域名对应哪个 Service,现在把这个动作抽象出来,变成一个 Ingress 对象,你可以用 yml 创建,不用每次都去改 Nginx 了,直接改yml,然后创建/更新就行了。
Ingress Controoler 动态的去感知集群中 Ingress 规则变化,生成一段 Nginx 配置,写到 Nginx Pod 里,最后 reload 一下,工作流程如下图:
在实际应用中,最新版本 Kubernetes 已经将 Nginx 与 Ingress Controller 合并为一个组件,所以 Nginx 无需单独部署,只需要部署 Ingress Controller 即可。