如何在 Ubuntu 16.04 上将特拉菲克用作 Docker 容器的反向代理

介绍

Docker可以是运行生产中的Web应用程序的有效方法,但您可能希望在同一个Docker主机上运行多个应用程序。

在本教程中,您将使用 Traefik 将请求路由到两个不同的 Web 应用容器:一个 Wordpress容器和一个 Adminer容器,每一个都与MySQL数据库交谈。

前提条件

要跟随本教程,您将需要以下内容:

步骤 1 – 配置和运行 Traefik

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

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

我们将使用htpasswd实用程序来创建这个加密密码. 首先,安装该实用程序,该实用程序包含在apache2-utils包中:

1sudo apt-get install apache2-utils

然后用htpasswd生成密码. 用secure_password代替您想为 Traefik 管理员用户使用的密码:

1htpasswd -nb admin secure_password

该计划的结果将是这样的:

1[secondary_label Output]
2admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/

您将在流量配置文件中使用此输出来为 Traefik 健康检查和监控仪表板设置 HTTP Basic Authentication。

为了配置Traefik服务器,我们将使用TOML格式创建一个名为traefik.toml的新配置文件。 TOML是一种类似于INI文件的配置语言,但它是标准化的。 这个文件允许我们配置Traefik服务器和我们想要使用的各种集成,或 providers。 在本教程中,我们将使用三个Treefik可用的提供商: web, docker和 `acme',用于使用Let's Encrypt来支持TLS。

1nano traefik.toml

首先,添加两个命名的输入点, httphttps,所有后端将默认访问:

1[label traefik.toml]
2defaultEntryPoints = ["http", "https"]

我们将在此文件中稍后配置httphttps输入点。

接下来,配置Web提供商,它为您提供访问仪表板界面,在这里您将粘贴htpasswd命令的输出:

1[label traefik.toml]
2...
3[web]
4address = ":8080"
5  [web.auth.basic]
6  users = ["admin:your_encrypted_password"]

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

web.auth.basic 部分为仪表板配置 HTTP Basic Authentication. 使用您刚刚运行的 htpasswd 命令的输出来指定用户 输入的值。

接下来,定义输入点. entryPoints 部分配置了 Traefik 和代理容器可以收听的地址。

 1[label traefik.toml]
 2...
 3[entryPoints]
 4  [entryPoints.http]
 5  address = ":80"
 6    [entryPoints.http.redirect]
 7      entryPoint = "https"
 8  [entryPoints.https]
 9  address = ":443"
10    [entryPoints.https.tls]

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

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

1[label traefik.toml]
2...
3[acme]
4email = "[email protected]"
5storage = "acme.json"
6entryPoint = "https"
7onHostRule = true
8onDemand = false

这个部分被称为acme,因为 ACME是与 Let’s Encrypt 进行通信以管理证书的协议的名称。为了让 Traefik 为我们的主机生成证书,我们将电子邮件密钥设置为您的电子邮件地址。然后我们指定我们将将从 Let’s Encrypt 获取的信息存储在一个名为acme.json的 JSON 文件中。

最后两个键,即onHostRuleonDemand,决定了Traefik应该如何生成证书。我们希望在创建有指定主机名称的容器后,立即获取我们的证书,这就是onHostRule设置所做的。

保存文件并离开编辑器. 有了所有这些配置,我们可以开火 Traefik。

步骤2 - 运行 Traefik 集装箱

接下来,创建一个Docker网络,让代理商与容器共享。Docker网络是必要的,以便我们可以使用使用Docker Compose运行的应用程序使用它。

1docker network create proxy

当 Traefik 容器启动时,我们会将其添加到该网络中,然后我们可以稍后将额外的容器添加到该网络中,以便 Traefik 进行代理。

接下来,创建一个空的文件,该文件将包含我们的 Let's Encrypt 信息,我们将将此信息共享到容器中,以便 Traefik 可以使用它:

1touch acme.json

Traefik 只能使用此文件,如果容器内的 root 用户有独特的读写访问权限. 要做到这一点,请锁定 acme.json上的权限,以便只有文件所有者才有读写权限。

1chmod 600 acme.json

一旦文件传递到Docker,所有者将自动更改为容器内的 root用户。

最后,用这个命令创建 Traefik 容器:

 1docker run -d \
 2  -v /var/run/docker.sock:/var/run/docker.sock \
 3  -v $PWD/traefik.toml:/traefik.toml \
 4  -v $PWD/acme.json:/acme.json \
 5  -p 80:80 \
 6  -p 443:443 \
 7  -l traefik.frontend.rule=Host:monitor.example.com \
 8  -l traefik.port=8080 \
 9  --network proxy \
10  --name traefik \
11  traefik:1.3.6-alpine --docker

命令有点长,所以让我们打破它。

我们使用d旗在背景中运行容器作为一个戴蒙,然后我们将我们的docker.sock文件共享到容器中,以便Traefik过程可以听取对容器的更改。

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

然后我们设置了两个Docker标签,告诉Traefik将流量导向托管名称monitor.example.com到Traefik容器中的端口:8080,暴露了监控仪表板。

我们将容器的网络设置为代理,我们将容器命名为traefik

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

一个Docker图像的ENTRYPOINT是一个命令,在从图像中创建一个容器时总是运行。在这种情况下,命令是容器内部的traefik二进制。当您启动容器时,您可以将额外的参数传递给该命令。在我们的情况下,我们将参数--docker传递给ENTRYPOINT,以确保docker提供商注册与默认设置。docker提供商允许Traefik在Docker容器前作为代理人。Docker提供商的默认配置对我们来说很好,所以我们不需要在我们的traefik.toml中进行配置。

随着容器的启动,你现在有一个仪表板,你可以访问,以查看你的容器的健康状况。你也可以使用这个仪表板来可视化Treefik注册的前端和后端。 通过指向您的浏览器到https://monitor.example.com来访问监控仪表板。 您将被提示您的用户名和密码,这是 admin和您在步骤 1中配置的密码。

一旦登录,你会看到一个类似于此的界面:

Empty Traefik dashboard

目前还没有太多要看的,但留下这个窗口打开,你会看到内容的变化,当你添加集装箱为 Traefik 工作。

我们现在有我们的 Traefik 代理程序运行,配置为与 Docker 工作,并准备监控其他 Docker 容器。

步骤 3 – 使用 Traefik 注册集装箱

随着 Traefik 容器运行,您已经准备好在其背后运行应用程序,让我们在 Traefik 背后推出以下容器:

  1. 使用 [官方 Wordpress 图像] 的博客(https://hub.docker.com/_/wordpress/)。
  2. 使用 [官方 Adminer 图像] 的数据库管理服务器(https://hub.docker.com/_/adminer/)。

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

1nano docker-compose.yml

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

1[label docker-compose.yml]
2version: "3"
3
4networks:
5  proxy:
6    external: true
7  internal:
8    external: false

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

为了让 Traefik 识别我们的应用程序,它们必须是同一网络的一部分,并且由于我们手动创建了网络,我们通过指定网络名称为代理并将外部设置为真实来引进它,然后我们将另一个网络定义为真实

接下来,我们将定义我们每个服务,一次。让我们从博客容器开始,我们将基于官方的WordPress图像。

 1[label docker-compose.yml]
 2version: "3"
 3...
 4
 5services:
 6  blog:
 7    image: wordpress:4.7.5-apache
 8    environment:
 9      WORDPRESS_DB_PASSWORD:
10    labels:
11      - traefik.backend=blog
12      - traefik.frontend.rule=Host:blog.example.com
13      - traefik.docker.network=proxy
14      - traefik.port=80
15    networks:
16      - internal
17      - proxy
18    depends_on:
19      - mysql

环境键允许您指定将设置在容器内部的环境变量. 通过不为WORDPRESS_DB_PASSWORD设置一个值,我们告诉Docker Compose从我们的壳中获取该值,并在我们创建容器时传输它。

标签部分是您为 Traefik 指定配置值的地方。Docker 标签不会自行做任何事情,但 Traefik 会读取这些标签,以便知道如何处理容器。

traefik.backend指定了Treefik中的后端服务的名称(指的是实际的博客容器)。

  • traefik.frontend.rule=Host:blog.example.com告诉Treefik检查所要求的主机,如果它匹配了blog.example.com的模式,它应该将流量路由到博客容器。
  • traefik.docker.network=proxy指定了哪些网络要搜索Treefik以找到此容器的内部IP。

通过此配置,所有发送到 Docker 主机端口 80 的流量将被路由到博客容器。

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

最后,depends_on键告诉Docker Compose该容器需要启动 _after_它的依赖性正在运行.由于WordPress需要一个数据库来运行,我们必须在启动我们的博客容器之前运行我们的mysql容器。

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

 1[label docker-compose.yml]
 2services:
 3...
 4  mysql:
 5    image: mysql:5.7
 6    environment:
 7      MYSQL_ROOT_PASSWORD:
 8    networks:
 9      - internal
10    labels:
11      - traefik.enable=false

我们正在使用这个容器的官方MySQL 5.7图像。您会注意到,我们再次使用一个环境项目而没有一个值。MYSQL_ROOT_PASSWORDWORDPRESS_DB_PASSWORD变量将需要设置为相同的值,以确保我们的WordPress容器可以与MySQL进行通信。我们不想将mysql容器暴露在Treefik或外部世界,所以我们只将此容器分配到内部网络。由于Treefik可以访问Docker插槽,这个过程仍然会默认地暴露一个对mysql容器的前端,所以我们会添加标签efiktraenable=false来说明Treefik不应该暴露这个容器。

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

 1[label docker-compose.yml]
 2services:
 3...
 4
 5  adminer:
 6    image: adminer:4.3.1-standalone
 7    labels:
 8      - traefik.backend=adminer
 9      - traefik.frontend.rule=Host:db-admin.example.com
10      - traefik.docker.network=proxy
11      - traefik.port=8080
12    networks:
13      - internal
14      - proxy
15    depends_on:
16      - mysql

这个容器的网络depends_on配置完全匹配我们正在使用的博客容器。

然而,由于我们正在将所有流量转移到 Docker 主机上的端口 `80 直接到‘博客’容器,我们需要将此容器配置不同的方式,以便流量转移到我们的 ‘adminer’ 容器。

