百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

能更好集成容器的反向代理工具Traefik的简单使用

wptr33 2025-01-27 00:37 21 浏览

Traefik 与 Nginx 一样,也是一款优秀的反向代理工具,使用 go 语言开发,本文将介绍怎样用 Traefik 来实现多服务转发的需求。

需求

1、WebAPI 接口中有两大类业务,当然根据具体情况可以是若干类。例如:workflow 和 interface,分别代表流程平台和接口平台。

2、在集群部署模式下,可以根据不同的路由分配到不同的节点。例如:一共部署了 10 个节点,workflow 分布式到其中的 3 个节点,interface 分布式到其余的 7 个节点。

这种方式的好处就是对于只有单一技术栈的团队,在物理上可以将代码组织在一起,方便维护,但在逻辑上可以将不同的业务分开,实现动态扩展和弹性。

当然上面的需求使用 nginx 也可以很容易做到,但本文采用的是 Traefk ,先来看看 Traefk 和 nginx 的区别。

Traefik 和 Nginx 的区别

Traefik 和 Nginx 都是反向代理工具,但它们在设计和使用场景上存在一些区别。下面简要比较一下这两者:

  • Traefik 可以无须重启即可更新配置,Nginx 据说能做到(没有验证过)
  • Traefik 可以自动的服务发现与负载均衡,Nginx 需要借助一些第三方工具
  • Traefik 对 Docker、Kubernetes、Swarm 的支持更好
  • Traefik 有漂亮的 dashboard 界面
  • Traefik 在功能上没有 Nginx 丰富,网上资料、案例也比 Nginx 少
  • Traefik 性能比 Nginx 要差,但具体差别多大,还未验证

环境

  • Traefik:v3.0.0-rc2
  • 操作系统:macOS13.0
  • Docker:20.10.13

Traefik 简单示例

1、Traefik 使用 docker-compose 进行部署,部署前先创建一个 docker 网络:

docker network create traefik-net

2、创建一个 traefik-demo 的目录,目录中创建 docker-compose.yml 文件,用来构建一个 Traefik 容器。

version: "3"

services:
traefik:
image: traefik:v3.0.0-rc2
restart: always
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command:
- "--api=true"
- "--api.dashboard=true"
- "--api.insecure=true"
- "--entrypoints.http.address=:80"
- "--providers.docker=true"
labels:
- "traefik.http.routers.traefik-dashboard.entrypoints=http"
- "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.fw.com`)"
- "traefik.http.routers.traefik-dashboard.service=dashboard@internal"
- "traefik.http.routers.traefik-dashboard-api.entrypoints=http"
- "traefik.http.routers.traefik-dashboard-api.rule=Host(`traefik.fw.com`) && PathPrefix(`/api`)"
- "traefik.http.routers.traefik-dashboard-api.service=api@internal"
networks:
- traefik-net

networks:
traefik-net:
external: true
name: traefik-net
  • /var/run/docker.sock:/var/run/docker.sock:允许 Traefik 访问 Docker 守护进程,用于自动发现 Docker 服务,允许 Traefik 订阅 Docker 服务事件,来动态的添加或删除要对用户暴露的网络服务

  • --api=true:启用 Traefik API

  • --api.dashboard=true:启用 Traefik 的 Web UI

  • --api.insecure=true:允许不安全的 API 和 Web UI 访问

  • --entrypoints.http.address=:80:设置 HTTP 入口点在容器的 80 端口

  • --providers.docker=true:启用 Docker 作为服务提供者

通过在 Docker Labels 中添加了声明式的路由,分别将 Dashboard 的网页(路由名称 traefik-dashboard )和 API (路由名称 traefik-dashboard-api )注册在了我们创建的 http 网络入口上,用户就可以通过我们设置的域名来访问服务了。

  • traefik.http.routers.traefik-dashboard.entrypoints=http: 为 Traefik dashboard 设置入口点

  • traefik.http.routers.traefik-dashboard.rule=Host(traefik.fw.com):设置访问 Traefik dashboard 的主机规则

  • traefik.http.routers.traefik-dashboard.service=dashboard@internal:指定 Traefik dashboard 使用内部服务

  • traefik.http.routers.traefik-dashboard-api.entrypoints=http:为 Traefik API 设置入口点

  • traefik.http.routers.traefik-dashboard-api.rule=Host(traefik.fw.com) && PathPrefix(/api):设置访问 Traefik API 的主机和路径前缀规则。

  • traefik.http.routers.traefik-dashboard-api.service=api@internal:指定 Traefik API 使用内部服务。

