服务环境搭建-Traefik网关服务

服务环境搭建-Traefik网关服务

1. 说明

Traefik网关服务用于提供一个实现反向代理、中间件鉴权、服务负载均衡、与服务发现的环境。

2. 反向代理

2.1 基本概念

EntryPoints:入口点是进入Traefik的网络入口点。它们定义了接收数据包的端口,以及是侦听TCP还是UDP。入口点是静态配置的一部分,它们可以通过使用文件(TOML或YAML)或CLI参数来定义。

Routers:路由器负责将传入的请求连接到能够处理它们的服务。在这个过程中,路由器可能会使用一些中间件来更新请求,或者在将请求转发给服务之前采取行动。

RuleRule是一组配置有值的匹配器,这些值确定特定请求是否匹配特定条件。 如果该规则得到验证,则路由器将变为活动状态,调用中间件,然后将请求转发到服务。

转发到Hostexample.com的服务

rule = "Host(`example.com`)"

转发到Hostexample.com或者Hostexample.org并且Path/traefik的服务

rule = "Host(`example.com`) || (Host(`example.org`) && Path(`/traefik`))"

Rule所有可用的配置器

可以使用AND(&&)OR(||)运算符组合多个匹配器。 也可以使用括号。

RuleDescription
Headers(key, value)Check if there is a key keydefined in the headers, with the value value
HeadersRegexp(key, regexp)Check if there is a key keydefined in the headers, with a value that matches the regular expression regexp
Host(example.com, …)Check if the request domain (host header value) targets one of the given domains
HostHeader(example.com, …)Check if the request domain (host header value) targets one of the given domains
HostRegexp(example.com, {subdomain:[a-z]+}.example.com, …)Check if the request domain matches the given regexp
Method(GET, …)Check if the request method is one of the given methods (GET, POST, PUT, DELETE, PATCH, HEAD)
Path(/path, /articles/{cat:[a-z]+}/{id:[0-9]+}, …)Match exact request path. It accepts a sequence of literal and regular expression paths
PathPrefix(/products/, /articles/{cat:[a-z]+}/{id:[0-9]+})Match request prefix path. It accepts a sequence of literal and regular expression prefix paths
Query(foo=bar, bar=baz)Match Query String parameters. It accepts a sequence of key=value pairs

2.2 Traefik监听Docker服务

简单例子

配置docker、部署/公开服务

启用docker提供程序

--providers.docker=true

将标签附加到容器(在docker-compose文件中)

version: "3"
services:
  my-container:
    # ...
    labels:
      - traefik.http.routers.my-container.rule=Host(`example.com`)

为容器指定自定义端口:将对http://example.com的请求转发到http:// <容器的私有IP>:12345

version: "3"
services:
  my-container:
    # ...
    labels:
      - traefik.http.routers.my-container.rule=Host(`example.com`)
      # Tell Traefik to use the port 12345 to connect to `my-container`
      - traefik.http.services.my-service.loadbalancer.server.port=12345

为每个容器指定多个路由器和服务

将请求转发到容器上的多个端口需要使用路由器上的service参数引用服务负载均衡器端口定义。

在此示例中,除了将http://example-a.com请求转发到http://<private IP of container>:8000外,还将http://example-b.com的请求转发到http://<private IP of container>:9000

version: "3"
services:
  my-container:
    # ...
    labels:
      - traefik.http.routers.www-router.rule=Host(`example-a.com`)
      - traefik.http.routers.www-router.service=www-service
      - traefik.http.services.www-service.loadbalancer.server.port=8000
      - traefik.http.routers.admin-router.rule=Host(`example-b.com`)
      - traefik.http.routers.admin-router.service=admin-service
      - traefik.http.services.admin-service.loadbalancer.server.port=9000

3. 中间件

连接到路由器上的中间件是在请求被发送到服务(或在服务的回答被发送到客户机之前)之前调整请求的一种方法。通常用来做一些权限校验与调整请求。

在Traefik中有几个可用的中间件,一些可以修改请求、头,一些负责重定向,一些添加身份验证,等等。

3.1 ForwardAuth

在这里插入图片描述

Traefik提供的ForwardAuth中间件可以使用外部服务转发身份验证。FrwardAuth中间件将身份验证委派给外部服务。 如果服务以2XX响应码回答,则将授予访问权限,并执行原始请求。 否则,将返回来自身份验证服务器的响应。我们用此中间件来完成服务的鉴权:

3.1.1 使用实例

将身份验证转发到http://example.com/auth

