Traefik 2 群晖硬核攻略

traefik.png

家中群晖nas使用docker运行各种各样的应用也有几年了,多半是自用,同时软路由启动着DDNS自动解析域名的服务。前几天,想和朋友共享gitea,创建一个私有的git服务器,决定再次维护一次。

阶段一:家中的各种docker容器均各自映射了各自的端口,通过路由器端口映射映射至互联网。

缺点:1. 端口混乱难以记住 2. 缺乏统一日志记录。

阶段二:我又创建了一个docker内部网,在总入口启动了一个nginx容器,同时把各应用加入到docker内部网中,将应用的端口统一,通过nginx配置虚拟主机,路由到不同的应用下,后端地址依赖于容器的主机名解析。

缺点:1. 容器变动起来十分麻烦,无法轻松的增加容器副本的负载均衡;2. nginx重启强制依赖于各服务的运行状态,否则会启动失败;3. 繁琐的配置懒得手动申请SSL。

阶段三:因路由器的配置问题,上行速度无法跑满,去掉了硬件路由器的方式,在群晖nas上启动了lede软路由,软路由作为DMZ区域,所有出口流量走软路由,速度极大的提升了,北京地区ms级别极速打开,上行速度跑满,但上述问题,依然繁琐。

我的VPS用过一段时间的caddy,可基于acme自动注册SSL、续签SSL。考虑到容器时代可能会自由启停增加容器副本,nginx增改配置文件的方式,在服务配置、域名配置、SSL配置方面,显得传统而又繁琐

为了彻底改变这种落后的机制,刚好在研究k8s的时候,我发现了traefik,刚好能满足我的需求。然而网上大部分内容均为k8s相结合的ingress-traefik,虽然k8s确实香,但家用nas基本上和k8s扯不上关系也不需要,网上仅有一篇文章描述群晖如何安装traefik1,决定分享一下我容器化部署taefik2的填坑经验。

Traefik

traefik-architecture.png

Traefik 是一个开源的可以使得服务发布变得轻松有趣的边缘路由器。它负责接收你系统的请求,然后使用合适的组件来对这些请求进行处理。

使用 Traefik,不需要维护或者同步一个独立的配置文件:因为一切都会自动配置,实时操作的(无需重新启动,不会中断连接)。使用 Traefik,你可以花更多的时间在系统的开发和新功能上面,而不是在配置和维护工作状态上面花费大量时间。

除了众多的功能之外,Traefik 的与众不同之处还在于它会自动发现适合你服务的配置。当 Traefik 在检查你的服务时,会找到服务的相关信息并找到合适的服务来满足对应的请求。

Traefik 部署

前提:

  1. 群晖打开了SSH
  2. 安装了docker套件
  3. 默认磁盘目录是volume1

SSH登录至群晖,执行如下命令:

cd /volume1/docker/
mkdir traefik
cd traefik
mkdir config
mkdir ssl
mkdir logs
# 创建traefik专属网络
docker network create traefik
touch docker-compose.yml

亮出我们的利器,通过docker-compose启动,编辑刚刚创建的yml文件 docker-compose.yml

version: '3.7'

services:

  traefik:
    container_name: traefik
    image: traefik:v2.1.3
    restart: always
    environment:
      - CF_API_EMAIL=CLOUDFLARE登录邮箱
      - CLOUDFLARE_DNS_API_TOKEN=CLOUDFLARE创建的DNS TOKEN
      - CLOUDFLARE_ZONE_API_TOKEN=CLOUDFLARE创建的API TOKEN
    ports:
      - "52080:80"
      - "52443:443"
      - "52022:22"
    networks:
      - traefik
    command: traefik --configFile /etc/traefik.toml
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./ssl/:/data/ssl/:rw
      - ./traefik.toml:/etc/traefik.toml:ro
      - ./config/:/etc/traefik/config/:ro
      - ./logs/:/data/logs/:rw
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider --proxy off localhost:8080/ping || exit 1"]

networks:
  traefik:
    external: true

值得注意的是,因为运营商屏蔽了2244380端口,于是我使用520225244352080做映射替代,如未被屏蔽,请忽略。

为了自动申请SSL证书,提交成功率,我才用DNS Challenge的方式校验有效性,因此需Cloudflare的环境信息,如果你的域名没有配置Cloudflare解析,可以根据这篇文章置换相应变量。

ddns.png

同时,我们在traefik目录下创建traefik.toml文件,作为全局配置文件,一般不会有改动。

[global]
  checkNewVersion = false
  sendAnonymousUsage = false

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

[api]
  dashboard = true
  insecure = true

[ping]

[accessLog]
  filePath = "/data/logs/access.log"
  bufferingSize = 100
  format = "json"
  [accessLog.filters]
    minDuration = "10ms"
[providers]
  [providers.docker]
    watch = true
    exposedByDefault = false
    endpoint = "unix:///var/run/docker.sock"
    swarmMode = false
    useBindPortIP = false
    network = "traefik"
  [providers.file]
    watch = true
    directory = "/etc/traefik/config"
    debugLogGeneratedTemplate = true

[entryPoints]
  [entryPoints.http]
    address = ":80"
  [entryPoints.https]
    address = ":443"
  [entryPoints.ssh]
    address = ":22"

[certificatesResolvers.my.acme]
  email = "CLOUDFLARE登录邮箱"
  storage = "/data/ssl/acme.json"
  [certificatesResolvers.my.acme.dnsChallenge]
    resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
    provider = "cloudflare"
    delayBeforeCheck = 30

随后,进入config目录。