3、上面的配置中有一个域名:traefik.fw.com ,这是我本地测试使用的域名,正式环境替换为真实域名即可。本地测试可以通过修改 hosts 文件的方式:

cd /etc/
sudo chmod 777 hosts
vi hosts

添加映射:

127.0.0.1 traefik.fw.com

4、在 traefik-demo 目中中执行 docker-compose up -d traefik 来构建 Traefik 服务,执行成功后,在浏览器中访问:traefik.fw.com ,可以看到如下界面:

可以看到 Services 有 10 个,其中包含了我本机上部署的其他的 docker 容器。

5、使用官方的测试容器来进行测试,修改 docker-compose.yml 文件,在下面添加如下内容:

 whoami:
image: containous/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.fw.com`)"
- "traefik.http.services.whoami.loadbalancer.server.port=80"
networks:
- traefik-net

6、执行 docker-compose up -d whoami 进行构建,构建成功后,命令行执行:curl -H Host:whoami.fw.com http://127.0.0.1

7、现在使用命令:docker-compose up -d --scale whoami=2 对 whoami 服务进行扩容,创建成功后,再使用:curl -H Host:whoami.fw.com http://127.0.0.1 进行测试,会发现已经在两个容器间进行负载了:

使用 WebAPI 示例进行验证

1、使用 C# 编写 WebAPI 接口,创建两个 Controller 模拟两个不同的业务,InterfaceCenterController 和 WorkflowController ,代码如下:

 [ApiController]
[Route("[controller]")]
public class WorkflowController : ControllerBase
{
[HttpGet()]
public string Test()
{
string ip = Request.HttpContext.Connection.LocalIpAddress.MapToIPv4().ToString() + ":" +
Request.HttpContext.Connection.LocalPort.ToString();

return $"workflow server,{ip}";
}
}

[ApiController]
[Route("[controller]")]
public class InterfaceCenterController : ControllerBase
{
[HttpGet()]
public string Test()
{
string ip = Request.HttpContext.Connection.LocalIpAddress.MapToIPv4().ToString() + ":" +
Request.HttpContext.Connection.LocalPort.ToString();
return $"interfaceCenter server,{ip}";
}
}

2、代码写好后,进行发布,在发布目录中创建 Dockerfile 文件,内容如下:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
COPY . /app
WORKDIR /app
EXPOSE 80/tcp

ENTRYPOINT ["dotnet", "ApiDemo.dll"]

3、执行下面命令进行镜像构建:

docker build -t apidemo .

4、修改 traefik-demo 目录中的 docker-compose.yml 文件,在下面添加如下内容:

 apidemo:
image: apidemo
labels:
- "traefik.enable=true"
- "traefik.http.routers.apidemo.entrypoints=http"
- "traefik.http.routers.apidemo.rule=Host(`apidemo.fw.com`) && PathPrefix(`/workflow`)"
- "traefik.http.services.apidemo.loadbalancer.server.port=80"
networks:
- traefik-net

apidemo-1:
image: apidemo
labels:
- "traefik.enable=true"
- "traefik.http.routers.apidemo-1.entrypoints=http"
- "traefik.http.routers.apidemo-1.rule=Host(`apidemo.fw.com`) && PathPrefix(`/interfacecenter`)"
- "traefik.http.services.apidemo-1.loadbalancer.server.port=80"
networks:
- traefik-net
  • 在 apidemo 中配置了路由 PathPrefix(/workflow) 表示只接受工作流平台的业务
  • 在 apidemo-1 中配置了路由 PathPrefix(/interfacecenter) 表示只接受接口平台的业务

5、在上面 labels 的路由配置中使用了 apidemo.fw.com 的域名,同样,这个域名也需要配置到 hosts 文件中:

127.0.0.1 traefik.fw.com apidemo.fw.com

6、执行下面的命令进行容器的构建:

docker-compose up -d apidemo
docker-compose up -d apidemo-1

7、使用 Postman 进行测试:

  • 当访问 workflow 路由时,返回的容器 IP 一直都是 172.18.0.2
  • 当访问 interfacecenter 路由时,返回的容器 IP 一直都是 172.18.0.4


相关推荐

Linux文件系统操作常用命令(linux文件内容操作命令)

在Linux系统中,有一些常用的文件系统操作命令,以下是这些命令的介绍和作用:#切换目录,其中./代表当前目录,../代表上一级目录cd#查看当前目录里的文件和文件夹ls#...

别小看tail 命令,它难倒了技术总监

我把自己以往的文章汇总成为了Github,欢迎各位大佬star...

lnav:基于 Linux 的高级控制台日志文件查看器

lnav是一款开源的控制台日志文件查看器,专为Linux和Unix-like系统设计。它通过自动检测日志文件的格式,提取时间戳、日志级别等关键信息,并将多个日志文件的内容按时间顺序合并显示,...

声明式与命令式代码(声明模式和命令模式)

编程范式中的术语和差异信不信由你,你可能已经以开发人员的身份使用了多种编程范例。因为没有什么比用编程理论招待朋友更有趣的了,所以这篇文章可以帮助您认识代码中的流行范例。命令式编程命令式编程是我们从As...

linux中的常用命令(linux常用命令和作用)

linux中的常用命令linux中的命令统称shell命令shell是一个命令行解释器,将用户命令解析为操作系统所能理解的指令,实现用户与操作系统的交互shell终端:我们平时输入命令,执行程序的那个...

提高工作效率的--Linux常用命令,能够决解95%以上的问题

点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf...

如何限制他人操作自己的电脑?(如何控制别人的电脑不让发现)

这段时间,小猪罗志祥正处于风口浪尖,具体是为啥?还不知道的小伙伴赶紧去补一下最近的娱乐圈八卦~简单来说,就是我们的小罗同事,以自己超强的体力,以及超强的时间管理能力,重新定义了「多人运动」的含义,重新...

最通俗易懂的命令模式讲解(命令模式百科)

我们先不讲什么是命令模式,先通过一个场景来引出命令模式,看看命令模式能解决什么样的问题。现在有一个渣男张三,他有还几个女朋友,你现在是不是还是单身狗,你就说你气不气?然后他需要每天分别叫几个女朋友起床...

互联网大厂后端必看!Spring Boot 中Runtime执行与停止命令?

你是否曾在使用SpringBoot开发项目时,遇到需要执行系统命令的场景?比如调用脚本进行文件处理,又或是启动外部程序?很多后端开发人员会使用Processexec=Runtime.get...

Linux 常用命令(linux常用的20个命令面试)

日志排查类操作命令...

Java字节码指令:if_icmpgt(0xA3)(java字节码使用的汇编语言)

if_icmpgt是Java字节码中的一条条件跳转指令,其全称是"IfIntegerCompareGreaterThan"。它用于比较两个整数值的大小。如果栈顶的第一个...

外贸干货|如何增加领英的曝光量和询盘

#跨境电商#...

golang执行linux命令(golang调用shell脚本)

需求需要通过openssl生成rsa秘钥,然后保存该秘钥。代码实例packagemainimport("io/ioutil""bytes"&...

LINUX磁盘挂载(linux磁盘挂载到windows)

1、使用root用户查看磁盘挂载情况:fdisk-l2、使用df查看当前磁盘挂载情况,根据和fdisk-l的结果进行对比,查看还有那些磁盘未使用3、挂载:mount磁盘挂载路径...

Linux命令学习——nl命令(linux ln命令的使用)

nl命令主要功能为每一个文件添加行号,每一个输入的文件添加行号后发送到标准输出。当没有文件或文件为-时,读取标准输入...