labels:
  - "traefik.http.middlewares.test-auth.forwardauth.address=http://example.com/auth"
3.1.2 转发请求头

以下请求属性以X-Forwarded- headers的形式提供给forward-auth目标端点。

PropertyForward-Request Header
HTTP MethodX-Forwarded-Method
ProtocolX-Forwarded-Proto
HostX-Forwarded-Host
Request URIX-Forwarded-Uri
Source IP-AddressX-Forwarded-For
3.1.3 配置项

address

address定义认证服务器的地址

labels:
  - "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth"

trustForwardHeader

trustForwardHeader选项设置为true以信任所有X-Forwarded-*头。

labels:
  - "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true"

authResponseHeaders

authResponseHeaders选项是要从身份验证服务器响应中复制并根据转发的请求进行设置的标头列表,以替换所有现有的冲突标头。

labels:
  - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret"

authResponseHeadersRegex

authResponseHeadersRegex选项是正则表达式,用于匹配要从身份验证服务器响应中复制的标头,并在转发与正则表达式匹配的所有标头后,根据转发的请求进行设置。 它允许将正则表达式与标题键进行部分匹配。 字符串(^)的开头和字符串($)的结尾应用于确保与标题键完全匹配。

labels:
  - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-"

authRequestHeaders

authRequestHeaders选项是要从请求复制到身份验证服务器的标头列表。 它允许过滤不应传递到身份验证服务器的标头。 如果未设置或为空,则传递所有请求标头。

labels:
  - "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders=Accept,X-CustomHeader"

3.2 Add Prefix

在这里插入图片描述

AddPrefix中间件在转发请求之前添加前缀更新请求的路径。

3.2.1 使用实例

给原请求的path添加前缀

# Prefixing with /foo
labels:
  - "traefik.http.middlewares.add-foo.addprefix.prefix=/foo"
3.2.2 配置项

prefix

prefix是要在请求的URL中的当前路径之前添加的字符串,它应该包含一个斜杠(/)。

3.3 StripPrefix

从URL路径中删除指定的前缀。

3.3.1 使用实例

删除原请求path的前缀

# Strip prefix /foobar and /fiibar
labels:
  - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar,/fiibar"
3.3.2 配置项

General

StripPrefix中间件将匹配的路径前缀去除,并将其存储在X - Forwarded - Prefix头文件中。

prefixes

prefixes选项定义从请求URL中去除的前缀。

forceSlash

Optional, Default=true

forceSlash选项可通过在必要时将其替换为/来确保所得的剥离路径不是空字符串。

添加这个选项是为了保持这个中间件的初始(非直观)行为,以避免引入破坏性更改。

建议显式设置forceSlash为false。

forceSlash的行为示例

  • forceSlash=true
PathPrefix to stripResult
///
/foo/foo/
/foo//foo/
/foo//foo//
/bar/foo/bar
/foo/bar/foo/bar
  • forceSlash=false
PathPrefix to stripResult
//empty
/foo/fooempty
/foo//foo/
/foo//foo/empty
/bar/foo/bar
/foo/bar/foo/bar

3.4 Chain

在这里插入图片描述

Chain中间件使您能够定义其他中间件的可重用组合, 这使得重用相同的组更加容易。

3.4.1 使用实例

以下是包含WhiteListBasicAuthRedirectScheme的Chain的示例。

labels:
  - "traefik.http.routers.router1.service=service1"
  - "traefik.http.routers.router1.middlewares=secured"
  - "traefik.http.routers.router1.rule=Host(`mydomain`)"
  - "traefik.http.middlewares.secured.chain.middlewares=https-only,known-ips,auth-users"
  - "traefik.http.middlewares.auth-users.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
  - "traefik.http.middlewares.https-only.redirectscheme.scheme=https"
  - "traefik.http.middlewares.known-ips.ipwhitelist.sourceRange=192.168.1.7,127.0.0.1/32"
  - "http.services.service1.loadbalancer.server.port=80"

4. 负载均衡

负载平衡器能够在程序的多个实例之间负载平衡请求,每个服务都有一个负载均衡器,即使只有一台服务器可以转发流量。

目前只支持轮询负载均衡

使用两个服务器声明服务(使用负载平衡)

http:
  services:
    my-service:
      loadBalancer:
      # 在以下服务中实现负载均衡
        servers:
        - url: "http://private-ip-server-1/"
        - url: "http://private-ip-server-2/"

5. 服务发现