创建dashboard.nas.yfgeek.com.toml文件,作为traefik展示面板的配置文件,因为相对固化,所以采用文件配置文件的形式,traefik支持文件加载配置。

[http.middlewares.dash-compress.compress]
[http.middlewares.dash-auth.basicAuth]
  users = [
    "test:$apr1$ux2tmr06$Qz5r/BNEfzdxriR/0o30Z1",
  ]

[http.routers.dashboard]
  rule = "Host(`dashboard.nas.yfgeek.com`)"
  entrypoints = ["http"]
  service = "dashboard@internal"
  middlewares = ["dash-auth", "dash-compress"]

[http.routers.api]
  rule = "Host(`dashboard.nas.yfgeek.com`) && PathPrefix(`/api`)"
  entrypoints = ["http"]
  service = "api@internal"
  middlewares = ["dash-auth", "dash-compress"]

[http.routers.ping]
  rule = "Host(`dashboard.nas.yfgeek.com`) && PathPrefix(`/ping`)"
  entrypoints = ["http"]
  service = "ping@internal"
  middlewares = ["dash-auth", "dash-compress"]

这个文件中,我们设置了一个用于验证的中间件,进入网站之前会默认进行验证,密码是htpasswd生成规则,例子中用户名是test,密码是test,如需定制,可到这个网站生成密码

全部创建好后,目录结构如下:

|____config
| |____dashboard.nas.yfgeek.com.toml
|____ssl
|____docker-compose.yml
|____traefik.toml

确认无误,我们使用启动大法,执行如下命令。

docker-compose up -d
docker container logs traefik -f

不出意外,服务即将启动成功,可以看到日志,如果有问题就见招拆招即可。

dashboard.png

Gitea 部署

traefik启动好后,我们还没有应用接入,接下来,整理一下原有的gitea容器,将其写为docker compose文件,同理,在docker目录下新建一个gitea目录。

cd /volume1/docker/
mkdir gitea
cd gitea
touch docker-compose.yml

docker-compose.yml参考如下:

version: '3'

services:

  gitea:
    container_name: gitea
    image: gitea/gitea:latest
    restart: always
    environment:
      - USER_UID=1000
      - USER_GID=1000
    networks:
      - traefik
    expose:
      - 3000
      - 22
    labels:
      - traefik.enable=true
      # 设置HTTP强制跳转HTTPS 中间件
      - traefik.http.middlewares.redirect-https.redirectscheme.scheme=https
      - traefik.http.middlewares.redirect-https.redirectscheme.port=52443

      # HTTP配置
      - traefik.http.routers.gitea-web.rule=Host(`git.nas.yfgeek.com`,`git.yfgeek.com`)
      - traefik.http.routers.gitea-web.entrypoints=http
      - traefik.http.routers.gitea-web.service=gitea-web
      - traefik.http.routers.gitea-web.middlewares=redirect-https

      # HTTPS配置
      - traefik.http.routers.gitea-web-secure.rule=Host(`git.nas.yfgeek.com`,`git.yfgeek.com`)
      - traefik.http.routers.gitea-web-secure.entrypoints=https
      - traefik.http.routers.gitea-web-secure.service=gitea-web
      - traefik.http.routers.gitea-web-secure.tls=true
      - traefik.http.routers.gitea-web-secure.tls.certresolver=my
      - traefik.http.services.gitea-web.loadbalancer.server.port=3000

      # SSH配置
      - traefik.tcp.routers.gitea-ssh.rule=HostSNI(`*`)
      - traefik.tcp.routers.gitea-ssh.entrypoints=ssh
      - traefik.tcp.routers.gitea-ssh.service=gitea-ssh
      - traefik.tcp.services.gitea-ssh.loadbalancer.server.port=22
    volumes:
      - /volume1/docker/gitea:/data


networks:
  traefik:
    external: true

traefik是通过增加label的方式,自动注册服务的,无需任何配置文件,实时生效,如果容器挂了,转发关系自动失效。配置文件中,利用redirectscheme的中间件方式,增加了HTTP强制跳转至HTTPS。

针对HTTPS的访问方式,traefik会自动注册访问域名rule=Host(`git.nas.yfgeek.com`,`git.yfgeek.com`)的两个域名的,因此一定要确认无误。

同时,为了实现后续的SSL自动签发、host自动注册,我在DDNS中增加了域名的泛解析配置。

确认无误后,执行如下命令

docker-compose up -d

这里有一个小坑,值得注意,acme申请证书需要一段时间,如果配置信息有误,是不会申请成功的。因此需要查看下traefik的日志。

docker container logs traefik -f

找到问题见招拆招,如果是权限等问题,exec进入容器,通过chmod命令解决即可。

随后访问域名的HTTP(http://git.yfgeek.com:52080),将被强制跳转至HTTPS(https://git.yfgeek.com:52443),即可看到SSL证书自动申请、配置成功。与此同时,基于TCP的SSH服务也被顺利转发。

gitea.png

反过来,我们查看dashboard,即可看到gitea的服务已经成功在dashboard中注册了,并且一切顺利。


gitea2.png
gitea3.png

类似的,如果后续增加新的docker应用,可直接编辑docker compose文件,增加label,配置域名,直接解析、自动申请SSL,方便极了,生产力得到了极大的提升。

下一期我将讲讲如何traefik+prometheus+grafana,实现自动采集数据,归集日志,构建网站监控系统,欢迎持续关注。

参考文章

  1. https://juejin.cn/post/6844904053722316813
  2. https://soulteary.com/2020/02/01/configure-traefik-v2-based-web-server.html
  3. https://www.qikqiak.com/traefik-book/
  4. https://doc.traefik.io/traefik/master/https/acme/
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容