前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何在Ubuntu上使用Traefik作为Docker容器的反向代理

如何在Ubuntu上使用Traefik作为Docker容器的反向代理

原创
作者头像
林岑影
发布2018-08-13 11:44:29
2.3K0
发布2018-08-13 11:44:29
举报

介绍

Docker是在生产中运行Web应用程序的有效方法,但您可能希望在同一个Docker主机上运行多个应用程序。在这种情况下,如果只有端口80443可用,您需要设置反向代理。

Traefik是一个支持Docker的反向代理,包括自己的监控仪表板。在本教程中,您将使用Traefik请求路由到两个不同的Web应用程序容器:Wordpress容器和Adminer容器,每个容器都与MySQL数据库通信。

准备

要继续学习本教程,您需要具备以下条件:

  • Ubuntu 16.04初始服务器,包括一个可以使用sudo命令的非root用户。
  • 正在运行的Docker主机。如果您还没有Docker,请按照教程:如何在Ubuntu16.04上安装和使用Docker
  • 安装的Docker Compose。
  • 一个域和三个A记录, db-adminblogmonitor,每个对应docker主机的IP地址。

第1步 - 配置和运行Traefik

Traefik项目有一个官方Docker镜像,因此我们将使用它在Docker容器中运行Traefik。

但在我们启动并运行Traefik容器之前,我们需要创建配置文件并设置加密密码,以便我们可以访问监控仪表板。

我们将使用htpasswd实用程序创建此加密密码。首先,安装apache2-utils包中包含的实用程序:

代码语言:txt
复制
$ sudo apt-get install apache2-utils

然后生成密码htpasswd。用secure_password替换您想要用于Traefik管理员用户的密码:

代码语言:txt
复制
$ htpasswd -nb admin secure_password

程序的输出如下所示:

代码语言:txt
复制
admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/

您将在Traefic配置文件中使用此输出为Traefik运行状况检查和监视仪表板设置HTTP基本身份验证。复制整个输出行,以便稍后粘贴。

要配置Traefik服务器,我们将创建一个使用TOML格式调用的新配置文件traefik.toml。TOML是一种类似于INI文件的配置语言,但它是标准化的。该文件允许我们配置Traefik服务器以及我们想要使用的各种集成或提供程序。在本教程中,我们将使用三个Traefik的可用提供商:webdocker,和acme,这是用于支持TLS加密。

代码语言:txt
复制
$ nano traefik.toml

首先,添加两个命名的入口点,httphttps,默认情况下所有后端都可以访问:

traefik.toml

代码语言:txt
复制
defaultEntryPoints = ["http", "https"]

我们稍后将在此文件中配置httphttps

接下来,配置web提供程序,使您可以访问仪表板界面。您可以在此处粘贴htpasswd命令的输出:

traefik.toml

代码语言:txt
复制
...
[web]
address = ":8080"
  [web.auth.basic]
  users = ["admin:your_encrypted_password"]

仪表板是一个单独的Web应用程序,将在Traefik容器中运行。我们将仪表板设置为在端口8080上运行。

web.auth.basic部分为仪表板配置HTTP基本身份验证。使用您刚刚运行的htpasswd命令的输出作为users条目的值。您可以通过用逗号分隔来指定其他登录。

接下来,定义入口点。该entryPoints部分配置Traefik和代理容器可以侦听的地址。将这些行添加到文件中:

traefik.toml

代码语言:txt
复制
...
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

http入口点处理端口80,而https入口点为TLS /SSL使用的端口443。我们自动将端口80上的所有流量重定向到https入口点,以强制所有请求的安全连接。

最后,添加此部分以配置Traefik的Let's Encrypt证书支持:

traefik.toml

代码语言:txt
复制
...
[acme]
email = "your_email@example.com"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
onDemand = false

调用此acme部分是因为ACME是用于与Let’s Encrypt进行通信以管理证书的协议的名称。要让Traefik为我们的主机生成证书,我们会将email密钥设置为您的电子邮件地址。然后,我们指定将把接收的信息存储在JSON文件中,命名为acme.json。在entryPoint关键的需求为指向切入点端口443,这对我们来说是https切入点。

最后两个关键步骤,onHostRuleonDemand指示Traefik应该如何生成证书。我们希望在创建具有指定主机名的容器后立即获取证书,这就是onHostRule设置的作用。该onDemand设置将尝试在第一次发出请求时生成证书。这会减慢第一个请求速度并使访问者可见,所以我们会避免这种情况。

保存文件并退出编辑器。有了所有这些配置,我们就可以启动Traefik了。

第2步 - 运行Traefik容器

接下来,为代理创建一个Docker网络以与容器共享。Docker网络是必需的,以便我们可以将它与使用Docker Compose运行的应用程序一起使用。我们把这个网络称为proxy

代码语言:txt
复制
$ docker network create proxy

