前言:
最近在家里搞智能家居折腾homeassistant之类, 上班就看看k8s之类学习下新技能,烟台的技术比较落后,基本还都靠宝塔之类跑PHP,然后跑的代码CCRMEB也比较邪典, 商业化的php脚本部署基本都会遇到很大问题(后台安装之类代码基本不支持单独部署,还有些奇奇怪怪的静态资源引用的后台代码的静态资源)。
尝试把crmeb之类打了包, 碰到上面说的问题, 还要映射出一个静态目录来交给nginx,因为以后项目可能比较杂乱,配了半天头越来越大,因为用的docker swarm 用一个nginx来作为网关路由, 加上域名也比较杂acme容器也搞半天,各种项目的静态文件映射也很杂乱,要是有轻量化的ingress之类的东西就好了。
traefik:
Traefik 是一个开源的反向代理和负载均衡器,专为微服务架构和容器化应用而设计。它可以自动发现新服务,并根据配置进行智能的流量管理和路由。以下是 Traefik 的一些主要功能和特性:
- 自动服务发现:Traefik 能够与多种容器编排工具(如 Docker、Kubernetes、Mesos、Consul、Etcd 等)集成,自动发现新的服务并动态配置路由。
- 动态配置:支持基于标签和注解的动态配置,避免了手动配置的繁琐。
- 多协议支持:支持 HTTP、HTTPS、TCP 和 WebSocket 等多种协议,可以处理不同类型的流量。
- 负载均衡:提供多种负载均衡策略,如轮询(Round Robin)、权重(Weight)等,确保流量在服务实例之间均匀分布。
- 中间件支持:通过中间件(Middleware)提供功能扩展,如认证、速率限制、重写请求等。
- TLS 终止和证书管理:支持自动获取和管理 Let’s Encrypt 的 TLS 证书,并可以终止 TLS 连接。
- 仪表盘和监控:提供一个直观的 Web 仪表盘,用于实时查看服务状态和流量统计,同时支持与 Prometheus、Grafana 等监控工具集成。
- 高可用性:支持集群模式,确保在高可用环境下的可靠运行。
Traefik 非常适合用于现代的微服务架构,尤其是在使用容器技术的环境中,因为它能简化流量管理,减少手动配置,并自动适应动态变化的服务环境。
为什么选traefik:
traefik支持traefik-label,通过给容器挂label的方式配置路由规则(解决了杂乱项目配置网关痛点),支持证书管理通过acme可以轻松实现证书的配置(主打不折腾),自带一个面板可以清晰的看到路由走向。
注意: traefik专著网关不支持HTML类静态资源服务,需要挂载个nginx处理
开始折腾:
先用家里母鸡和这博客上的vps折腾。这台vps主要跑了个bitwarden和wordpress,因为没邪典php代码再跑,直接干掉nginx。
注意: 因为V3版本不能单独配置两个docker endpoint, 也就是说同时配置https和http双路由,规则会消失,不知道为什么试了很多方法也不行,所以干脆把80强制转向443,如果没证书不想这样做可以把middlewares规则单独放到docker service label里。
部署网关stack
version: "3.7"
services:
traefik:
image: traefik:v3.0
container_name: traefik
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--providers.swarm=true"
- "--certificatesresolvers.zerossl.acme.email=cyanprber@gmail.com" # 配置 ZeroSSL 邮箱
- "--certificatesresolvers.zerossl.acme.storage=/letsencrypt/acme.json" # 配置 ACME 存储文件
- "--certificatesresolvers.zerossl.acme.caserver=https://acme.zerossl.com/v2/DV90" # 配置 ZeroSSL ACME 服务器
- "--certificatesresolvers.zerossl.acme.httpchallenge.entrypoint=web" # 配置 验证选项
- "--certificatesresolvers.zerossl.acme.eab.kid=xxxx" # 配置 ZeroSSL EAB KID
- "--certificatesresolvers.zerossl.acme.eab.hmacencoded=xxxxx"
- "--log.level=INFO" # 设置日志级别
- "--accesslog=true" # 启用访问日志
- "--accesslog.filepath=/var/log/traefik/access.log" # 指定访问日志路径
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "/var/traefik_logs:/var/log/traefik" # 挂载日志目录
- "/root/docker/letsencrypt:/letsencrypt"
deploy:
labels:
- "traefik.enable=true" # 启用 Traefik 标签
- "traefik.http.routers.api.rule=Host(`traefik.cyanprobe.com`)" # 访问 Traefik 仪表板
- "traefik.http.routers.api.service=api@internal" # 使用内部 API 服务
- "traefik.http.routers.api.entrypoints=websecure" # 使用 HTTPS 入口点
- "traefik.http.routers.api.tls.certresolver=zerossl" # 使用 ZeroSSL 证书解析器
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https" # 因为V3版本不能单独配置两个docker endpoint
- "traefik.http.middlewares.https-redirect.redirectscheme.permanent=true"
placement:
constraints:
- node.role == manager
networks:
- traefik-net
networks:
traefik-net:
name: traefik-net
driver: overlay
attachable: true
部署其他服务:
version: "3.7"
networks:
traefik-net:
external: true
name: traefik-net
services:
mysql:
container_name: db
image: mysql
volumes:
- /root/docker/db_data:/var/lib/mysql
restart: always
ports:
- ":3306"
networks:
- traefik-net
environment:
MYSQL_ROOT_PASSWORD:xxxx
MYSQL_DATABASE: xxxx
MYSQL_USER: xxxx
MYSQL_PASSWORD: xxxx
deplay:
labels:
- "traefik.http.services.dummy-svc.loadbalancer.server.port=9999"
wordpress:
container_name: wordpress
depends_on:
- mysql
image: wordpress
volumes:
- /root/docker/wordpress_data:/var/www/html
restart: always
networks:
- traefik-net
environment:
WORDPRESS_DB_HOST: xxx
WORDPRESS_DB_USER:xxx
WORDPRESS_DB_PASSWORD:xxx
WORDPRESS_DB_NAME:xxx
deploy:
labels:
- "traefik.http.routers.wordpress-https.rule=Host(`cyanprobe.com`)||Host(`www.cyanprobe.com`)"
- "traefik.http.routers.wordpress-https.entrypoints=websecure"
- "traefik.http.routers.wordpress-https.tls.certresolver=zerossl"
- "traefik.http.services.wordpress-https.loadbalancer.server.port=80"
bitwarden:
image: vaultwarden/server
container_name: bitwardenrs
restart: always
ports:
- :80
- :3012
volumes:
- /root/docker/bw-data:/data
networks:
- traefik-net
environment:
SIGNUPS_ALLOWED: "false"
WEB_VAULT_ENABLED: "true"
WEBSOCKET_ENABLED: "true"
deploy:
labels:
# - "traefik.enable=false"
- "traefik.http.routers.bitwarden-https.rule=Host(`bitwarden.cyanprobe.com`)"
- "traefik.http.routers.bitwarden-https.entrypoints=websecure"
- "traefik.http.routers.bitwarden-https.tls.certresolver=zerossl"
- "traefik.http.services.bitwarden-https.loadbalancer.server.port=80"
遇到问题 翻下官网:
2024-06-14T02:18:08Z ERR error=“service \”xxx-agent\” error: port is missing” container=xxxx providerName=swarm
traefik.http.services.<service_name>.loadbalancer.server.port
Registers a port. Useful when the container exposes multiples ports.
Mandatory for Docker Swarm (see the section “Port Detection with Docker Swarm”).
- "traefik.http.services.myservice.loadbalancer.server.port=8080"
看了下官网说是traefik无法扫描到swarm上的端口,需要定义
https://github.com/traefik/traefik/issues/5732
原来是因为traefic默认swarm provider上的服务都是自动注册的,那么只需要随便添加一个路由,或者干脆不启用traefik
traefik.http.services.dummy-svc.loadbalancer.server.port=9999
看到这个还在讨论有人说要加50行…..
搞完效果: