初试 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。

从上图可以看出,在我们日常业务开发中,我们会部署一系列微服务,外部网络要通过 domainpath、负载均衡等转发到后端私有网络中,微服务之所以称为微,是因为它是动态变化的,它会经常被增加、删除、干掉或者被更新。而且传统的反向代理对服务动态变化的支持不是很方便,也就是服务变更后,我们不是很容易立马改变配置和热加载。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

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
...

好了,此时 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

访问 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

此时,我们不需要刷新浏览器 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

再看一下 UI 页面,立马更新过来,可以看到刚刚配置的 dashboard.k8s.traefikela.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

注意:这里我们根据路径来转发,需要指明 rule 为 PathPrefixStrip,配置为 traefik.frontend.rule.type: PathPrefixStrip

再看一下 UI 页面,也是立马更新过来,可以看到刚刚配置的 my.k8s.traefik/dashboardmy.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 的其他特性,还在了解实践中,后期尝试之后在更新吧。

参考资料

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

半自动化搭建Data Guard的想法和实践(二)(r9笔记第79天)

关于半自动化搭建Data Guard,自己花了一些时间,总算是把这件事情继续推进了一下,还是再啰嗦一句,为什么不自动化,因为安全。主库就是主库,任何变更都要手...

3255
来自专栏杨建荣的学习笔记

一则报警信息所折射出来的诸多问题(r9笔记第14天)

在主备库环境中,如果出现数据文件级的一些不一致,后期修复会很麻烦,所以这种情况可以提前规避,减少后期的隐患,我定制了一个数据库监控选项,即数据文件状态的检查。 ...

3398
来自专栏Hadoop实操

如何使用StreamSets实现MySQL中变化数据实时写入HBase

2142
来自专栏Hadoop实操

HDFS部署最佳实践

1784
来自专栏星汉技术

原 Spark简介及完全分布式安装

3186
来自专栏about云

监控hadoop生态系统企业应该用什么监控软件

问题导读 1.文中哪些监控软件有邮件通知功能? 2.监控粒度更细如何自定义实现? 3.哪些监控软件可以自定义? 企业转型大数据,随着发展,可能会遇到很多的问...

3177
来自专栏公有云大数据平台弹性MapReduce

腾讯云EMR使用说明: 配置工作流

本文将通过一个简单,并且具有典型代表的例子,描述如何使用EMR产品中的Hue组件创建工作流,并使该工作流每天定时执行。

9.9K13
来自专栏大魏分享(微信公众号:david-share)

Oracle11g RAC双NFS仲裁容错方案

说明: 整理文档时发现自己在2010年写的一个RAC容灾方案,觉得有一些用,分享出来。当时为了验证此方案,做了很多PoC。方案相对比较复杂,但是也提供了一种思路...

3909
来自专栏运维前线

CentOS 6.8 部署zookeeper集群

由于公司缓存方案改进,准备采用codis集群作为主要的缓存解决方案(codis:国内豌豆荚开发的redis集群解决方案,已开源,github地址:https:/...

20710
来自专栏恰同学骚年

Hadoop学习笔记—1.基本介绍与环境配置

说到Hadoop的起源,不得不说到一个传奇的IT公司—全球IT技术的引领者Google。Google(自称)为云计算概念的提出者,在自身多年的搜索引擎业务中构...

551

扫码关注云+社区