初试 Kubernetes 集群中使用 Traefik 反向代理
初试 Kubernetes 集群中使用 Traefik 反向代理
目录
- Traefik 介绍
- 环境、软件准备
- 部署 Traefik
- 部署 Traefik UI
- 部署自定义 Ingress
- 部分特性说明
1、Traefik 介绍
在日常工作中,我们经常使用 Nginx、Apache 等工具作为反向代理、负载均衡,而 Træfik 是一个为了让部署微服务更加便捷而诞生的 HTTP 反向代理、负载均衡工具。它支持多种后台 (Docker、Swarm、Kubernetes、Mesos、Consul、Etcd…) 来自动、动态的刷新配置文件,以实现快速地服务发现。在 Kubernetes 集群中使用,可以完全替代 ngxin + Ingress Controller,快速实现服务的暴漏。
引用 Traefik 官网文档 中的一张图片,可以简要说明一下什么是 Traefik。
从上图可以看出,在我们日常业务开发中,我们会部署一系列微服务,外部网络要通过 domain
、path
、负载均衡等转发到后端私有网络中,微服务之所以称为微,是因为它是动态变化的,它会经常被增加、删除、干掉或者被更新。而且传统的反向代理对服务动态变化的支持不是很方便,也就是服务变更后,我们不是很容易立马改变配置和热加载。traefik 的出现就是为了解决这个问题,它可以时刻监听服务注册或服务编排 API,随时感知后端服务变化,自动重新更改配置并热重新加载,期间服务不会暂停或停止,这对于用户来说是无感知的。
Traefik 还有很多特性如下:
- 速度快
- 不需要安装其他依赖,使用 GO 语言编译可执行文件
- 支持最小化官方 Docker 镜像
- 支持多种后台,如 Docker, Swarm mode, Kubernetes, Marathon, Consul, Etcd, Rancher, Amazon ECS 等等
- 支持 REST API
- 配置文件热重载,不需要重启进程
- 支持自动熔断功能
- 支持轮训、负载均衡
- 提供简洁的 UI 界面
- 支持 Websocket, HTTP/2, GRPC
- 自动更新 HTTPS 证书
- 支持高可用集群模式
上一篇文章 初试 Kubernetes 暴漏服务类型之 Nginx Ingress 中大概介绍了 Kubernetes 使用 Nginx Ingress 暴漏服务,接下来我们使用 Traefik 来替代 Nginx + Ingress Controller 来实现反向代理和服务暴漏。
那么二者有什么区别呢?简单点说吧,在 Kubernetes 中使用 nginx 作为前端负载均衡,通过 Ingress Controller 不断的跟 Kubernetes API 交互,实时获取后端 Service、Pod 等的变化,然后动态更新 Nginx 配置,并刷新使配置生效,来达到服务自动发现的目的,而 Traefik 本身设计的就能够实时跟 Kubernetes API 交互,感知后端 Service、Pod 等的变化,自动更新配置并热重载。大体上差不多,但是 Traefik 更快速更方便,同时支持更多的特性,使反向代理、负载均衡更直接更高效。
2、环境、软件准备
Kubernetes 集群中使用 Traefik 反向代理,前提我们需要有一个正常运行的集群服务,这里我采用 kubeadm 搭建的 Kubernetes 集群,具体搭建步骤可以参考我上一篇文章 国内使用 kubeadm 在 Centos 7 搭建 Kubernetes 集群 讲述的比较详细,这里就不做演示了。上边说了 Traefik 提供最小化官方 Docker 镜像,这次就不需要翻墙或者找替代品了哈,去 Docker Hub 下载最新版本的镜像即可。
3、部署 Traefik
在 Kubernetes 上部署 Traefik 很简单,只需 Yaml 创建一下即可。
$ cd /home/wanyang3/k8s/
$ git clone https://github.com/containous/traefik.git
# ll traefik/examples/k8s/
总用量 32
-rw-r--r--. 1 root root 1805 11月 9 16:23 cheese-deployments.yaml
-rw-r--r--. 1 root root 519 11月 9 16:23 cheese-ingress.yaml
-rw-r--r--. 1 root root 509 11月 9 16:23 cheese-services.yaml
-rw-r--r--. 1 root root 504 11月 9 16:23 cheeses-ingress.yaml
-rw-r--r--. 1 root root 978 11月 9 16:23 traefik-deployment.yaml
-rw-r--r--. 1 root root 1128 11月 9 16:23 traefik-ds.yaml
-rw-r--r--. 1 root root 694 11月 9 16:23 traefik-rbac.yaml
-rw-r--r--. 1 root root 466 11月 9 16:43 ui.yaml
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
traefik/examples/k8s/
这个目录下就是示例 Traefik 启动所需要的 yaml 文件,Traefik 提供了适配各个类型服务编排的部署方式,kubernetes 启动方式支持 Deployment 和 DaemonSet,二选一都可以。
$ kubectl create -f traefik/examples/k8s/traefik-rbac.yaml
clusterrole "traefik-ingress-controller" created
clusterrolebinding "traefik-ingress-controller" created
$ kubectl create -f traefik/examples/k8s/traefik-deployment.yaml
serviceaccount "traefik-ingress-controller" created
deployment "traefik-ingress-controller" created
service "traefik-ingress-service" created
$ kubectl get pods --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE
kube-system traefik-ingress-controller-833033881-1lnlt 1/1 Running 0 10s 10.96.4.23 node0.localdomain
...
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
好了,此时 Traefik 已经启动成功了,它同时启动了 80 和 8080 端口,80 对应的服务端口,8080 对应的 UI 端口,我们可以通过查看服务暴漏端口号浏览器访问下了提供的 UI 界面。
$ kubectl get service --all-namespaces
NAMESPACE NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes 10.96.0.1 <none> 443/TCP 2d
kube-system elasticsearch-logging 10.99.38.47 <none> 9200/TCP 2d
kube-system kibana-logging 10.107.203.145 <none> 5601/TCP 2d
kube-system kube-dns 10.96.0.10 <none> 53/UDP,53/TCP 2d
kube-system kubernetes-dashboard 10.96.156.22 <nodes> 80:30659/TCP 2d
kube-system traefik-ingress-service 10.96.8.191 <nodes> 80:30016/TCP,8080:30960/TCP 3m
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
访问 http://<node_ip>:<node_port>/dashboard/#/
,这里 <node_ip>
可以为 master 或者 node 节点 IP 均可,这里我使用的是 Master IP,如:http://10.222.76.93:30960/dashboard/#/
。
初次访问,我们发现 Providers 下 Kubernetes 什么服务都没有,Health里面也没有任何信息,这是因为我们还没有指定任何 Ingress 规则。
4、部署 Traefik UI
从上边可以看到 Traefik 提供了一套简洁的 UI 供我们使用,是由 Angular JS 编写的,它是以 Ingress 方式暴露服务的,只需要 Yaml 创建一下即可。
# 先修改一下 host,默认为 traefik-ui.minikube ,这里我改成 traefik-ui.k8s 更直观些。
vim ui.yaml
...
spec:
rules:
- host: traefik-ui.k8s
http:
paths:
- path: /
backend:
serviceName: traefik-web-ui
servicePort: web
...
$ kubectl create -f ui.yaml
service "traefik-web-ui" created
ingress "traefik-web-ui" created
$ kubectl get service --all-namespaces
NAMESPACE NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes 10.96.0.1 <none> 443/TCP 2d
kube-system elasticsearch-logging 10.99.38.47 <none> 9200/TCP 2d
kube-system kibana-logging 10.107.203.145 <none> 5601/TCP 2d
kube-system kube-dns 10.96.0.10 <none> 53/UDP,53/TCP 2d
kube-system kubernetes-dashboard 10.96.156.22 <nodes> 80:30659/TCP 2d
kube-system traefik-ingress-service 10.96.8.191 <nodes> 80:30016/TCP,8080:30960/TCP 25m
kube-system traefik-web-ui 10.98.14.250 <none> 80/TCP 13s
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
此时,我们不需要刷新浏览器 UI 界面,就可以看到 traefik-ui.k8s/
已经显示出来了,速度很快,用户无感知。
5、部署自定义 Ingress
好了,上边我们通过部署一个 Traefik 提供的 traefik-web-ui 服务,初窥了一下 Traefik,现在我们自定义一个 Ingress 来实现服务暴漏。从已安装的服务列表中可以看到,我们已经安装了很多服务,这里还是选择 kubernetes-dashboard 和 elasticsearch-logging 来演示一下,基于域名访问虚拟主机的 Ingress 配置,Yaml 文件如下。
$ vim dashboard-ela-k8s-traefik.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dashboard-ela-k8s-traefik
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: dashboard.k8s.traefik
http:
paths:
- path: /
backend:
serviceName: kubernetes-dashboard
servicePort: 80
- host: ela.k8s.traefik
http:
paths:
- path: /
backend:
serviceName: elasticsearch-logging
servicePort: 9200
$ kubectl create -f dashboard-ela-k8s-traefik.yaml
ingress "dashboard-ela-k8s-traefik" created
$ kubectl get ingress --all-namespaces
NAMESPACE NAME HOSTS ADDRESS PORTS AGE
kube-system dashboard-ela-k8s-traefik dashboard.k8s.traefik,ela.k8s.traefik 80 25s
kube-system traefik-web-ui traefik-ui.k8s 80 31m
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
再看一下 UI 页面,立马更新过来,可以看到刚刚配置的 dashboard.k8s.traefik
和 ela.k8s.traefik
。
接下来,看下通过域名下不同的路径转发到不同的服务上去的 Ingress 配置,Yaml 文件如下。
$ vim my-k8s-traefik.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-k8s-traefik
namespace: kube-system
annotations:
kubernetes.io/ingress.class: traefik
traefik.frontend.rule.type: PathPrefixStrip
spec:
rules:
- host: my.k8s.traefik
http:
paths:
- path: /dashboard
backend:
serviceName: kubernetes-dashboard
servicePort: 80
- path: /kibana
backend:
serviceName: kibana-logging
servicePort: 5601
$ kubectl create -f my-k8s-traefik.yaml
ingress "my-k8s-traefik" created
$ kubectl get ingress --all-namespaces
NAMESPACE NAME HOSTS ADDRESS PORTS AGE
kube-system dashboard-ela-k8s-traefik dashboard.k8s.traefik,ela.k8s.traefik 80 12m
kube-system my-k8s-traefik my.k8s.traefik 80 4s
kube-system traefik-web-ui traefik-ui.k8s 80 43m
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
注意:这里我们根据路径来转发,需要指明 rule 为 PathPrefixStrip,配置为 traefik.frontend.rule.type: PathPrefixStrip
再看一下 UI 页面,也是立马更新过来,可以看到刚刚配置的 my.k8s.traefik/dashboard
和 my.k8s.traefik/kibana
。
最后在演示一下更新或删除服务,Traefik 是否能够实时监测的到,我们去 Kubernetes dashboard 上将 dashboard 服务增加两个 pod,操作过程就不多说了,直接看结果吧!
6、部分特性说明
文章开头列举了一下 Traefik 的众多特性,有很多我还没了解到,目前了解到其中有两个很好的特性。
6.1 自动熔断
在集群中,当某一个服务大量出现请求错误,或者请求响应时间过久,或者返回500+错误状态码时,我们希望可以主动剔除该服务,也就是不在将请求转发到该服务上,而这一个过程是自动完成,不需要人工执行。Traefik 通过配置很容易就能帮我们实现,Traefik 可以通过定义策略来主动熔断服务。
NetworkErrorRatio() > 0.5
:监测服务错误率达到50%时,熔断。LatencyAtQuantileMS(50.0) > 50
:监测延时大于50ms时,熔断。ResponseCodeRatio(500, 600, 0, 600) > 0.5
:监测返回状态码为[500-600]在[0-600]区间占比超过50%时,熔断。
6.2 负载均衡策略
Traefik 提供两种负载均衡策略支持。一种是 wrr
(加权轮训调度算法),一种是 drr
(动态加权循环调度算法)。
从上边截图右侧我们看到提示 Load Balancer: wrr
,默认的策略为根据权重轮训调度,从图上可以看出,新创建的 service 权重都是一样为 1,这样的话,请求会平均分给每个服务,但是这样很多时候会出现资源分配不均衡的问题,比如由于集群中每个机器配置不一样,而且服务消耗不一样,假设 A 资源使用率已经很高,而 B 属于空闲状态,如果还是均摊到每个服务的话,会加重 A 的负荷,这时候因该有一种策略能够主动识别并分担更多流量到 B 才对。
drr
就更加智能,它是一种动态加权轮训调度方式,它会记录一段时间内转发到 A 的请求数,跟转发到 B 的请求数对比,转发数量多,说明处理速度快,响应时间快。如果 A 处理请求速度比 B 快,那么就会调整 A 的权重,接下来的一段时间,就会转发更多请求给 A,相应的 B 的转发就少一些。整个过程都在不断的调整权重,实现请求的合理分配,从而达到资源使用最大化。
Traefik 的其他特性,还在了解实践中,后期尝试之后在更新吧。
参考资料
初试 Kubernetes 集群中使用 Traefik 反向代理的更多相关文章
- 【转载】浅析从外部访问 Kubernetes 集群中应用的几种方式
一般情况下,Kubernetes 的 Cluster Network 是属于私有网络,只能在 Cluster Network 内部才能访问部署的应用.那么如何才能将 Kubernetes 集群中的应用 ...
- 实操教程丨如何在K8S集群中部署Traefik Ingress Controller
注:本文使用的Traefik为1.x的版本 在生产环境中,我们常常需要控制来自互联网的外部进入集群中,而这恰巧是Ingress的职责. Ingress的主要目的是将HTTP和HTTPS从集群外部暴露给 ...
- 解决项目迁移至Kubernetes集群中的代理问题
解决项目迁移至Kubernetes集群中的代理问题 随着Kubernetes技术的日益成熟,越来越多的企业选择用Kubernetes集群来管理项目.新项目还好,可以选择合适的集群规模从零开始构建项目: ...
- ingress-nginx 的使用 =》 部署在 Kubernetes 集群中的应用暴露给外部的用户使用
文章转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247488189&idx=1&sn=8175f067 ...
- 在Kubernetes集群中使用calico做网络驱动的配置方法
参考calico官网:http://docs.projectcalico.org/v2.0/getting-started/kubernetes/installation/hosted/kubeadm ...
- Docker Swarm集群中部署Traefik负载均衡器
一.创建单节点的Docker Swarm集群 docker swarm init 二.在Swarm集群中创建一个网络 docker network create --driver=overlay tr ...
- 在kubernetes集群中创建redis主从多实例
分类 > 正文 在kubernetes集群中创建redis主从多实例 redis-slave镜像制作 redis-master镜像制作 创建kube的配置文件yaml 继续使用上次实验环境 ht ...
- Kubernetes集群中Service的滚动更新
Kubernetes集群中Service的滚动更新 二月 9, 2017 0 条评论 在移动互联网时代,消费者的消费行为已经“全天候化”,为此,商家的业务系统也要保持7×24小时不间断地提供服务以满足 ...
- Kubernetes集群中Jmeter对公司演示的压力测试
6分钟阅读 背景 压力测试是评估Web应用程序性能的有效方法.此外,越来越多的Web应用程序被分解为几个微服务,每个微服务的性能可能会有所不同,因为有些是计算密集型的,而有些是IO密集型的. 基于微服 ...
随机推荐
- mysql-ubuntu卸载安装mysql
安装MySQL sudo apt-get install mysql-server mysql-client 查看状态 是否是运行中 sudo service mysql status 启动MySQL ...
- babel和postcss引起的一点儿思考
写es6,一般都会用到babel,它能把es6转为更好的es5,而es5可以直接在浏览器上运行.postcss是css界的babel,它可以把css转为更好的css,比如autoprefixer,让不 ...
- 28BYJ-48步进电机
28BYJ-48步进电机:1.步进电机是一种将电脉冲转化为角位移的执行机构. 2.通俗一点讲:当步进驱动器接收到 一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角). 3.通过控 ...
- 数码管应用digital_pile
#include "reg52.h" #include "digital_pile.h" void main(){ //P0 = 0x00; //P2 = 0x ...
- 常用类及 LeetCode 每日一题
1 日期时间类 在 Java 语言中,是通过时间戳来表示时间的.所谓的时间戳,在 Java 中就是指当前时间距离历元(1970-01-01 00:00:00)的时间间隔,单位是毫秒,所以 Java 中 ...
- tomcat出现Error in dependencyCheck java.io.IOException: invalid manifest format
我只能说这个错误很坑爹,检查了很多地方都没问题,结果最后在MANIFEST.MF 里面把所有的空的行都删掉就好了.坑爹有木有.
- python 字符串的一些方法
总结:# split 分割 ********# strip 脱 默认脱头尾的空格 ********# replace 替换 ********# join 插入 拼接 ********# format ...
- jsp get参数乱码问题
摘自:username2.iteye.com/blog/1597917个人理解中文传送的时后需要转码: js代码: 要进行两次转码才不会出现乱码(默认为UTF-) encodeURI(encodeUR ...
- iOS for MachineLearning
链接: 手把手教你在应用里用上iOS机器学习框架Core ML iOS11 新功能开发之 - "高大上"的 CoreML 与 Vision Core ML介绍 (Apple机器学习 ...
- ToolTip C#
yourToolTip = new ToolTip(); //The below are optional, of course, yourToolTip.ToolTipIcon = ToolTipI ...