Traefik--云原生下的Nginx替代品

本文详细介绍了Traefik在Docker和Kubernetes环境中的优势,包括自动发现服务变化、动态负载均衡、跨docker-compose负载示例以及可观测性配置。重点展示了如何通过Traefik实现服务间的负载均衡,并配置Prometheus监控。

不可否认,Nginx作为老牌的负载软件经久不衰,依然是绝大多数情况下的不二选择,但是在云原生时代,Nginx却显得力有不逮。

由于微服务架构以及Docker技术和K8s编排工具最近几年才开始逐渐流行,所以一开始的反向代理服务器比如Nginx、Apache等并未提供其支持。所以才会出现Ingress Controller这种东西来做k8s和Nginx之间的衔接。而Traefik天生就提供了Docker、k8s的支持,也就是说traefik本身就能跟k8s api交互感知后端变化,因此在使用traefik时,Ingress controller和nginx这类工具就失去了存在的意义。

在目前我们使用Docker-Compose编排所有微服务的阶段,Traefik能够依赖自身的特性,自动发现服务的变更,动态调整自身的负载均衡配置。

一、示例

下面我们通过一个示例,来展现traefik在容器化时代的过人之处。

version: "3.8"

services:

  traefik:
    image: traefik:v2.4.8
    ports:
      - 18181:80
      - 18182:8080
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"  # trafik通过docker.sock监控后端变化
    command:
      - "--api.insecure=true"   # 开启不安全接口方便本地调试
      - "--api.dashboard=true"   # 开启Dashboard便于调式,生产环境建议关闭
      - "--accesslog=true"   # 开启日志
      - "--providers.docker=true"  # 后端使用Docker作为工作模式
      - "--entrypoints.testapi.address=:80"  # 新建一个名为 testapi 的入口监听80端口


  whoami:
    image: containous/whoami
    labels:
      - "traefik.http.routers.app.rule=Host(`192.168.1.178`)"  # 用户使用 localhost 访问时,此服务进行响应
      - "traefik.http.routers.app.entrypoints=testapi"     # 入口为 testapi

docker-compoes启动 docker-compose up --scale whoami=3后,使用 curl 进行访问 curl http://192.168.1.178:18181/, 得到的响应如下:

Hostname: 21274e83b339
IP: 127.0.0.1
IP: 172.30.0.2
RemoteAddr: 172.30.0.3:56066
GET / HTTP/1.1
Host: 192.168.1.178:18181
User-Agent: curl/7.64.1
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 10.100.1.7
X-Forwarded-Host: 192.168.1.178:18181
X-Forwarded-Port: 18181
X-Forwarded-Proto: http
X-Forwarded-Server: 89a1ed50d8e4
X-Real-Ip: 10.100.1.7

多次访问,每次响应的Hostname都是不同的,说明traefik实现了请求在多个whoami容器之间进行负载。

如果使用多级路径进行路由判断可以添加如下配置

- "traefik.http.routers.app.rule=Path(`/test`)"  # 指定/test路径才响应

此时我们需要使用 http://192.168.1.178:18181/test 才能获得正确响应。

二、跨 docker-compose 负载演示

上面的内容都是基础性的配置演示,下面简单介绍一下在docker-compose中更有意思的配置。

我们在另一个 docker-compose 中启动一个新的 whoami 服务

version: "3.8"
services:
  whoami2:
    image: containous/whoami
    labels:
      - "traefik.http.routers.1.rule=Host(`192.168.1.178`)"  # 用户使用 localhost 访问时,此服务进行响应
      - "traefik.http.routers.1.rule=Path(`/test2`)"
      - "traefik.http.routers.1.entrypoints=testapi"     # 入口为 testapi

当我们使用 http://192.168.1.178:18181/test 访问时响应的是第一个docker-compse中的服务,使用http://192.168.1.178:18181/test2访问时,响应的则是第二个docker-compose中的服务。

三、负载均衡演示

那么如果想通过 /test 路径实现跨docker-compose中的两个服务之间的负载呢?

version: "3.8"

services:

  traefik:
    image: traefik:v2.4.8
    ports:
      - 18181:80
      - 18182:8080
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"  # trafik通过docker.sock监控后端变化
    command:
      - "--api.insecure=true"   # 开启不安全接口方便本地调试
      - "--api.dashboard=true"   # 开启Dashboard便于调式,生产环境建议关闭
      - "--accesslog=true"   # 开启日志
      - "--providers.docker=true"  # 后端使用Docker作为工作模式
      - "--entrypoints.testapi.address=:80"  # 新建一个名为 testapi 的入口监听80端口


  whoami:
    image: containous/whoami
    labels:
      - "traefik.http.routers.app.entrypoints=testapi"     # 入口为 testapi
      - "traefik.http.routers.app.rule=Host(`192.168.1.178`)"  # 用户使用 localhost 访问时,此服务进行响应
      - "traefik.http.routers.app.rule=Path(`/test`)"
      - "traefik.http.services.whoami.loadbalancer.server.scheme=http"
      - "traefik.http.services.whoami.loadbalancer.server.port=80"


  whoami_2:
    image: containous/whoami
    labels:
      - "traefik.http.services.whoami.loadbalancer.server.scheme=http"
      - "traefik.http.services.whoami.loadbalancer.server.port=80"

此时使用curl http://192.168.1.178:18181/test 会有2个容器分别进行负载响应,从此以后,容器内的服务变更都不在需要更新nginx配置文件了

五、可观测性