Traefik可以自动发现服务。其服务发现是通过 providers来实现的, providers是基础设置组件,其思想是Traefik查询提供程序的API,以查找有关路由的相关信息,并且当Traefik检测到更改时,它会动态更新路由。

使用Docker作为Traefik的提供商

指定docker作为Traefik的providers

--providers.docker=true

Traefik需要访问docker套接字来获取它的动态配置。你可以用endpoint来指定要使用哪个Docker API端点。

--providers.docker.endpoint=unix:///var/run/docker.sock

使Traefik监听Docker事件

 volumes:
   - /var/run/docker.sock:/var/run/docker.sock:ro

使用docker部署服务时,通过labels标签附加信息,告诉Traefik服务可以处理的请求的特征,这意味着当部署服务时,Traefik会立即检测到该服务并实时更新路由规则。反之亦然:当您从基础设施中删除服务时,路由将随之消失。

如下例子:

  whoami:
    image: traefik/whoami
    container_name: whoami
    networks:
      - proxy
    labels:
    # 通知Traefik路由的名称为routers,规则为:访问Host为example.com、path为/whoami的请求转发到whoami的服务
     - "traefik.http.routers.whoami.rule=Host(`example.com`) && Path(`/whoami`)"

6. 综合实例

6.1 实现目标

使用Traefik监听Docker服务,自动发现服务与自动负载均衡。启动两个whoami的docker服务,http://example.com/web的请求转发到whoami_web服务;http://example.com/svv_runtimehttp://example.com/svv/...的请求转发到whoami_svv服务的根路径下。同时请求这两个服务之前进行鉴权,当鉴权成功时才可以顺利访问服务。

6.2 实现方式

# docker-compose.yml
version: '3'

services:
  # traefik服务
  traefik:
    image: traefik:v2.4
    container_name: traefik
    restart: always
    # 禁止容器进程获取新的权限
    security_opt:
      - no-new-privileges:true
    # traefik服务监听80与8080两个端口
    ports:
      - 80:80
      - 8080:8080
    command:
      - "--api=true"
      # 启用Web UI并监听docker
      - "--api.insecure=true"
      # 开启控制台(默认开启)
      - "--api.dashboard=true"
      # 入口点定义
      - "--entrypoints.web.address=:80"
      # 指定traefik的提供商为docker
      - "--providers.docker=true"
      # 访问docker套接字获取动态配置
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      # 指定docker网络为proxy
      - "--providers.docker.network=proxy"
    
    # 使Traefik监听Docker事件
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    # 创建docker自定义网络为proxy
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      # 访问traefik的后台的Host为example.com
      - "traefik.http.routers.traefik.rule=Host(`example.com`)"
  # whoami服务
  whoami_web:
    image: traefik/whoami
    container_name: whoami_web
    networks:
      - proxy
    labels:
      # 创建名为whoami_web的路由,将path为/web请求转发到该服务
      - "traefik.http.routers.whoami_web.rule=Path(`/web`)"
      # 将名为whoami_web的路由与test-auth的鉴权中间件进行连接
      - "traefik.http.routers.whoami_web.middlewares=test-auth@docker"
      # 将请求转发到address为http://ip:port/auth的鉴权服务,若服务响应2xx的状态码,则授权访问,并执行原始请求。否则,将返回鉴权服务器的响应
      - "traefik.http.middlewares.test-auth.forwardauth.address=http://ip:port/auth"
  whoami_svv:
    image: traefik/whoami
    container_name: whoami_svv
    networks:
      - proxy
    labels:
     # 创建名为whoami_svv的路由,将path前缀为/svv_runtime请求转发到该服务
     - "traefik.http.routers.whoami_svv.rule=PathPrefix(`/svv_runtime`)"
     # 创建名为middlewareschain的中间件链路
     - "traefik.http.routers.whoami_svv.middlewares=middlewareschain"
     # middlewareschain中间件链路包含鉴权中间件test-auth与删除前缀中间件test-stripprefix
     - "traefik.http.middlewares.middlewareschain.chain.middlewares=test-auth@docker,test-stripprefix@docker"
     # 将请求转发到address为http://ip:port/auth的鉴权服务,若服务响应2xx的状态码,则授权访问,并执行原始请求。否则,将返回鉴权服务器的响应
     - "traefik.http.middlewares.test-auth.forwardauth.address=http://ip:port/auth"
     # 将原请求Path删除前缀svv_runtime
     - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/svv_runtime"

networks:
  proxy:
    external: true
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

banmajio

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值