详解k8s组件Ingress边缘路由器并落地到微服务 - kubernetes
写在前面
Ingress
英文翻译 进入;进入权;进食
,更准确的讲就是入口,即外部流量进入k8s
集群必经之口。这到大门到底有什么作用?我们如何使用Ingress
?k8s
又是如何进行服务发现的呢?先看一张图:
备注:此图来源我转载的一篇博客NodePort,LoadBalancer还是Ingress?我该如何选择 – kubernetes,特此说明。
原理
虽然k8s
集群内部署的pod
、server
都有自己的IP
,但是却无法提供外网访问,以前我们可以通过监听NodePort
的方式暴露服务,但是这种方式并不灵活,生产环境也不建议使用。Ingresss
是k8s
集群中的一个API
资源对象,扮演边缘路由器(edge router)的角色,也可以理解为集群防火墙、集群网关,我们可以自定义路由规则来转发、管理、暴露服务(一组pod),非常灵活,生产环境建议使用这种方式。另外LoadBlancer
也可以暴露服务,不过这种方式需要向云平台申请负债均衡器;虽然目前很多云平台都支持,但是这种方式深度耦合了云平台,所以你懂的。
首先我们来思考用传统的web
服务器,比如Nginx
,如何处理这种场景?Nginx
充当一个反向代理服务器拦截外部请求,读取路由规则配置,转发相应的请求到后端服务。
kubernetes
处理这种场景时,涉及到三个组件:
- 反向代理
web
服务器
负责拦截外部请求,比如Nginx
、Apache
、traefik
等等。我一般以Deployment
方式部署到kubernetes
集群中,当然也可以用DeamonSet
方式部署;这两种部署方式个人觉得有利有弊,感兴趣的请参考这篇文章,这里就不敖述了。- Ingress controller
k8s
中的controller
有很多,比如CronJob
、DeamonSet
、Deployment
、ReplicationSet
、StatefulSet
等等,大家最熟悉的应该是Deployment
(嘿嘿,我也是),它的作用就是监控集群的变化,使集群始终保持我们期望的最终状态(yml文件)。同理,Ingress controller
的作用就是实时感知Ingress
路由规则集合的变化,再与Api Server
交互,获取Service
、Pod
在集群中的IP
等信息,然后发送给反向代理web
服务器,刷新其路由配置信息,这就是它的服务发现机制。- Ingress
定义路由规则集合,上面已经详细介绍,这里就不再敖述了。
经过上面的剖析,知道了吧,如果我们仅仅创建Ingress
对象,只是定义了一系列路由规则集合而且,没有任何作用,不要想得太简单了,嘿嘿。
Ingress 选型
这个我花费了不少时间,最终选用的是Traefik
,它是一个用Golang开发的轻量级的Http反向代理和负载均衡器,虽然相比于Nginx
,它是后起之秀,但是它天然拥抱kubernetes
,直接与集群k8s的Api Server
通信,反应非常迅速,实时感知集群中Ingress
定义的路由规则集合和后端Service
、Pod
的变化,自动热更新Traefik
后端配置,根本不用创建Ingress controller
对象,同时还提供了友好的控制面板和监控界面,不仅可以方便地查看Traefik
根据Ingress
生成的路由配置信息,还可以查看统计的一些性能指标数据,如:总响应时间、平均响应时间、不同的响应码返回的总次数等,Traefik
部署请参考官网用户示例Kubernetes Ingress Controller。不经如此,Traefik
支持丰富的annotations
配置,可配置众多出色的特性,例如:自动熔断、负载均衡策略,Traefik
对于微服务来说简直就是一神器啊,嘿嘿。而Nginx
在拥抱kubernetes
这方面比较后知后觉,详情请参考官方网站和开源项目ingress-nginx ;另外微软开源的微服务示例项目 eShopOnContainers 采用了ingress-nginx
,大家可以下去自行研究。
Traefik
:
示例说明
创建Ingress
资源对象
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
spec:
rules:
host: registry.wuling.com
- http:
paths:
- path: /api/vi/identity
backend:
serviceName: identity-api
servicePort: 80
非常重要:当我们定义额外的路由时,比如这里的
/api/vi/identity
,必须添加这个traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
注解传递路径,否则会看不到任何效果;ingress.kubernetes.io/ssl-redirect: "false"
是否强制使用https
,其他的配置信息,请查看详情。另外,不同的Ingress
选型,请参照各自的组件说明。
Traefik
的控制面板:
Traefik
的监控界面:
延伸阅读
https://docs.traefik.io/
https://github.com/containous/traefik
https://docs.traefik.io/user-guide/kubernetes/
https://docs.traefik.io/configuration/backends/kubernetes/
https://kubernetes.io/docs/concepts/services-networking/ingress/
https://kubernetes.io/docs/admin/authorization/rbac/
https://github.com/kubernetes/ingress-nginx/blob/master/README.md
https://kubernetes.github.io/ingress-nginx/development/
https://www.kubernetes.org.cn/1237.html
https://github.com/kubernetes/ingress-nginx
https://blog.csdn.net/hxpjava1/article/details/79459489
https://blog.csdn.net/hxpjava1/article/details/79375452