保存文件并离开文本编辑器。

接下来,在启动容器之前,为WORDPRESS_DB_PASSWORDMYSQL_ROOT_PASSWORD变量设置壳中的值:

1export WORDPRESS_DB_PASSWORD=secure_database_password
2export MYSQL_ROOT_PASSWORD=secure_database_password

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

使用这些变量设置,使用docker-compose运行容器:

1docker-compose up -d

现在再看看Treefik管理仪表板,你会看到现在有两个曝光的服务器的后端前端:

Populated Traefik dashboard

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

WordPress setup screen

现在访问 Adminer 浏览器中的「db-admin.example.com」,再一次将「example.com」替换为您的域名。「mysql」容器不会暴露于外部世界,但「adminer」容器可以通过他们使用「mysql」容器名称作为主机名称共享的「内部」 Docker 网络访问它。

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

Adminer connected to the MySQL database

两个网站都正在工作,您可以使用monitor.example.com的仪表板来监控您的应用程序。

结论

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

Traefik 在应用程序容器级别的声明配置使其易于配置更多的服务,当您将新应用程序添加到代理流量时,无需重新启动traefik容器,因为 Traefik 会通过其监控的 Docker 接口文件立即注意到变化。

要了解有关您可以使用 Traefik 做什么的更多信息,请访问官方 Traefik 文档

Published At
Categories with 技术
comments powered by Disqus