zzxworld

Traefik 体验小记

我有一个待办清单,里面记录了一些平常无意中看到,想要等有空的时候再去了解的技术名词。因为各种原因,这个清单大部分时候是记上去的多,移出来的少,导致它现在已经成了我的焦虑之源。是时候行动一下了!今天就从 Traefik 这个名字开始。

Traefik 是什么

去搜索了一些介绍,很多文章会把 Traefik 和 Nginx 摆在一起做对比。如果仅从代理服务(Proxy Service)的角度来衡量,两者的确看起来很相似。但以我目前的了解来看,从功能的全面性方面来衡量,Nginx 明显更胜一筹。

举个简单的例子,现在要部署一个 PHP 应用,如果使用 Nginx,因为它提供了 FastCGI 模块,所以可以直接配合 PHP-FPM 来运行 PHP 应用。但 Traefik 至少目前还没有类似的功能。如果想在 Traefik 上部署 PHP 项目,至少就需要在项目外先包一层像 Nginx 这样的服务,然后再和 Traefik 进行连接。

如果把 Nginx 的用途列的更多一些,我相信这个差异会更大。所以我不认为 Traefik 和 Nginx 存在可比性,二者也不存在「完全的」可替代性。

那 Traefik 到底是什么?

我觉得官方文档的第一句话介绍的就很恰当:

traefik-architecture

Edge 什么的我还没整明白,但 Router 这个概念我熟。Traefik 提供的是应用级别的路由服务,如果套用微服务的架构,其实很像网关(Gateway)。

Traefik 用来做什么

既然是路由或网关服务,Traefik 的用途也就很明显了:针对多应用环境,提供统一的访问入口,把不同应用的请求高效传递到正确的应用服务上。

这个「高效」以我目前的发现主要体现在两点:

  1. 对容器化部署工具的原生支持。
  2. 配置参数的动态加载能力。

对于第一点主要是 Docker,不过从去年开始我把容器引擎给切换到了 Podman,所以这点目前暂时无法测试。下面主要体验下第二点,来看看 Traefik 的动态配置能力。关于 Podman,不熟悉的朋友可以看看这篇介绍的文章:

搭建一个服务

使用 Docker 来体验 Traefik 是最简单的选择。不过无碍,Traefik 提供了多种动态配置方式,比如使用 yaml 格式的文件配置。这里就使用 Podman 容器结合文件配置的方式来体验一下 Traefik 的动态配置能力。

第一步,把 Traefik 服务跑起来。这需要先创建一个 Traefik 主配置文件,内容如下:

providers:
  file:
    directory: /etc/traefik/config
    watch: true

上面的配置内容很简单,只是定义了一个基于文件(File-based)的动态配置项,directory 定义了动态配置文件目录,而 watch 表示监视目录中文件的变动。

把上面的配置保存为 traefik.yml,然后创建一个 config 目录,接下来开始第二步:启动 Traefik 服务。

使用 Podman 的启动命令如下:

podman run --rm -it -p 8000:80 \
  -v $PWD/config:/etc/traefik/config \
  -v $PWD/traefik.yml:/etc/traefik/traefik.yml \
  traefik

如果你熟悉 Docker 的启动命令,上面的启动参数应该也能看懂。就是把刚才的创建的配置文件和目录挂载到 Traefik 的启动容器,然后把容器内的 80 端口映射到主机的 8000 端口。

现在访问主机的 8000 端口,会返回 404 消息。

Screenshot

因为当前没有任何可供访问的服务。来进入第三步:启动可供访问的服务。

Traefik 刚好提供了一个可供测试的容器镜像,功能也很简单,通过 HTTP 协议发送请求后会显示来源 IP 地址。我就以这个镜像来作为示例。

podman run --rm -it -p 8080:80 traefik/whoami

访问一下本地 8080 端口,可以看到输出了一堆 IP 地址信息。

Screenshot

证明服务启动成功,接下来进入最后一步:让 Traefik 和刚刚启动的 IP 服务之间建立路由连接。

在刚才创建的 config 目录中新增一个 route.yml 文件,内容如下:

http:
  routers:
    to-ip-service:
      rule: "Path(`/ip`)"
      service: ip-service
  services:
    ip-service:
      loadBalancer:
        servers:
        - url: 'http://host.containers.internal:8080'

上面的配置创建了一个路由和一个服务。路由配置段的 rule 关键词定义了路由规则,只要访问路径是 /ip,就定位到 ip-service 服务。后面的 services 则定义了服务项目,主要配置就是最后的 url 项,表示当前服务的访问地址。host.containers.internal 是 Podman 容器的一个主机别名。

保存文件后,直接访问 Traefik 的服务地址:

curl localhost:8000/ip

可以看到,同样输出了 IP 信息。

Screenshot

证明从 Traefik 到应用之间的连接打通了。重要的是,刚刚只是在 config 目录中新增了一个配置文件,并没有对 Traefik 做重启操作。这就是 Traefik 的动态配置能力。

仓促的结尾

Traefik 对我的主要吸引力就是动态配置功能,在体验完这个功能之后,我就没有更多想深入了解的意愿了。这不是 Traefik 存在不足,而是以我目前的需求来说,它还没有可以发挥的空间。

如果换成我之前上班的环境,我对 Traefik 的兴趣会很大,而且很有可能会用它替换掉当时基于 Openresty 自研的微服务网关系统。而目前作为自由职业者,我还没有任何一个项目到了需要使用微服务架构的地步。目前使用的 Nginx,修改配置并需要重启的次数一年来都屈指可数,Traefik 简便易用的各种功能对我自然也就没有太大的欲望了。而且更重要的是以我目前的技术栈,即便使用 Traefik,还是无法替换掉 Nginx。硬上就属于是把简单的问题搞复杂了,所以先就这样吧。