编辑推荐: |
本文来自于网络,介绍了应用原理,Ingress
选型,创建Ingress资源对象,特性配置等知识。 |
|
写在前面
Ingress 英文翻译进入;进入权;进食,更准确的讲就是入口,即外部流量进入k8s集群必经之口。这到大门到底有什么作用?我们如何使用Ingress?k8s又是如何进行服务发现的呢?先看一张图:
原理
虽然k8s集群内部署的pod、server都有自己的IP,但是却无法提供外网访问,以前我们可以通过监听NodePort的方式暴露服务,但是这种方式并不灵活,生产环境也不建议使用。Ingresss是k8s集群中的一个API资源对象,扮演边缘路由器(edge
router)的角色,也可以理解为集群防火墙、集群网关,我们可以自定义路由规则来转发、管理、暴露服务(一组pod),非常灵活,生产环境建议使用这种方式。另外LoadBlancer也可以暴露服务,不过这种方式需要向云平台申请负债均衡器;虽然目前很多云平台都支持,但是这种方式深度耦合了云平台,所以你懂的。
首先我们来思考用传统的web服务器,比如Nginx,如何处理这种场景?
Nginx充当一个反向代理服务器拦截外部请求,读取路由规则配置,转发相应的请求到后端服务。
kubernetes处理这种场景时,涉及到三个组件:
1.反向代理web服务器
负责拦截外部请求,比如Nginx、Apache、traefik等等。我一般以Deployment方式部署到kubernetes集群中,当然也可以用DeamonSet方式部署;这两种部署方式个人觉得有利有弊,感兴趣的请参考这篇文章,这里就不敖述了。
2.Ingress controller
k8s中的controller有很多,比如CronJob、DeamonSet、Deployment、ReplicationSet、StatefulSet等等,大家最熟悉的应该是Deployment(嘿嘿,我也是),它的作用就是监控集群的变化,使集群始终保持我们期望的最终状态(yml文件)。同理,Ingress
controller的作用就是实时感知Ingress路由规则集合的变化,再与Api Server交互,获取Service、Pod在集群中的
IP等信息,然后发送给反向代理web服务器,刷新其路由配置信息,这就是它的服务发现机制。
3.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对于微服务来说简直就是一神器啊,嘿嘿。而Nginx在拥抱kubernetes这方面比较后知后觉,详情请参考官方网站和开源项目ingress-nginx
;另外微软开源的微服务示例项目 eShopOnContainers 采用了ingress-nginx,大家可以下去自行研究。
Traefik:
示例说明
创建Ingress资源对象
apiVersion:
extensions /v1beta1
kind: Ingress
metadata:
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选型,请参照各自的组件说明。
特性配置
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:
v1
kind: Service
metadata:
name: identity-api
namespace: geekbuying-light
labels:
app: light
component: identity
annotations:
traefik.backend.circuitbreaker: " NetworkErrorRatio()
> 0.5"
traefik.backend.loadbalancer. method: drr
spec:
selector:
app: light
component: identity
type: webapi
ports:
- port: 80 |
效果图
控制面板:
前端优先级、熔断器、负载均衡策略:
监控界面:
|