详解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
配置,可配置众多出色的特性,例如:自动熔断、负载均衡策略、黑名单、白名单;还支持许多后端存储,如:zookeeper、eureka、consul、rancher、docker等,它会自动感知这些统一配置中心的变化,热更新自己的路由配置,所以Traefik
对于微服务来说简直就是一神器啊,嘿嘿。那么Traefik
性能又如何呢?容器化部署,还担心性能,不要这么搞笑,好吗。而Nginx
在拥抱kubernetes
这方面比较后知后觉,详情请参考官方网站和开源项目ingress-nginx ;另外微软开源的微服务示例项目 eShopOnContainers 采用了ingress-nginx
,大家可以下去自行研究。
Traefik :
示例说明
使用Ingress
暴露微服务
apiVersion: extensions/v1beta1kind: Ingressmetadata: labels: app: light component: frontend name: light-edge-router namespace: geekbuying-light annotations:
kubernetes.io/ingress.class: "traefik"
ingress.kubernetes.io/ssl-redirect: "false"
traefik.frontend.rule.type: "PathPrefixStrip"
traefik.ingress.kubernetes.io/frontend-entry-points: "http,https"
traefik.ingress.kubernetes.io/priority: "3"spec: rules: - host: <hostdomain literal> http: paths: - path: /api/v1/light backend: serviceName: aggregation-light-api servicePort: 80 - path: /api/v1/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
选型,请参照各自的组件说明。
其他命名空间下的服务发现规则为:[serviceName].[namespace]:[port],如:exceptionless-ui.geekbuying-light-addons:80(备注:端口80可以省略,其他端口不能省略),表示查找geekbuying-light-addons
命名空间下的exceptionless-ui
服务,并匹配端口。
特性配置
traefik支持强大的annotations
配置,需要添加到kubernetes
相应资源对象的annotations
下面。至于具体配置到的哪个对象,先弄清楚三个概念:
EntryPoint(入口点)
顾名思义,这是外部网络进入traefik
的入口,我们上面就是通过监听主机端口拦截请求。
FrontEnd(前端)
traefik
拦截请求后,会转发给FrontEnd
。前端定义EntryPoint
映射到BackEnd
的路由规则集,字段包括Host
, Path
, Headers
等,匹配请求后,默认通过加权轮询负载算法路由到一个可用的BackEnd
,然后进入指定的微服务,这就是服务发现。
备注:这些路由规则可以来自不同的后端存储,如Kubernetes、zookeeper、eureka、consul
等,Kubernetes
使用的Ingress
资源对象定义路由规则集。建议大家自行去官网学习Kubernetes Ingress Backend。
BackEnd(后端)
一组http
服务集,kubernetes
中对应一个service
对象下的一组pod
地址。对于后端的服务发现,可配置负载均衡策略、熔断器等特性。
一个后端service
对象的配置例子:
apiVersion: v1kind: Servicemetadata: annotations:
traefik.backend.circuitbreaker: NetworkErrorRatio() > 0.5
traefik.backend.loadbalancer.method: drr labels: app: light component: identity name: identity-api namespace: geekbuying-lightspec: ports:
- port: 80
selector: app: light component: identity type: webapi
效果图
控制面板:
前端优先级、后端熔断器和负载均衡策略:
监控界面:
总结
综上所述,首先部署拥抱k8s的反向代理服务器(treafik、nginx
等)拦截请求,然后拦截的请求会根据Ingress
定义的路由规则集,转发到集群内部对应的Service
。
延伸阅读
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
如果你觉得本篇文章对您有帮助的话,感谢您的【推荐】。
如果你对 kubernets 感兴趣的话可以关注我,我会定期的在博客分享我的学习心得。