当Traefik容器启动时,我们会将其添加到此网络中。然后,我们可以稍后向此网络添加其他容器,以便Traefik代理。

接下来,创建一个空文件,它将保存我们的信息。我们将这个分享到容器中,以便Traefik可以使用它:

代码语言:txt
复制
$ touch acme.json

然后锁定此文件的权限,以便只有root用户可以读取和写入此文件。如果你不这样做,Traefik将无法启动。

代码语言:txt
复制
$ chmod 600 acme.json

最后,使用以下命令创建Traefik容器:

代码语言:txt
复制
$ docker run -d \
$   -v /var/run/docker.sock:/var/run/docker.sock \
$   -v $PWD/traefik.toml:/traefik.toml \
$   -v $PWD/acme.json:/acme.json \
$   -p 80:80 \
$   -p 443:443 \
$   -l traefik.frontend.rule=Host:monitor.example.com \
$   -l traefik.port=8080 \
$   --network proxy \
$   --name traefik \
$   traefik:1.3.6-alpine --docker

命令有点长,让我们逐行分析。

我们使用该-d标志在后台运行容器作为守护进程。然后,我们将docker.sock文件共享到容器中,以便Traefik进程可以监听容器的更改。我们还将traefik.toml配置文件和我们创建的acme.json文件共享到容器中。

接下来,我们将端口:80:443 Docker主机映射到Traefik容器中的相同端口,以便Traefik接收到服务器的所有HTTP和HTTPS流量。

然后我们设置两个Docker标签,告诉Traefik将流量引导到Traefik容器内的主机名monitor.example.com到端口:8080,从而显示监控仪表板。我们将容器的网络设置为proxy,并将容器命名为traefik。

最后,我们使用此容器的镜像traefik:1.3.6-alpine,因为它很小。

Docker镜像ENTRYPOINT是一个始终在从图像创建容器时运行的命令。在这种情况下,该命令是traefik容器内的二进制文件。启动容器时,可以将其他参数传递给该命令。在我们的例子中,我们将参数--docker传递给ENTRYPOINT确保docker提供者使用默认设置注册的参数。该docker提供程序使Traefik能够在Docker容器前充当代理。Docker提供程序的默认配置对我们很有用,因此我们不需要在我们的配置traefik.toml中进行配置。

启动容器后,您现在可以访问仪表板以查看容器的运行状况。您还可以使用此仪表板显示Traefik已注册的前端和后端。通过指向您的浏览器访问监控仪表板。系统将提示您输入用户名和密码,即管理员和您在步骤1中配置的密码。https://monitor.example.com

登录后,你会看到类似这样的界面:

Empty Traefik dashboard
Empty Traefik dashboard

目前还没有太多东西可以看,但是打开这个窗口,当你为Traefik添加容器时,你会看到内容发生了变化。

我们现在运行Traefik代理,配置为与Docker一起使用,并准备监视其他Docker容器。让我们为Traefik开始一些容器作为代理。

第3步 - 使用Traefik注册容器

运行Traefik容器后,您就可以在其后面运行应用程序了。让我们在Traefik后面推出以下cotainers:

  1. 使用官方Wordpress镜像的博客。
  2. 使用官方Adminer映像的数据库管理服务器。

我们将使用Docker Compose管理这两个docker-compose.yml文件应用程序:

代码语言:txt
复制
$ nano docker-compose.yml

将以下行添加到文件中以指定我们将使用的版本和网络:

docker-compose.yml

代码语言:txt
复制
version: "3"

networks:
  proxy:
    external: true
  internal:
    external: false

我们使用Docker Compose版本3,因为它是Compose文件格式的最新主要版本。

对于Traefik来识别我们的应用程序,它们必须是同一网络的一部分,并且由于我们手动创建了网络,我们通过指定网络名称proxy和设置external来将其拉入true。然后我们定义另一个网络,以便我们可以将我们公开的容器连接到我们不会通过Traefik公开的数据库容器。我们称之为网络internal

接下来,我们将逐个定义services。让我们从blog容器开始,我们将基于官方的WordPress镜像。将此配置添加到文件中:

docker-compose.yml

代码语言:txt
复制
version: "3"
...

services:
  blog:
    image: wordpress:4.7.5-apache
    environment:
      WORDPRESS_DB_PASSWORD:
    labels:
      - traefik.backend=blog
      - traefik.frontend.rule=Host:blog.example.com
      - traefik.docker.network=proxy
      - traefik.port=80
    networks:
      - internal
      - proxy
    depends_on:
      - mysql

environment键允许您指定将在容器内设置的环境变量。但不要将值设置为WORDPRESS_DB_PASSWORD,我们告诉Docker Compose从我们的shell获取值并在创建容器时传递它。我们将在启动容器之前在shell中定义此环境变量。这样我们就不会将密码硬编码到配置文件中。

