使用 Traefik 作为服务网关

前一阵子在折腾服务器的时候,偶然读到了苏洋老师的文章,了解了 Traefik,搞明白了该怎样用 Docker 部署服务。随后,我照猫画虎搭起来了 Traefik 和 Docker,并成功部署了 MediaWiki 和一个静态网站。

这篇文章记录一下搭建 Traefik 的过程,并部署一个简单的静态网站。

什么是 Traefik

Traefik 是一个开源的边缘路由软件,能够自动发现服务,方便地实现反向代理、负载均衡。

具体来说,它可以接收系统收到的请求,并将它们分派到合适的服务去处理。

安装配置 Traefik

我采用了裸机部署 Traefik 的方案,而没有将 Traefik 部署在 Docker 容器中。主要考虑到我是用的是单体云主机,裸机部署服务网关可以获得更好的性能。

安装

我们这里选择二进制应用文件安装的方式。在 Traefik 的 Github 仓库里找到编译好的二进制文件,下载解压之后放入 /usr/bin 文件夹中:

wget https://github.com/traefik/traefik/releases/download/v2.5.4/traefik_v2.5.4_linux_amd64.tar.gz
tar zxvf traefik_v2.5.4_linux_amd64.tar.gz
mv traefik /usr/bin/

然后验证系统能否找着 Traefik,并检查 Traefik 版本:

which traefik
traefik version

我这里使用的 Traefik 版本是:

Version:      2.5.4
Codename:     livarot
Go version:   go1.17.3
Built:        2021-11-08T17:41:41Z
OS/Arch:      linux/amd64

配置

首先创建 Traefik 配置和值日的目录:

midir -p /data/basic/traefik/{logs,conf}

这一步主要是参照苏洋老师的做法,实际上将配置文件放在 /etc/traefik/~/.config 等文件夹就可以,不一定要单独建立文件夹。

然后参照文档,编写配置文件 traefik.toml,放在 /data/basic/traefik/ 目录下:

[global]
  checkNewVersion = false       # 禁用检查新版本
  sendAnonymousUsage = false    # 禁用发送匿名监测记录

[entryPoints]
  [entryPoints.http]            # http 的默认入口
    address = ":80"
  [entryPoints.https]           # https 的默认入口
    address = ":443"
  [entryPoints.http1]           # 额外的 http 入口
    address = ":8088"
  [entryPoints.http2]           # 额外的 http 入口
    address = ":8089"

[providers]                     # 后端服务提供平台
  [providers.docker]            # docker
    exposedByDefault = false    # 默认不暴露容器,除非其设置了 traefik.enable=true
    network = "traefik"         # 连接容器使用的 Docker 网络
  [providers.file]              # 配置文件
    watch = true                # 监视文件变化
    directory = "/data/basic/traefik/conf"

[api]
  dashboard = true              # 启用看板
  insecure = false              # 禁用 8080 端口的看板入口
  debug = false

[ping]                          # 允许 ping

[log]
  level = "INFO"
  format = "common"
  filePath = "/data/basic/traefik/logs/traefik.log"

[accessLog]
  filePath = "/data/basic/traefik/logs/access.log"
  bufferingSize = 100

写配置文件的时候,主要还是要看原始文档。有不少配置项采用默认值就完全 OK。

启动 Traefik,验证配置:

traefik --configFile /data/basic/traefik/traefik.toml

访问服务器的 IP,如果看到 404 page not found,说明已经成功了。

守护进程

在容器环境中保持应用持续运行只需要一句 --restart=always,但在裸机环境下的事情会略微麻烦一些。

这里采用 supervisor 来担当守护进程,用 APT 安装:

sudo apt install supervisor

然后给 Traefik 编写进程守护配置文件,保存到 /etc/supervisor/conf.d/traefik.conf

[program:traefik]
command=traefik --configFile /data/basic/traefik/traefik.toml
user=root
autostart=true
startsecs=3
startretries=100
autorestart=true
stderr_logfile=/data/basic/traefik/logs/supervisor-traefik-error.log
stderr_logfile_maxbytes=50MB
stderr_logfile_backups=10
stdout_logfile=/data/basic/traefik/logs/supervisor-traefik-access.log
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=10

重启进程守护服务,可以看到 Traefik 已经开始运行。

service supervisor restart
ps -ef | grep traefik

此后,可以用下面的这些命令来启动、停止、重启 Traefik:

sudo supervisorctl start traefik
sudo supervisorctl stop traefik
sudo supervisorctl restart traefik

部署静态网站

这里采用 Apache HTTP 服务器的官方镜像 httpd 部署一个静态网站,来展示透过 Traefik 部署 Web 服务的流程。

准备工作目录

首先创建一个应用的工作目录 homepage,然后将静态网站的文件放在 www 子文件夹下:

mkdir homepage
mkdir homepage/www

编写容器编排文件

为静态网站应用编写一个 Docker compose 的编排文件:

version: "3"

services:
  homepage:
    image: ${HTTP_IMAGE}
    restart: always
    labels:
      - traefik.enable=true
      - traefik.http.routers.homepage.rule=Host(`${HTTP_DOMAINS}`)
      - traefik.http.routers.homepage.entrypoints=${HTTP_ENTRY}
    networks:
      - traefik
    expose:
      - 80
    volumes:
      - ./www:/usr/local/apache2/htdocs/

networks:
  traefik:
    external: true

这个文件主要做了这么几件事情:

  • 指定服务名称和镜像,并保持持续运行;
  • 通过 labels 属性通知 Traefik 该应用的路由规则;
  • 暴露 80 端口,并挂载网页文件。

为了方便修改,这里参数化了部分内容,将之放到 .env 文件中:

HTTP_IMAGE=httpd:2.4-alpine
HTTP_DOMAINS=www.ceba.tech
HTTP_ENTRY=http, http1

然后工作目录执行命令,启动应用:

docker-compose up -d

如果你修改了编排文件,可以重复执行上面的命令,Docker compose 会自动更新容器配置。

在这个应用中,我们实际上只用到了一个容器,上述的编排文件完全可以转化成单条 Docker 命令。但是包含如此多参数的 Docker 命令一定又臭又长,使用结构化的编排文件反而更加方便。

关于自定义配置的补充

对于静态网站来说,使用 httpd 的默认配置应当是足够了。但如果需要,我们还可以对 apache2 做进一步的配置。

首先,执行下面的命令,获取一份配置文件:

docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > my-httpd.conf

然后,修改编排文件,将自定义配置文件挂载进去:

services:
  homepage:
    volumes:
      - ./www:/usr/local/apache2/htdocs/
      - ./my-httpd.conf:/usr/local/apache2/conf/httpd.conf

后记

搭好服务快一个月了,这才动笔记一记搭建的过程。

之后还会写一篇文章,讲讲 MediaWiki 部署的过程和踩的坑。希望别咕。

最近可能会尝试以容器化的方式搭建一个 Cloudlog。希望别咕。

参考文献

本作品采用知识共享署名 4.0 国际许可协议进行许可。
本文链接:https://blog.ceba.tech/2021/12/Treafik-as-gateway/