在 Traefik Proxy 2.5 中使用/开发私有插件(Traefik 官方博客)
Traefik Proxy 在设计上是一个模块化路由器,允许您将中间件放入您的路由中,并在请求到达预期的后端服务目的地之前对其进行修改。 Traefik 内置了许多这样的中间件,还允许您以插件的形式加载自己的中间件。
查找和安装中间件插件的最简单方法是通过 Traefik Pilot。 Traefik Pilot 是一个软件即服务 (SaaS) 平台,它为您的所有 Traefik 代理实例提供全球指标和警报系统,并具有免费使用的内置插件商店。 在商店内,您可以浏览所有可用的开源插件,然后单击按钮进行安装。
随着 Traefik Proxy v2.5 的发布,有一种新方法可以直接从本地存储加载插件(并且无需启用 Traefik Pilot)。 只需将您的插件源代码放入一个名为 /plugins-local
的新目录中。(您将相对于当前工作目录 [从您调用 traefik 的位置] 创建此目录,如果您使用的是 traefik
docker 映像,则入口点始终是根目录 /
。) Traefik Proxy
本身将负责构建(解释 ) 你的插件,所以你所要做的就是编写源代码,并在正确的目录中提供它以便 Traefik Proxy 加载它。插件每次启动仅加载一次(即,每次您希望重新加载插件源代码时都必须重新启动 traefik
)。
在以下场景中,您将找到使用 Traefik Proxy v2.5 编写自己的 Docker 容器镜像并将插件源代码捆绑到该镜像的 /plugins-local
目录中的示例。在使用 Docker 在开发环境中测试您的插件之后(并且可能在为其创建持续集成构建之后),您可以将此镜像推送到容器 registry,并在生产 Docker 服务器和/或 Kubernetes 集群中引用此镜像。您可以将镜像保密,也可以将其发布并在任何地方共享您的插件。
构建 Traefik Proxy 容器镜像并捆绑 demo 插件
这是一个示例 Dockerfile
,它重新混合了标准 traefik:v2.5
docker 映像,并添加了一个从可配置的 git 存储库自动克隆的插件。
在某个地方创建一个临时目录,并在其中创建一个名为 Dockerfile.demo
的新文件:
# Dockerfile.demo - Example for Traefik Proxy and a demo plugin from git:
FROM alpine:3
ARG PLUGIN_MODULE=github.com/traefik/plugindemo
ARG PLUGIN_GIT_REPO=https://github.com/traefik/plugindemo.git
ARG PLUGIN_GIT_BRANCH=master
RUN apk add --update git && \
git clone ${PLUGIN_GIT_REPO} /plugins-local/src/${PLUGIN_MODULE} \
--depth 1 --single-branch --branch ${PLUGIN_GIT_BRANCH}
FROM traefik:v2.5
COPY --from=0 /plugins-local /plugins-local
默认构建参数加载 Traefik Labs 发布的示例插件 demo,它本质上是内置 headers.customRequestHeaders 中间件的克隆,但作为插件。
- https://github.com/traefik/plugindemo
- https://doc.traefik.io/traefik/middlewares/headers/#customrequestheaders
在与 Dockerfile.demo
相同的目录中,构建镜像:
docker build -f Dockerfile.demo --tag traefik-with-demo-plugin .
您现在刚刚构建了一个 docker 镜像,其中包含 Traefik v2.5 和演示插件。您现在可以运行镜像来测试它:
docker run --rm -it traefik-with-demo-plugin \
--log.level=DEBUG \
--experimental.localPlugins.demo.moduleName=github.com/traefik/plugindemo
日志将打印显示插件已加载且 Traefik 代理将运行的配置。
你可以肯定地测试一下,按 Ctrl-C
停止容器,然后重新运行将 moduleName=
更改为 github.com/something/different
的命令,你会得到一个错误,说它不存在并立即退出。
使用您的自定义插件构建 Traefik Proxy 容器镜像
要创建您自己设计的新插件,请分叉此演示存储库。(要直接在 GitHub 上执行此操作,您可以单击标有 Use this template
的绿色按钮,或者您可以将存储库克隆到另一台服务器)。 您可以选择将此新存储库设为公共或私有,但说明会有所不同,具体取决于它是否需要身份验证才能克隆它,因此将分别介绍每种情况。
将您的分叉存储库克隆到您的工作站,并阅读 readme.md 文件中的开发说明。 创建您的插件代码,更新 .traefik.yml
中的 import
行以匹配您的存储库名称,将更改提交到 git,然后将更改推送回您的 git 服务器 (GitHub)。 如果您只想测试示例插件代码,则无需提交任何更改。 此外,Traefik 不需要编译插件源代码:插件通过原始源代码加载,并在运行时由 Yaegi 解释。
从公共存储库构建镜像
如果您将存储库公开,则构建镜像很容易。打开您的 shell 终端,并创建这些临时环境变量以用作构建参数:
## Create temporary variables for your plugin and git repository details:
## Optionally save these to build-env.sh and run "source build-env.sh" after.
export DOCKER_IMAGE=traefik-with-my-plugin
export PLUGIN_MODULE=github.com/YOUR_NAME/YOUR_REPOSITORY
export PLUGIN_GIT_REPO=https://github.com/YOUR_NAME/YOUR_REPOSITORY.git
export PLUGIN_GIT_BRANCH=master
更改这些变量以适合您的分叉插件存储库:
DOCKER_IMAGE
是你的新 Docker 镜像的 tag,它将捆绑 Traefik 和你的插件代码。PLUGIN_MODULE
是插件的 Go 模块的名称(例如github.com/traefik/plugindemo
)。 使用您自己的服务器、组织和分叉存储库名称。PLUGIN_GIT_REPO
是插件存储库中心的完整git clone
URL。 (此示例假设使用了公共存储库,并且不需要身份验证,否则请参阅下一节。)PLUGIN_GIT_BRANCH
是您希望克隆和安装的 git 分支名称。
在克隆存储库的根目录中,创建一个名为 Dockerfile.public
的新文件:
## Dockerfile.public - Bundle a Traefik plugin from a public git repository
FROM alpine:3
ARG PLUGIN_MODULE=github.com/traefik/plugindemo
ARG PLUGIN_GIT_REPO=https://github.com/traefik/plugindemo.git
ARG PLUGIN_GIT_BRANCH=master
RUN apk update && \
apk add git && \
git clone ${PLUGIN_GIT_REPO} /plugins-local/src/${PLUGIN_MODULE} \
--depth 1 --single-branch --branch ${PLUGIN_GIT_BRANCH}
FROM traefik:v2.5
COPY --from=0 /plugins-local /plugins-local
构建并标记镜像,从环境中传递参数:
docker build -f Dockerfile.public \
--tag ${DOCKER_IMAGE} \
--build-arg PLUGIN_MODULE \
--build-arg PLUGIN_GIT_REPO \
--build-arg PLUGIN_GIT_BRANCH .
从私有 git 存储库构建镜像
从私有 git 存储库构建镜像更具挑战性,因为您需要将 SSH 凭据传递到 Docker 构建过程,以便按照 Dockerfile
中的脚本从私有 git 存储库进行克隆。
您需要将 Docker
安装更新到版本 >=18.09
,这允许在 docker
镜像构建过程中加载与 ssh-agent
通信和临时使用工作站用户帐户的 SSH 密钥所需的实验性 BuildKit 增强功能。
在你的 shell 中设置这些环境变量:
## Optionally save these to build-env.sh and run "source build-env.sh" after.
## Docker BuildKit is required for ssh-agent forwarding:
export DOCKER_BUILDKIT=1
## Edit these variables for your plugin and git repository:
export DOCKER_IMAGE=traefik-with-my-plugin
export PLUGIN_MODULE=github.com/YOUR_NAME/YOUR_REPOSITORY
export PLUGIN_GIT_REPO=git@github.com:YOUR_NAME/YOUR_REPOSITORY.git
export PLUGIN_GIT_BRANCH=master
主机 ssh-agent
直通需要修改 Dockerfile
。创建一个名为 Dockerfile.private
的新文件:
# syntax=docker/dockerfile:1.0.0-experimental
# The above line is required to turn on experimental BuildKit features.
# Dockerfile.private - Build Traefik and plugin from a private git repository.
# Loads SSH keys from the host `ssh-agent` to allow git clone.
FROM alpine:3
# Clone your plugin git repositories:
ARG PLUGIN_MODULE=github.com/traefik/plugindemo
ARG PLUGIN_GIT_REPO=git@github.com:traefik/plugindemo.git
ARG PLUGIN_GIT_BRANCH=master
RUN apk add --update git openssh && \
mkdir -m 700 /root/.ssh && \
touch -m 600 /root/.ssh/known_hosts && \
ssh-keyscan github.com > /root/.ssh/known_hosts
RUN --mount=type=ssh git clone \
--depth 1 --single-branch --branch ${PLUGIN_GIT_BRANCH} \
${PLUGIN_GIT_REPO} /plugins-local/src/${PLUGIN_MODULE}
FROM traefik:v2.5
COPY --from=0 /plugins-local /plugins-local
使用额外的 --ssh default
选项构建镜像。这将通过连接到运行 ssh-agent 的主机连接到构建过程,以便您可以在构建过程中使用 SSH 密钥,并克隆私有 git 存储库:
docker build -f Dockerfile.private \
--ssh default --tag ${DOCKER_IMAGE} \
--build-arg PLUGIN_MODULE \
--build-arg PLUGIN_GIT_REPO \
--build-arg PLUGIN_GIT_BRANCH .
注意:由于 docker-compose 中存在一个未解决的问题,您目前无法在 docker-compose
中使用 --ssh
参数(并且与 ssh-agent
的连接将失败),因此如果您想使用此修改后的 Dockerfile
以及 docker-compose
,您必须首先使用上面列出的 docker build
命令手动构建容器映像。 如果您首先以这种方式构建映像,则 docker-compose
可以依赖构建缓存或显式镜像名称,而无需再次构建它。
使用 docker-compose 作为插件开发环境
你可以使用 docker-compose 作为一个简单的插件开发环境。
将您的插件存储库克隆到您的工作站,然后将这些新文件创建到存储库的根目录中:
创建 Dockerfile
:
FROM traefik:v2.5
## Default module name (put your setting in .env to override)
ARG PLUGIN_MODULE=github.com/traefik/plugindemo
ADD . /plugins-local/src/${PLUGIN_MODULE}
创建 .env
设置文件:
## Traefik Proxy local plugin .env file
## Configure your plugin name:
PLUGIN_NAME=demo
## Configure your module namespace:
PLUGIN_MODULE=github.com/traefik/plugindemo
## Configure whoami domain name for route testing:
WHOAMI_TRAEFIK_HOST=whoami.example.com
## Configure Email address for Let's Encrypt:
## Uncomment and configure this for production only:
# ACME_CA_EMAIL=you@example.com
创建 docker-compose.yaml
:
# docker-compose.yaml for Traefik Proxy local plugin development
version: "3.3" networks: traefik-proxy: volumes: traefik-proxy:
services:
traefik-proxy:
build:
context: .
args:
PLUGIN_MODULE: ${PLUGIN_MODULE}
restart: unless-stopped
networks:
- traefik-proxy
security_opt:
- no-new-privileges:true
command:
#- "--log.level=DEBUG"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=traefik-proxy"
## Entrypoints:
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.traefik.address=:9000"
## Automatically redirect HTTP to HTTPS
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
## ACME TLS config:
- "--certificatesresolvers.default.acme.storage=/data/acme.json"
## Uncomment for production TLS certificates (Let's Encrypt):
# - "--certificatesresolvers.default.acme.tlschallenge=true"
# - "--certificatesresolvers.default.acme.caserver=https://acme-v02.api.letsencrypt.org/directory"
# - "--certificatesresolvers.default.acme.email=${ACME_CA_EMAIL}"
## Enable Dashboard available only from the docker localhost:9000
- "--api.dashboard=true"
- "--api.insecure=true"
## Enable local plugins:
- "--experimental.localPlugins.${PLUGIN_NAME}.moduleName=${PLUGIN_MODULE}"
ports:
- "80:80"
- "443:443"
- "127.0.0.1:9000:9000"
volumes:
- "traefik-proxy:/data"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
## The whoami container will run the demo plugin for testing purposes:
whoami:
image: traefik/whoami
networks:
- traefik-proxy
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`${WHOAMI_TRAEFIK_HOST}`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
# Configure the plugin as a new middleware:
- "traefik.http.routers.whoami.middlewares=whoami-demo"
# Add a test header to all incoming requests:
# (the presense of this header in whoami response shows if the plugin works:)
- "traefik.http.middlewares.whoami-demo.plugin.${PLUGIN_NAME}.headers.DoesPluginWork=YES"
- "traefik.http.routers.whoami.tls.certresolver=default"
创建 .dockerignore
以从镜像构建中排除 .git
目录:
# .dockerignore file exludes files from the image:
.git
构建镜像并启动测试实例:
docker-compose up
编辑您的 /etc/hosts
文件(或您的本地 DNS 服务器)并添加 whoami 路由域:
# ... excerpt from /etc/hosts
# Domain names for Traefik:
# Point to the IP address of your docker server:
127.0.0.1 whoami.example.com app1.example.com app2.example.com
使用 curl
测试您的 DNS
是否正常工作,以及插件是否已生效(使用与您为 WHOAMI_TRAEFIK_HOST
和 /etc/hosts
配置的域名相同的域名):
curl -k https://whoami.example.com
您应该得到 whoami
响应,并在输出中显示此测试头:
Doespluginwork: YES
这是插件配置为注入请求的相同头和值,并从 whoami 回显。 如果你看到它,你就知道你的插件配置成功了。
为常规开发工作配置本地 DNS 服务
当你需要测试大量不同的子域和 Traefik Proxy Host
路由器规则时,一个更好的 DNS 解决方案,而不是不断编辑你的 /etc/hosts
文件,是在你的工作站上运行 dnsmasq
作为本地 DNS
服务器,它会响应到通配符 DNS A
记录查询,用于整个根域或子域名。
dnsmasq
的配置是可选的,是对 /etc/hosts
文件的补充。dnsmasq
的安装说明取决于您的操作系统,但可以从大多数包管理器中获得。 dnsmasq
将使您的开发工作更加顺畅,并且是清理 /etc/hosts
文件的好方法。这是一个示例 /etc/dnsmasq.conf
配置文件,用于设置具有通配符域的本地 DNS 服务。您还需要按照注释中的说明编辑您的 /etc/resolv.conf
:
# /etc/dnsmasq.conf
# Use this if you are tired of editing your /etc/hosts file.
# This is a local DNS service bound only to the looback device on localhost.
# To use this requires an /etc/resolv.conf file
# with a single line (no leading space): nameserver 127.0.0.1
# To prevent any changes to the host DNS config,
# run: sudo chattr +i /etc/resolv.conf
# (now all of your DNS queries will go through dnsmasq)
interface=lo
listen-address=::1,127.0.0.1
bind-interfaces
cache-size=1000
# Use cloudflare upstream DNS servers:
server=1.1.1.1
server=1.0.0.1
# Example wildcard domain names
# All *.example.com names point to a single docker server IP address:
address=/example.com/127.0.0.1
# dnsmasq also loads your /etc/hosts file, so those host names still work.
检查您的操作系统说明以启用 dnsmasq 服务,但通常使用 Systemd:
sudo systemctl enable --now dnsmasq.service
编辑 /etc/resolv.conf
以将 dnsmasq
服务器用于所有系统 DNS 查询:
domain your.domain.example.com
search domain.example.com
nameserver 127.0.0.1
有时其他服务(systemd-resolved)想要覆盖这个文件,你可以通过在文件上应用不可变标志来防止这种情况:
# This prevents editing the file, use -i to re-enable editing:
chattr +i /etc/resolv.conf
您可以使用 dig
、drill
或 nslookup
实用程序测试 DNS 服务器是否处于活动状态:
# dig or drill:
dig test.example.com | grep -A1 "ANSWER SECTION"
# or nslookup:
nslookup test.example.com
任何这些工具的输出都应该报告您的 docker
主机的正确 IP 地址,现在您可以在 Traefik 代理路由中使用您想要的任何子域。
引用
在 Traefik Proxy 2.5 中使用/开发私有插件(Traefik 官方博客)的更多相关文章
- 如何使用 Rancher Desktop 访问 Traefik Proxy 仪表板
Adrian Goins 最近举办了关于如何使用 K3s 和 Traefik 保护和控制边缘的 Kubernetes 大师班,演示了如何访问 K3s 的 Traefik Proxy 仪表板,可以通过以 ...
- Eclipse中Python开发环境搭建
Eclipse中Python开发环境搭建 目 录 1.背景介绍 2.Python安装 3.插件PyDev安装 4.测试Demo演示 一.背景介绍 Eclipse是一款基于Java的可扩展开发平台. ...
- ARC中KVO开发注意
1 在ARC 中 KVO开发 添加监听和去掉监听必需 一一匹配,不要有过的去掉监听否则会有可能导致对象无法释放. 例如,在一个viewcontroller中添加webview 并监听webview的c ...
- 动态调用WebService 通用方法Moss 中 传统开发中都可用。
WebService是啥大家都知道了,这里不做过多的解释.通常我们使用WebService的做法基本都是在我们的项目中添加Web引用的方式,首先找到WebService的地址,然后定义命名空间,这样会 ...
- 使用 PySide2 开发 Maya 插件系列二:继承 uic 转换出来的 py 文件中的类 Ui_Form
使用 PySide2 开发 Maya 插件系列二:继承 uic 转换出来的 py 文件中的类 Ui_Form 开发环境: Wing IDE 6.1 步骤1: 打开 Wing IDE,创建一个新的 pr ...
- 【Git 使用笔记】第四部分:git在公司中的开发流程
先声明几个变量 仓管A:主分支,只有master分支仓管B:开发分支,只有各个业务开发分支 仓管B fork 于 A 如下图 为了保证 代码的稳定性,只有 仓管B中的某个分支测试完毕并进行了代码r ...
- 教你如何获取ipa包中的开发文件
教你如何获取ipa包中的开发文件 1. 从iTunes获取到ipa包 2. 修改ipa包然后获取里面的开发文件
- C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例
C# 动态生成word文档 本文以一个简单的小例子,简述利用C#语言开发word表格相关的知识,仅供学习分享使用,如有不足之处,还请指正. 在工程中引用word的动态库 在项目中,点击项目名称右键-- ...
- Eclipse中一个开发AspectJ的插件安…
eclipse4.2 EE版本插件安装 Eclipse最新版本Juno版本发布.部分插件版本跟不上. 选择自己需要的插件安装. eclipse http://www.eclipse.org/downl ...
随机推荐
- js 生成 pdf 文件
话不多说好吧, 直接上demo图: 直接上代码好吧:(要引入的两个js 链接我放最后) <!DOCTYPE html> <html> <head> <met ...
- Python入门-pip模块管理工具
安装 # 在线安装 pip install <包名> 安装后,该模块文件会在安装python环境目录:lib/packages目录下 # 安装本地安装包 pip install <目 ...
- Ubuntu中hyperledger-fabric2.3.0环境搭建
系统环境 hyperledger-fabric在Ubuntu安装过程,fabric版本为2.3.0 首先安装相关软件 1.安装docker 直接参考下面这篇文档安装好docker-ce即可 Ubunt ...
- springdata jpa多表查询的方式
方式一:使用@Query注解方式查询主要有JPQL方式,也就是面向对象的方式,这种情况下查表其实查的是对象,字段是实体中的属性,该方式可以直接映射到实体,如下图. 使用jpql的方式模糊查询时候不能使 ...
- [翻译] Cassandra 分布式结构化存储系统
Cassandra 分布式结构化存储系统 摘要 Cassandra 是一个分布式存储系统,用于管理分布在许多商品服务器上的大量结构化数据,同时提供无单点故障(no single point of fa ...
- 在UnityUI中绘制线状统计图2.0
##在之前的基础上添加横纵坐标 上一期在这里:https://www.cnblogs.com/AlphaIcarus/p/16123434.html 先分别创建横纵坐标点的模板,将这两个Text放在G ...
- css加载动画(纯css和html)
从jq官网上摘抄下来的一个简单加载动画,个人比较喜欢使用~存在这里,作为记录 话不多说~上代码 <!DOCTYPE html> <html lang="en"&g ...
- Java语言学习day24--7月30日
###17创建子类对象过程的细节 * A 创建子类对象过程的细节 * 如果子类的构造方法第一行写了this调用了本类其他构造方法,那么super调用父类的语句还有吗? * 这时是没有的,因为this( ...
- HTML中的Hack手段之条件注释
通常WEB的好处就是可以跨平台,但这个世界偏偏有个另类,就是IE浏览器.在平常做HTML设计时,有时需要为IE的表示差异而不得不使用一些Hack手段.条件注释就是这类手段之一. 条件注释是IE浏览器的 ...
- IDEA通过Jedis操作Linux上的Redis;Failed to connect to any host resolved for DNS name问题
testPing.java public class testPing { public static void main(String[] args) { Jedis jedis = new Jed ...