#云原生征文# Ingress-nginx和Ingress-traefik对比和应用 原创
@toc
1.Ingress
1.1 Service与Ingress的对比
基于L4的服务
每个应用独占ELB, 浪费资源
为每个服务动态创建DNS记录,频繁的DNS更新
支持TCP和UDP,业务部门需要启动HTTPS服务,自己管理证书
基于L7的Ingress
多个应用共享ELB,节省资源
多个应用共享一个Domain,可采用静态DNS配置
TLS termination发生在Ingress 层,可集中管理证书
更多复杂性,更多的网络hop
1.2 Ingress和Ingress Controller
1.2.1 Ingress
1、Ingress是一层代理
2、负责根据hostname和path将流量转发到不同的服务上,使得一个负载均衡器用于多个后台应用
3、Kubernetes Ingress Spec是转发规则的集合
1.2.2 Ingress Controller
1、在kubernetes领域,确保实际状态(Actual)与期望状态(Desired)一致的组件称为controller
2、Ingress Controller确保
负载均衡(HTTP2、HTTP/HTTPS、SSL/TLS 卸载、TCP/UDP、WebSocket、gRPC)
边缘路由配置
DNS配置
流量控制(速率限制、断路、主动健康检查)
流量分流(调试路由、A/B 测试、灰度部署、蓝绿部署)
1.3 kubernetes中的负载均衡技术
1.3.1 基于L4的服务
1、基于四层负载均衡技术
2、多种Load Balancer Provider提供与企业现有ELB的整合
3、Kube-proxy基于iptables rules为kubernetes形成全局统一的distributed load balancer
4、Kube-proxy是一种mesh, Internal Client无论通过pod ip,nodeport还是LB VIP都经由kube-proxy跳转至pod
5、属于kubernetes core
1.3.2 基于L7的Ingress(L7 - HTTP / TCP)
1、基于七层,提供更多功能
2、TLS termination
3、L7 path forwarding
4、URL/http header rewrite
5、与采用7层软件紧密相关
1.4 几个Ingress Controller
1.4.1 Kubernetes Ingress
官方推荐的ingress控制器,google主导开发,简称gic,基于nginx web服务器,容易上手,学习成本低
配置文件多的适合reload慢,插件扩展能力非常弱小。功能有限,牵扯很多模块和lua代码,定制困难。基于nginx+lua,集成了第三方模块(Sticky、Brotli、balancer by lua)门槛高,偏运维,可编程弱
1.4.2 Nginx Ingress(官方维护的方案)
是nginx开发的官方版本,基于nginx plus商业版本,简称NIC/KIC,有很高稳定性,持续向后兼容性,没有任何第三方模块,支持tcp/udp流量转发。门槛低,天花板高,框架大且自由,可定制的地方多。
缺点:缺失鉴权方式、流量调度等其他功能
扩展资源:mergeable-ingress、snippets(直接嵌入nginx指令),针对1和2,最好用crd自定义资源。
=区别于GIC的NGINX+Lua的方案,KIC全部是基于C语言实现的,好处就是高效,因为Lua毕竟还是脚本语言,要有虚拟机去解释运行,KIC用 C语言去实现的会更高效一些。
1.4.3 Kong Ingress(lua)
建立在nginx之上,增加了扩展其功能的lua模块,支持模块插件,方便配置。提供了api和服务的定义,可抽象为k8s的crd
1.4.4 Traefik Ingress(基于go,微服务网关)
是一个功能很全面的Ingress.连续更新配置(不重新启动),支持多种负载平衡算法,Web UI,指标导出,支持各种协议,REST API,Canary版本等.在2.0版本已经支持了TCP / SSL,金丝雀部署和流量镜像/阴影等功能,社区非常活跃。可编程API/对接各种服务发现。
缺点:生产案例不太多,不支持数据转换,容器集成上仅作为网关
1.4.5 HAProxy Ingress
最大的优势还在负载均衡上。无流量丢失,基于DNS的服务发现.还支持完全自定义配置文件模板(通过替换ConfigMap)以及在其中使用Spring Boot函数。
1.4.6 Istio Ingress
是ibm.google和Lyft(Envoy的原始作者)的联合项目,是一个全面的服务网格解决方案,中心思想是最大程度的控制,可扩展性,安全性和透明性。
1.4.7 APISIX Ingress
是一个新兴的Ingress Controller,它主要对标Kong Ingress。强大的路由能力、灵活的插件拓展能力
缺点:缺少落地案例,文档不健全。
1.5 选择的维度
1、支持的协议:是否支持除HTTP(S)之外的协议
2、路由的规则:有哪些转发规则,是否支持正则
3、部署策略:是否支持ab部署、金丝雀部署、蓝绿部署等
4、upstream探针:通过什么机制判定应用程序正常与否,是否有主动和被动检查,重试,熔断器,自定义运行状况检查等解决方案
5、负载均衡算法:支持哪些负载均衡算法,Hash、会话保持、RR、WRR等
6、鉴权方式:支持哪些授权方案?基本,摘要,OAuth,外部身份验证等
7、DDoS防护能力:是否支持基本的限速、白名单等
8、全链路跟踪:能否正常接入全链路监控
9、JWT验证:是否有内置的JSON Web令牌验证,用于对最终应用程序的用户进行验证和验证
10、图像界面:是否需要图形界面
11、定制扩展性:是否方便扩展
1.6 Ingress-nginx使用
1、Ingress Http
(1) 部署 Deployment 与 Service
(2) 查看
(3) 访问端设置本地DNS解析 & 在浏览器中进行HTTP访问
2、ingress HTTPS 代理访问
TLS 证书配置 https://kubernetes.github.io/ingress-nginx/user-guide/tls/
nginx.ingress.kubernetes.io/ssl-redirect
nginx.ingress.kubernetes.io/force-ssl-redirect # 即使lngress未启用TLS,也强制重定向到HTTPS bool
(1) 创建 Pod 与 Service
(2) 创建证书及cert存储方式
(3) 创建 ingress-nginx https
3、Ingress Rewrite 重写重定向访问
4、Ingress VirtualHost 虚拟主机访问
5、Ingress BasicAuth(基础认证)功能
(1) 先安装Apache的模块 : Nginx的认证方案所需
(2) 把该文件以secret方式进行保存,类型为generic
(3) 部署Ingress资源清单
6、Ingress Redirect 域名重定向功能
annotations:
nginx.ingress.kubernetes.io/permanent-redirect: ‘https://chandao.index’
7、Ingress 黑白名单访问限制
Annotations(注解) :只对指定的ingress生效nginx.ingress.kubernetes.io/whitelist-source-range
ConfigMap(配置文件) :全局生效
黑名单可以使用ConfigMap去配置,白名单使用Annotations去配置。
8、Ingress Header 请求头匹配
可以采用nginx.ingress.kubernetes.io/server-snippet注解
9、Ingress 灰度金丝雀发布
10、Ingress 相关配置补充
(1) 自定义错误页面 修改 deploy.yaml 中指定 nginx-ingress-controller 运行的参数,
在此处添加- --default-backend-service=名称空间/SVC名称参数
(2) 连接和传输速率限制
减轻DDoS攻击
11、Socket.io
12、限速
13.证书生成
证书主要的格式有以下几种
a.DER .CER
b.PEM,文本格式,可保存证书,可保存私钥。
c.CRT,可以是二进制格式,可以是文本格式,
d.PFX .P12,二进制格式
e.JKS,二进制格式
mtls (双向认证)
由同一个 root ca 生成两套证书。客户端使用 https 访问服务端时,双方会交换证书,
并进行认证,认证通过方可通信。
15、tcp和udp( UDP 负载均衡)
–tcp-services-configmap
–udp-services-configmap
1.7 Ingress—服务发现
外部流量进入k8s集群必经之口。可以自定义路由规则来转发、管理、暴露服务(一组pod),非常灵活,生产环境建议使用这种方式。LoadBlancer也可以暴露服务,但是深度耦合了云平台。是k8s微服务南北流量的入口。
Ingress 由Ingress API对象和 Ingress Controller 组成。kubernetes处理这种场景时,涉及到三个组件:
1.反向代理web服务器(反向代理负载均衡器)
负责拦截外部请求,比如Nginx、Apache、traefik等。可用DeamonSet、Deployment、Replication Controller方式部署;
2.Ingress controller
k8s中的controller有很多,比如CronJob、DeamonSet、Deployment、ReplicationSet、StatefulSet等等,Deployment,它的作用就是监控集群的变化,使集群始终保持我们期望的最终状态(yml文件)。同理,Ingress controller的作用就是实时感知Ingress路由规则集合的变化,再与Api Server交互,获取Service、Pod在集群中的IP等信息,然后发送给反向代理web服务器,刷新其路由配置信息,这就是它的服务发现机制。
3.Ingress
定义路由规则集合比如说某个域名对应某个 service,即当某个域名的请求进来时转发给某个 service;这个规则将与 Ingress Controller 结合,然后 Ingress Controller 将其动态写入到负载均衡器配置中,从而实现整体的服务发现和负载均衡
图解:
1.8 Nginx-Ingress工作流程
1、ingress controller和k8s api交互,感知ingress
规则变化;
2、读取变化,按照自定义规则,即域名对应的
service,生成一段nginx配置;
3、将2中的写到nginx-ingress-controller的pod里
pod中运行一个nginx服务,控制器会把生成的写
入到/etc/nginx.conf文件中;
4、然后reload配置即可。
如何构建ingress controller
1、复用Kubernetes LoadBalancer接口
2、定义Informer,监控ingress, secret, service,
endpoint的变化,加入相应的队列
3、启动worker,遍历ingress队列
1.9 ngress-nginx代码代码解析
ngress-nginx代码分两部分:
ingress-nginx 的目标是构造配置文件(nginx.conf)
主要用途是在配置文件有任何变更后都需重新加载NGINX
注意:upstream 配置变更的时候我们不需要重新加载
Nginx(即当你部署的应用 Endpoints 变更时)
常操作的不同对象来构建模型: Ingresses、Services、
Endpoints、Secrets 以及 Configmaps
1.10 ingress-nginx运行原理
ingress-nginx 控制器主要是用来组装一个 nginx.conf 的配置文件,当配置文件发生任何变动的时候就需要重新加载 Nginx 来生效,但是并不会只在影响 upstream 配置的变更后就重新加载 Nginx,控制器内部会使用一个 lua-nginx-module 来实现该功能。
Ingress-nginx流量控制—AHAS Sentinel
AHAS Sentinel 为 Ingress/Nginx 网关提供原生的入口流量控制能力,将流量防护进行前置,提前对多余的流量进行拦截,保障后端服务的稳定性。
主要配置:
use-sentinel: true
sentinel-params: --app=ahas-ingress-demo
配置完成后,进行分组,设置,假设限流为20,分组名为chandao,流程图为:
1.11 Ingress-nginx灰度发布—Annotations
ingress-nginx 支持通过 Annotations 配置【标签:key/value】来实现不同场景下的灰度发布和测试,可以满足金丝雀发布、蓝绿部署与 A/B 测试等业务场景。
总体来说,分为两类
1、基于用户
2、基于权重
优先级:canary-by-header -> canary-by-cookie -> canary-weight
TCP与UDP
由于在 Ingress 资源对象中没有直接对 TCP 或 UDP 服务的支持,
要在 ingress-nginx 中提供支持,需要在控制器启动参数中添加
–tcp-services-configmap 和 --udp-services-configmap
配置示例
tcp: # 配置 tcp 服务
27017: “default/mongo:27017” # 使用 27017 端口去映射 mongo 服务
9000: “default/chandao:8080” # 如果还需要暴露其他 TCP 服务,继续添加即可
udp: # 配置 udp 服务
53: “kube-system/kube-dns:53”
Ingress-nginx访问控制—IP
用户ip的传递依靠的是X-Forwarded-*参数。但是默认情况下,ingress是没有开启的。
- use-forwarded-headers
如果Nginx在其他7层代理或负载均衡后面,当期望Nginx将X-Forwarded-*的头信息传递给后端服务时,则需要将此参数设为true
如果设为false(默认为false),Nginx会忽略掉X-Forwarded-*的头信息。false设置适用于Nginx直接对外或前面只有3层负载均衡的场景
use-forwarded-headers: “true”
-
forwarded-for-header
用来设置识别客户端来源真实ip的字段,默认是X-Forwarded-For。可根据需要进行设置更改。 -
compute-full-forwarded-for
在configmap的data配置块添加:compute-full-forwarded-for: “true”。其作用就是,将客户端用户访问所经过的代理ip按逗号连接的列表形式记录下来。
1.12 部署方案
1.13 Ingress其他说明
解决问题:
1、动态配置服务
2、减少不必要的Port暴露(安全,容易管理端口)
ingress-nginx和ingress-nginx-controller区别
ingress-Nginx: 是每个服务自己创建的ingress,就是nginx的转发规则,生成Nginx的配置文件
ingress-Nginx-Controller: 相当于Nginx的服务,监听API Server,根据用户编写的ingress-nginx规则(ingress.yaml文件),动态的去更改Nginx服务的配置文件,并且reload使其生效,此过程是自动化的通过lua实现
目前常用的Ingress-Nginx-Controller有两个。一个是K8S官方
开源的Ingress-Nginx-Controller,另一个是nginx官方开源的
Ingress-Nginx-Controller。
1)K8S官方的Controller也是采用Go语言开发的,集成了Lua
实现的OpenResty;而Nginx官方的controller是集成了Nginx;
2)两者对Nginx的配置不同,并且使用的nginx.conf配置模板
也是不一样的,Nginx官方的采用两个模板
文件以include的方式配置upstream;
K8S官方版本采用Lua动态配置upstream,所以不需要reload。
在pod频繁变更的场景下,
采用K8S官方版本不需要reload,影响会更小。
2.Traefik
2.1 Traefik简介
traefik 本身就能跟 kubernetes API 交互,感知后端变化。traefik 是一个前端负载均衡器,做反向代理。对于微服务架构尤其是 kubernetes 等编排工具具有良好的支持;traefik部署在k8s上分为daemonset和deployment。所有操作都会自动实时进行(热加载)。在2.0版本之后增加了tcp代理。证书有效期为3个月,剩余不足30天时,Traefik将自动尝试续订。
2.2 Traefik部署
在k8s上分为daemonset和deployment
------daemonset 能确定有哪些node在运行traefik,所以可以确定的知道后端ip,但是不能方便的伸缩
------deployment 可以更方便的伸缩,但是不能确定有哪些node在运行traefik
所以不能确定的知道后端ip
1、面向内部(internal)服务的traefik,建议可以使用deployment的方式
2、面向外部(external)服务的traefik,建议可以使用daemonset的方式
同 nginx 等相比,traefik 能够自动感知后端容器变化,从而实现自动服务发现
2.3 Traefik原理图、五大核心组件、架构图
2.4 Traefik—EntryPoints Routes Service
entryPoints示例
entryPoints:(静态配置)
web:
address: “:80”
web-secure:
address: “:443”
routers示例(动态配置)
http:
routers:
my-router:
rule: “Path(/chandao
)”
service: service-chandao
将 /chandao请求被 service-chandao 服务处理
http:
services:
my-service:
loadBalancer:
servers:
- url: “http://ip-server-1/”
- url: “http://ip-server-2/”
Services示例
tcp:
services:
my-service:
loadBalancer:
servers:
- address: “10.10.10.10”
- address: “10.10.10.11”
2.5 Traefik—EntryPonit
自动生成HTTPS证书
Traefik除了使用自有证书外,还支持Let’s Encrypt自动生成证书【6】。
要使用Let’s Encrypt自动生成证书,需要使用ACME。需要在静态配置中定义 “证书解析器”,Traefik负责从ACME服务器中检索证书。
然后,每个 "路由器 "被配置为启用TLS,并通过tls.certresolver配置选项与一个证书解析器关联。
Traefik—Middlewares Providers
2.6 Traefik— 创建
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
spec:
entryPoints:
- web
routes:
- match: Host(traefik.k8s.com
)
kind: Rule
services:
- name: traefik
port: 8080
2.7 Traefik— 创建 Traefik Dashboard 路由规则对象
1、 通过 Middlewares 中间件自定义扩展( https://doc.traefik.io/traefik/middlewares/overview/ )
2、具有可观测的 GUI 仪表板(服务日志、访问日志、链路追踪tracing、metrics数据)
3、轻松处理 TLS 证书自动续订
4、文档中充斥着每种提供者类型、每种功能的配置示例
除此以外,借助其云原生特性,其能够完全支持 Metrics,与 Prometheus 和 Kubernetes 无缝集成等;其还能够具备更丰富的高级功能。例如,多版本的灰度发布、流量复制、自动生成 HTTPS 免费证书以及其他相关特性等。
2.8 Traefik日志收集
1、打开traefik日志功能
2、日志显示客户端源IP spec.externalTrafficPolicy设置为local
3、CRD
网关规划
1、业务网关:traefik-business
2、内部使用网关:traefik-internal,常用内部使用网关即可。
2.9 Ingress-traefik—主要特性
1、自动熔断
配置实现,也可以定制策略来主动熔断。
熔断和限流根据middlewares实现,对流量匹配后,再进行中间件二次流量确认。
如图:
2、负载均衡
wrr(加权轮训调度算法,默认)
drr(动态加权循环调度算法)
3、Gateway API
旨在通过可扩展的面向角色的接口来增强服务网络。Gateway API 是 Kubernetes 中的一个 API 资源集合,包括 GatewayClass、Gateway、HTTPRoute、TCPRoute、Service 等。Gateway API 中定义了3种主要的资源模型:GatewayClass、Gateway、Route。
GatewayClass:定义了一组共享相同配置和动作的网关。
Gateway:将流量转化为集群内的服务
Route 资源:将请求从网关映射到 Kubernetes 服务。
流程
1). 客户端向 http://foo.chandao.com 发出请求
2).DNS 将域名解析为 Gateway 网关地址
3).反向代理在监听器上接收请求,并使用 Host Header 来匹配HTTPRoute
4).(可选)反向代理可以根据 HTTPRoute 的匹配规则进行路由
5).(可选)反向代理可以根据 HTTPRoute 的过滤规则修改请求,即添加或删除 headers
6).反向代理根据 HTTPRoute 的 forwardTo 规则,将请求转发给集群中的一个或多个对象,即服务。
4、traefik可观测性
1)、服务日志
2)、访问日志
3)、Metrics
4)、提供了链路追踪接口tracing
5、安全性
证书
ingress-traefik 和ingress nginx对比
2.10 traefik总结:
更快速方便,同时支持更多的特性,使反向代理,负载均衡更直接更高效。
微服务下更适合用traefik,当 Traefik 检测到新服务时,它会自动创建相应的路由,然后我们可以访问相应的路由
完全支持Metrics(资源监控) Prometheus(开源监控系统)和 Kubernetes 无缝集成等
多版本的灰度发布、流量复制、自动生成 HTTPS 免费证书
缺点:cpu利用率很高,压榨了cpu整体性能,不如nginx.
服务少,不常更改或添加,使用nginx。cpu利用率优势大。高并发场景Nginx Ingress 使用大量源端口与 upstream 建立连接,端口范围小容易导致源端口耗尽,使得部分连接异常。需要调高单个 worker 最大连接数,调高 keepalive 最大空闲连接数,调高 keepalive 连接最大请求数。还需要内核参数调优,操作繁琐。一旦扩展,就会出现很多问题。
主流性:github
stars : ingress-traefik>ingress-nginx
releases:ingress-traefik>ingress-nginx
commits:ingress-traefik<ingress-nginx
可见,ingress-traefik更加活跃,后起之秀。
2.11 其他说明
一、gateway api
ingress-traefik可以支持,ingress-nginx也可以但需解决如下问题
a、定义类的ingress api
b、实现ingress api的controller,负载实际流量的转发控制
c、打通外部访问
二、部署区别
金丝雀:又称灰度,原版本可用,部署一新版本,测试新版本(小–大推广)
蓝绿:流量开关和镜像(见下方ppt备注解释)
灰度:百分比(见下方ppt备注解释)
1、ingress-nginx
a、ingress-nginx金丝雀
前提条件:部署nginx ingress作为ingress controller,且暴露统一流量入口
支持场景:header cookie 权重
场景1:灰度发布给部分用户
场景2:切流量给新版本
b、ingress-nginx灰度发布【配置好annotarion】
支持场景:header cookie 权重
c、ingress-nginx蓝绿发布【配置好annotarion】
流量转发(旧版本100%流量导入新的后端服务),七层的ingress不好实现蓝绿发布。
缺点:集群需要安装nginx-ingress插件,存在资源消耗
2、traefik
不需要安装ingress controller,直接创建ingress,省去了很多步骤。
k8s中部署:使用deamonset部署,便于扩展,hostport绑定端口。支持crd 方式 金丝雀部署
由于负载均衡,WRR 这个功能目前只支持 File Provider,所以要开启File Provider。将配置文件内容挂载到 Traefik 的 Pod 中。
不同点:traefik中负载权重分配指定每个部署的请求的百分比方式
流量复制:流量镜像,ingress-nginx没有此功能。
三、错误码
ingress-traefik:常遇错误码500【服务进程主动关闭了空闲连接导致】和502【EOF,没有读取完响应数据,就断开】可调整配置参数修改
ingress-nginx:404 504
3.总结
综合对比而言,建议在项目实践中使用traefik
A、结合:
一、前置条件
1、创建平台k8s集群
2、集群创建后,配置kubectl客户端连接k8s集群
二、traefik部署
1、权限配置
创建响应的ClusterRole和ClusterRoleBinding,赋予权限
2、部署traefik
80端口为接收HTTP请求,8080为dashboard端口
通过LoadBalancer类型的Service创建平台负载均衡SLB,
作为集群入口
3、创建服务
对外提供的http服务,根据平台或公司项目创建需要的服务
4、访问
访问3中创建的服务(项目中的某一个)
5、配置域名和证书并解析SLB到公网
【本文正在参加云原生有奖征文活动】,活动链接:https://ost.51cto.com/posts/12598