在Traefik-2.x的生态里,将可观测性分成了如下几部分

  • 服务日志: Traefik 进程本身相关的操作日志
  • 访问日志: 由Traefik接管的代理服务的访问日志
  • Metrics: Traefik 提供的自身详细的metrics数据
  • Tracing: Traefik也提供了链路追踪相关接口,可用来可视化分布式或微服务中的调用情况

我们主要说明Metrics中的监控能力,首先开启Promethus数据

- "--metrics.prometheus=true"
- "--metrics.prometheus.buckets=0.100000, 0.300000, 1.200000, 5.000000"

配置prometheus的监控任务

  # 监控面板: 11462
  - job_name: "Traefik"
    static_configs:
      - targets: ["192.168.1.178:18182"]

可观测到如下面板
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iePewpEG-1624432821951)(./1619509537326.png)]

六、其它问题

如何解决CORS跨域问题: https://doc.traefik.io/traefik/middlewares/headers/
如何使用HTTPS: https://doc.traefik.io/traefik/https/overview/

更多配置、更多用法请自行查询相关文档!

<think>嗯,用户询问ingress是否能查询服务注册与发现中心。这是个关于Kubernetes架构的实践问题,需要结合之前提供的引用内容展开分析。 先看引用材料的关键点:引用[1]明确指出Ingress控制器核心职能是"外部流量路由",引用[2]详细说明服务注册发现是Eureka这类组件的职责,引用[3]展示Ingress配置项完全不涉及服务查询,引用[4]则强调Istio的服务发现基于Kubernetes原生机制。这些引用共同表明——服务注册发现属于基础设施层,而Ingress属于流量入口层。 用户可能混淆了服务网格(Service Mesh)和Ingress的概念。从技术分层看,服务注册中心(如Consul/Eureka)属于服务治理层,负责记录服务实例状态;Ingress则是第七层流量网关,依赖下游服务列表进行路由。当用户问"能否查询",实际需要的是动态服务发现能力,这恰是服务网格(如Istio)的专长。 考虑到用户的技术背景,补充说明实践方案会更有帮助。比如在Kubernetes中,Ingress通常通过Service对象间接感知服务,而Service本身已经抽象了Pod变化。如果要实现用户设想的"直接查询注册中心",需要自定义控制器同步注册中心数据到Ingress规则,但这会破坏基础设施的解耦性。 最后注意到用户引用的材料跨度较大(Eureka/Istio/K8s原生),可能在微服务技术选型阶段。回答时需要强调标准方案与扩展方案的边界,避免误导用户走向复杂架构。 </think>根据Kubernetes架构设计和服务发现机制的原理,Ingress控制器**本身不具备直接查询服务注册与发现中心的能力**,但可通过间接方式与服务发现协同工作。以下是关键分析: --- ### **1. Ingress的核心职责(无法直接查询注册中心)** - **流量路由**:Ingress控制器依据`Ingress`资源定义的规则(主机名、路径等)转发HTTP/HTTPS流量到后端Service(如`my-service:80`)[^1] - **依赖Service对象**:Ingress规则中的`backend`字段仅指向Kubernetes **Service名称**,而非直接对接注册中心(如Eureka/Nacos) - **无服务发现接口**:标准Ingress控制器(Nginx/HAProxy/Traefik)未内置服务注册中心查询逻辑[^4] --- ### **2. 服务注册与发现的运作层级** - **服务注册中心**(如Eureka)职责: ✅ 记录微服务实例的IP、端口、健康状态 ✅ 提供API供消费者查询可用实例(如Spring Cloud客户端)[^2] - **Kubernetes原生机制**: ✅ Service通过`Endpoints`自动关联Pod IP(内置服务发现) ✅ Ingress只需声明Service名称,由kube-proxy实现负载均衡[^4] --- ### **3. 协同工作的间接方式** 虽然Ingress不直接查询注册中心,但可通过以下方案集成: #### **方案1:通过Service抽象层** ```mermaid graph LR A[外部流量] --> B(Ingress控制器) B --> C{Kubernetes Service} C --> D[注册中心的服务实例] ``` - **流程**: Ingress → Kubernetes Service → Service背后的Pod(已注册到服务中心) - **优势**:符合K8s设计,无需改造Ingress #### **方案2:定制化Ingress控制器** - **扩展Controller**:修改源码使Ingress直接从注册中心拉取实例(如集成Consul API) - **动态更新**:当注册中心实例变化时,主动刷新Ingress路由规则 - **代价**:需自行维护控制器,违反Kubernetes松耦合设计[^1][^4] #### **方案3:服务网格代理(如Istio)** ```yaml # Istio VirtualService 替代部分Ingress功能 apiVersion: networking.istio.io/v1alpha3 kind: VirtualService spec: hosts: ["example.com"] http: - route: - destination: host: my-service # 自动关联服务注册信息 ``` - **原理**:Sidecar代理(Envoy)直连服务注册中心,实现动态服务发现[^4] - **Ingress替代品**:`Istio IngressGateway` + `VirtualService`可覆盖Ingress能力 --- ### **总结** | **能力** | 是否支持 | 说明 | |-------------------------|------------------|--------------------------| | 直接查询注册中心 | ❌ 否 | 超出Ingress设计范畴 | | 通过Service间接路由 | ✅ 是 | 标准Kubernetes方案 | | 定制控制器实现动态发现 | ⚠️ 可能需开发 | 破坏原生架构,不推荐 | | 结合服务网格替代方案 | ✅ 是(Istio等) | 推荐云原生方案 | > ⚠️ **最佳实践**:在Kubernetes中,优先使用**Service抽象层**解耦Ingress与服务发现。若需高级流量管理,建议采用服务网格(如Istio)替代传统Ingress控制器[^4]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值