初试 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集群来管理项目.新项目还好,可以选择合适的集群规模从零开始构建项目: ...
-
在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密集型的. 基于微服 ...
-
(转)在Kubernetes集群中使用JMeter对Company示例进行压力测试
背景 压力测试是评估应用性能的一种有效手段.此外,越来越多的应用被拆分为多个微服务而每个微服务的性能不一,有的微服务是计算密集型,有的是IO密集型. 因此,压力测试在基于微服务架构的网络应用中扮演着越 ...
随机推荐
-
ORA 各种oraclesql错误
ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出 ...
-
爬虫:selenium + phantomjs 解决js抓取问题(一)
selenium模块主要用来做测试,模拟键盘.鼠标来操作浏览器. phantomjs 就像一个*面的浏览器一样. 两个结合能很好的解决js抓取的问题. 测试代码: #coding=utf-8 fro ...
-
《深入理解Nginx》阅读与实践(三):使用upstream和subrequest访问第三方服务
本文是对陶辉<深入理解Nginx>第5章内容的梳理以及实现,代码和注释基本出自此书. 一.upstream:以向nginx服务器的请求转化为向google服务器的搜索请求为例 (一)模块框 ...
-
解析xml报classnotfound错误
使用dom4j解析XML时,要快速获取某个节点的数据,使用XPath是个不错的方法,dom4j的快速手册里也建议使 用这种方式, 方法是使用Document的selectNodes(String XP ...
-
17.allegro导入导出[原创]
一.从一张现成的PCB中导出元件封装到库中 --- -- 二. ①规则 ②元件摆放位置信息导出 这个时候我们在新建的电路板上: ① 导入记事文档 -- -- 到如后: 系统本来默认的是双层,这个时候变 ...
-
SHELL自动运行脚本
pass.sh ------------------------ #!/bin/bashecho start /usr/bin/expect <<EOFset timeout 10spaw ...
-
The Rings Akhaten
在其他的平行宇宙中存在着一个古老的星系--Akhaten,星系中有七个世界,上面生活着Panbabylonian.Lucanian等物种,不过外界也常常把他们统称为Akhet,因为这七个世界环绕着同一 ...
-
linux通过history查看命令执行时间
Linux的bash内部命令history就可以显示命令行的命令历史,默认环境执行 history 命令后,通常只会显示已执行命令的序号和命令本身.如果想要查看命令历史的时间戳,那么可以执行:# ex ...
-
仔细讲解socket(转载https://www.zybuluo.com/phper/note/47110)
老实讲,到目前为止,我对socket一无所知,真的.我就现学现卖用过nodejs平台的socket.io搭建过一套高可用实时性的网页聊天系统,其他,就真的只是听过它. 今天就来仔仔细细的学一下,soc ...
-
Docker系列三:Docker容器管理
Docker容器管理 1. 单一容器管理 1) 容器的启动 $ docker run --name gitlab-redis -d --volume /srv/docker/gitlab/redis: ...