labels部分是您为Traefik指定配置值的部分。Docker标签本身不做任何事情,但Traefik会读取这些内容,因此它知道如何处理容器。以下是每个标签的作用:

  • traefik.backend指定Traefik中后端服务的名称(指向实际blog容器)。
  • traefik.frontend.rule=Host:blog.example.com告诉Traefik检查所请求的主机,如果它匹配它的blog.example.com模式,应该将流量路由到blog容器。
  • traefik.docker.network=proxy指定Traefik查找哪个网络以查找此容器的内部IP。由于我们的Traefik容器可以访问所有Docker信息,internal如果我们没有指定它,它可能会占用网络的IP 。
  • traefik.port 指定Traefik用于将流量路由到此容器的公开端口。

使用此配置,发送到Docker主机80端口的所有流量都将路由到blog容器。

我们将此容器分配给两个不同的网络,以便Traefik可以通过proxy网络找到它,并且可以通过网络与数据库容器进行internal通信。

最后,该depends_on密钥告诉Docker Compose该容器需要在其依赖项运行后启动。由于WordPress需要运行数据库,因此我们必须在启动容器mysql之前运行我们的blog容器。

接下来,通过将此配置添加到您的文件来配置MySQL服务:

docker-compose.yml

代码语言:txt
复制
services:
...
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD:
    networks:
      - internal
    labels:
      - traefik.enable=false

我们正在使用这个容器的官方MySQL 5.7映像。您会注意到我们再次使用没有值的environment项目。该MYSQL_ROOT_PASSWORD和WORDPRESS_DB_PASSWORD变量需要被设置为相同的值,以确保我们的WordPress的容器可以与MySQL进行通信。我们不希望将mysql容器暴露给Traefik或其他地方,因此我们只将此容器分配给internal网络。由于Traefik可以访问Docker socket,因此默认情况下该进程仍会暴露容器mysql的前端,因此我们将添加标签traefik.enable=false以指定Traefik不应公开此容器。

最后,添加此配置以定义Adminer容器:

docker-compose.yml

代码语言:txt
复制
services:
...

  adminer:
    image: adminer:4.3.1-standalone
    labels:
      - traefik.backend=adminer
      - traefik.frontend.rule=Host:db-admin.example.com
      - traefik.docker.network=proxy
      - traefik.port=8080
    networks:
      - internal
      - proxy
    depends_on:
      - mysql

此容器基于官方Adminer镜像。在networkdepends_on此容器的配置完全符合我们使用什么blog容器。

但是,由于我们将所有流量直接导向Docker主机上的端口80到blog容器,因此我们需要以不同方式配置此容器,以便将流量传输到adminer容器。该traefik.frontend.rule=Host:db-admin.example.com行告诉Traefik检查所请求的主机。如果匹配Traefik 的模式将流量db-admin.example.com路由到adminer容器。保存文件并退出文本编辑器。

接下来,在启动容器之前,在shell中为WORDPRESS_DB_PASSWORD和MYSQL_ROOT_PASSWORD变量设置值:

  • export WORDPRESS_DB_PASSWORD=secure_database_password
  • export MYSQL_ROOT_PASSWORD=secure_database_password

secure_database_password用您想要的数据库密码替换。

设置这些变量后,使用以下命令运行容器docker-compose:

代码语言:txt
复制
$ docker-compose up -d

现在再看一下Traefik管理仪表板。你会看到现在有一个backend和一个frontend显示的服务器:

Populated Traefik dashboard
Populated Traefik dashboard

导航到blog.example.com并替换您的域名example.com。您将被重定向到TLS连接,现在可以完成Wordpress设置:

WordPress setup screen
WordPress setup screen

现在用Adminer浏览器访问db-admin.example.com,再次使用您的域名example.com替换。该mysql容器未显示在外界,但adminer容器仍可以通过internal docker访问它。

在Adminer登录屏幕上,使用用户名root,mysql用于服务器,并使用您为密码设置的MYSQL_ROOT_PASSWORD值。登录后,您将看到Adminer用户界面:

Adminer 连接到MySQL
Adminer 连接到MySQL

这两个站点现在都在monitor.example.com工作,您可以使用仪表板来监视您的应用程序。

结论

在本教程中,您将Traefik配置为将请求代理到Docker容器中的其他应用程序。

Traefik在应用程序容器级别的声明性配置使得配置更多服务变得容易,并且在traefik向代理流量添加新应用程序时无需重新启动容器,因为Traefik会通过它正在监视的Docker socket文件立即进行更改。


参考文献:《How to Use Traefik as a Reverse Proxy for Docker Containers on Ubuntu 16.04》

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
  • 准备
  • 第1步 - 配置和运行Traefik
  • 第2步 - 运行Traefik容器
  • 第3步 - 使用Traefik注册容器
  • 结论
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档