type
status
date
slug
summary
tags
category
icon
password
作者选择Girls Who Code作为Write for捐款计划的一部分接受捐款
Docker是在生产环境中运行web应用程序的有效方法,但您可能希望在同一Docker主机上运行多个应用程序。在这种情况下,您需要设置一个反向代理,因为您只想向世界其他地方公开端口80443
Traefik是一个Docker感知的反向代理,包括自己的监控仪表板。在本教程中,您将使用Traefik将请求路由到两个不同的web应用程序容器:一个Wordpress容器和一个Adminer容器,每个容器都与一个MySQL数据库通信。您将使用让我们加密将Traefik配置为通过HTTPS提供一切服务。
要继续学习本教程,您需要以下内容:
  • 一个Debian 9服务器,按照Debian九的初始服务器设置设置,包括一个sudo非root用户和一个防火墙。
  • Docker安装在您的服务器上,您可以通过以下方式完成如何在Debian 9上安装和使用Docker。
  • Docker Compose是按照How To Install Docker Compose on Debian 9中的说明安装的。
  • 一个域和三个A记录db-adminblogmonitor,每个记录都指向服务器的IP地址。通过阅读DigitalOcean的domains and DNS documentation,您可以了解如何将域指向DigitalOcean Drops。在本教程中,将配置文件和示例中的your_domain替换为您的域。
Traefik项目有一个official Docker image,因此我们将使用它在Docker容器中运行Traefix。
不过,在启动并运行Traefik容器之前,我们需要创建一个配置文件并设置一个加密密码,以便访问监控仪表板。
我们将使用htpasswd实用程序创建此加密密码。首先,安装apache2-utils软件包中包含的实用程序:
sudo apt install apache2-utils
然后用htpasswd生成密码。用您想用于Traefik admin用户的密码替换secure_password:
htpasswd -nb admin secure_password
程序的输出如下所示:
Outputadmin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/
您将在Traefik配置文件中使用此输出来为Traefik健康检查和监视仪表板设置HTTP基本身份验证。复制整个输出行,以便稍后粘贴。
为了配置Traefik服务器,我们将使用TOML格式创建一个名为traefik.toml的新配置文件。TOML是一种类似于INI文件的配置语言,但标准化了。该文件允许我们配置Traefik服务器和各种集成,或者我们想要使用的_providers_。在本教程中,我们将使用Traefik的三个可用提供程序:apidockeracme,它们用于支持使用Let’s Encrypt的TLS。
nano或您最喜欢的文本编辑器中打开新文件:
nano traefik.toml
首先,添加两个命名入口点httphttps,默认情况下,所有后端都可以访问这些入口点:
traefik.toml
defaultEntryPoints = \["http", "https"\]
我们将在本文件稍后部分配置httphttps入口点。
接下来,配置api提供程序,它允许您访问仪表板界面。您将在此处粘贴htpasswd命令的输出:
traefik.toml
... \[entryPoints\] \[entryPoints.dashboard\] address = ":8080" \[entryPoints.dashboard.auth\] \[entryPoints.dashboard.auth.basic\] users = \["admin:your\_encrypted\_password"\] \[api\] entrypoint="dashboard"
仪表板是一个单独的web应用程序,将在Traefik容器中运行。我们将仪表板设置为在端口8080上运行。
entrypoints.dashboard部分配置我们将如何与api提供程序连接,entrypoints.dashboard.auth.basic部分配置仪表板的HTTP基本身份验证。使用刚刚运行的htpasswd命令的输出作为users项的值。您可以使用逗号分隔其他登录名。
我们已经定义了第一个entryPoint,但我们需要为标准HTTP和HTTPS通信定义其他不针对api提供商的内容。entryPoints部分配置Traefik和代理容器可以侦听的地址。将以下行添加到entryPoints标题下的文件中:
traefik.toml
... \[entryPoints.http\] address = ":80" \[entryPoints.http.redirect\] entryPoint = "https" \[entryPoints.https\] address = ":443" \[entryPoints.https.tls\] ...
http入口点处理端口80,而https入口点将端口443用于TLS/SSL。我们自动将端口80上的所有流量重定向到https入口点,以强制所有请求的安全连接。
接下来,添加此部分以配置Let’s Encrypt certificate support for Traefik:
traefik.toml
... \[acme\] email = "your\_email@your\_domain" storage = "acme.json" entryPoint = "https" onHostRule = true \[acme.httpChallenge\] entryPoint = "http"
此部分称为acme,因为ACME是用于与Let’s Encrypt通信以管理证书的协议的名称。Let’s Encrypt服务需要使用有效的电子邮件地址注册,因此为了让Traefik为我们的主机生成证书,请将email密钥设置为您的电子邮件地址。然后,我们指定将从Let’s Encrypt接收的信息存储在一个名为acme.json的JSON文件中。entryPoint密钥需要指向入口点处理端口443,在我们的示例中,该端口是https入口点。
密钥onHostRule指示Traefik应该如何生成证书。我们希望在创建具有指定主机名的容器后立即获取证书,这就是onHostRule设置的作用。
acme.httpChallenge部分允许我们指定让我们加密如何验证应该生成的证书。我们将其配置为通过http入口点作为挑战的一部分提供文件。
最后,让我们通过向文件中添加以下行来配置docker提供程序:
traefik.toml
... \[docker\] domain = "your_domain" watch = true network = "web"
docker提供程序使Traefik能够在Docker容器之前充当代理。我们已经将web网络(我们将很快创建)上的新容器的提供程序配置为watch,并将它们作为your_domain的子域公开。
此时,traefik.toml应具有以下内容:
traefik.toml
defaultEntryPoints = \["http", "https"\] \[entryPoints\] \[entryPoints.dashboard\] address = ":8080" \[entryPoints.dashboard.auth\] \[entryPoints.dashboard.auth.basic\] users = \["admin:your\_encrypted\_password"\] \[entryPoints.http\] address = ":80" \[entryPoints.http.redirect\] entryPoint = "https" \[entryPoints.https\] address = ":443" \[entryPoints.https.tls\] \[api\] entrypoint="dashboard" \[acme\] email = "your\_email@your\_domain" storage = "acme.json" entryPoint = "https" onHostRule = true \[acme.httpChallenge\] entryPoint = "http" \[docker\] domain = "your_domain" watch = true network = "web"
保存文件并退出编辑器。有了所有这些配置,我们可以启动Traefik。
接下来,创建一个Docker网络,让代理与容器共享。Docker网络是必要的,因此我们可以将其用于使用Docker Compose运行的应用程序。我们把这个网络叫做web
docker network create web
当Traefik容器启动时,我们将其添加到此网络。然后,我们可以稍后向该网络添加其他容器,以便Traefik代理。
接下来,创建一个空文件,该文件将保存我们的Let’s Encrypt信息。我们将把它共享到容器中,以便Traefik可以使用它:
touch acme.json
只有当容器内的根用户对该文件具有唯一的读写访问权限时,Traefik才能使用该文件。为此,请锁定acme.json上的权限,以便只有文件所有者具有读写权限。
chmod 600 acme.json
一旦文件传递给Docker,所有者将自动更改为容器内的用户。
最后,使用以下命令创建Traefik容器:
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.your_domain \ -l traefik.port=8080 \ --network web \ --name traefik \ traefik:1.7.6-alpine
命令有点长,我们把它分解一下。
我们使用-d标志在后台作为守护进程运行容器。然后,我们将docker.sock文件共享到容器中,以便Traefik进程可以侦听对容器的更改。我们还将traefik.toml配置文件和我们在容器中创建的acme.json文件共享。
接下来,我们将Docker主机的端口80443映射到Traefik容器中的相同端口,以便Traefiks接收到服务器的所有HTTP和HTTPS流量。
然后,我们设置了两个Docker标签,告诉Traefik将主机名monitor.your_domain的流量引导到Traefix容器内的端口8080,从而显示监控仪表板。
我们将容器的网络设置为web,并将容器命名为traefik
最后,我们对这个容器使用traefik:1.7.6-alpine图像,因为它很小。
Docker图像的ENTRYPOINT是一个命令,在从图像创建容器时始终运行。在这种情况下,该命令是容器中的traefik二进制文件。您可以在启动容器时向该命令传递其他参数,但我们已经在traefik.toml文件中配置了所有设置。
容器启动后,您现在有了一个仪表板,可以访问它来查看容器的运行状况。您还可以使用此仪表板可视化Traefik已注册的前端和后端。通过将浏览器指向https://monitor.your_domain来访问监控仪表板。系统将提示您输入用户名和密码,即admin和您在步骤1中配置的密码。
登录后,您将看到类似的界面:
notion image
现在还没有太多可看的内容,但将此窗口保持打开状态,您将看到内容在添加容器以供Traefik使用时发生变化。
我们现在已经运行了Traefik代理,配置为与Docker一起工作,并准备好监视其他Docker容器。让我们启动一些容器,让Traefik充当其代理。
随着Traefik容器的运行,您就可以运行其背后的应用程序了。让我们在Traefik后面启动以下容器:
1.Wordpress官方图片博客(https://hub.docker.com/_/wordpress/)。
2.使用官方管理员图像的数据库管理服务器。
我们将使用Docker Compose使用docker-compose.yml文件管理这两个应用程序。在编辑器中打开docker-compose.yml文件:
nano docker-compose.yml
在文件中添加以下行,以指定我们将使用的版本和网络:
docker-compose.yml
version: "3" networks: web: external: true internal: external: false
我们使用Docker Compose版本3,因为它是Compose文件格式的最新主要版本。
为了让Traefik识别我们的应用程序,它们必须是同一个网络的一部分,由于我们手动创建了网络,我们通过指定网络名称web并将external设置为true将其拉入。然后我们定义另一个网络,以便我们可以将公开的容器连接到我们不会通过Traefix公开的数据库容器。我们将这个网络称为internal
接下来,我们将逐一定义services。让我们从blog容器开始,我们将基于官方的WordPress图像。将此配置添加到文件:
docker-compose.yml
version: "3" ... services: blog: image: wordpress:4.9.8-apache environment: WORDPRESS\_DB\_PASSWORD: labels: - traefik.backend=blog - traefik.frontend.rule=Host:blog.your_domain - traefik.docker.network=web - traefik.port=80 networks: - internal - web depends_on: - mysql
environment键允许您指定将在容器内设置的环境变量。通过不将值设置为WORDPRESS_DB_PASSWORD,我们告诉Docker Compose从shell中获取值,并在创建容器时传递它。在启动容器之前,我们将在shell中定义这个环境变量。这样我们就不会将密码硬编码到配置文件中。
labels部分用于指定Traefik的配置值。Docker标签本身不会做任何事情,但Traefik会阅读这些内容,因此它知道如何处理容器。以下是这些标签的作用:
  • traefik.backend指定Traefik中后端服务的名称(它指向实际的blog容器)。
  • traefik.frontend.rule=Host:blog.your_domain告诉Traefik检查请求的主机,如果它与blog.your_domain模式匹配,则应将流量路由到blog容器。
  • traefik.docker.network=web指定在哪个网络下查找Traefik以查找此容器的内部IP。由于我们的Traefik容器可以访问所有Docker信息,如果我们不指定这一点,它可能会占用internal网络的IP。
  • traefik.port指定Traefik应用于将流量路由到此容器的公开端口。
通过此配置,发送到Docker主机端口80的所有流量将路由到blog容器。
我们将该容器分配给两个不同的网络,以便Traefik可以通过web网络找到它,并且可以通过internal网络与数据库容器通信。
最后,depends_on键告诉Docker Compose,该容器需要在其依赖项运行后启动。因为WordPress需要一个数据库来运行,所以我们必须在启动blog容器之前运行mysql容器。
接下来,通过将此配置添加到文件来配置MySQL服务:
docker-compose.yml
services: ... mysql: image: mysql:5.7 environment: MYSQL\_ROOT\_PASSWORD: networks: - internal labels: - traefik.enable=false
我们正在为这个容器使用官方的MySQL 5.7图像。你会注意到,我们再次使用了一个没有值的environment项。MYSQL_ROOT_PASSWORDWORDPRESS_DB_PASSWORD变量需要设置为相同的值,以确保我们的WordPress容器可以与MySQL通信。我们不想将mysql容器暴露给Traefik或外界,因此我们只将此容器分配给internal网络。由于Traefik可以访问Docker套接字,因此默认情况下,该过程仍将公开mysql容器的前端,因此我们将添加标签traefik.enable=false,以指定Traefix不应公开此容器。
最后,添加此配置以定义adminer容器:
docker-compose.yml
services: ... adminer: image: adminer:4.6.3-standalone labels: - traefik.backend=adminer - traefik.frontend.rule=Host:db-admin.your_domain - traefik.docker.network=web - traefik.port=8080 networks: - internal - web depends_on: - mysql
此容器基于官方管理员图像。该容器的networkdepends_on配置与我们用于blog容器的配置完全匹配。
然而,由于我们将所有到Docker主机上端口80的流量直接定向到blog容器,因此我们需要对该容器进行不同的配置,以使流量到达adminer容器。第traefik.frontend.rule=Host:db-admin.your_domain行告诉Traefik检查请求的主机。如果匹配db-admin.your_domain的模式,Traefik将把流量路由到adminer集装箱。
此时,docker-compose.yml应具有以下内容:
docker-compose.yml
version: "3" networks: web: external: true internal: external: false services: blog: image: wordpress:4.9.8-apache environment: WORDPRESS\_DB\_PASSWORD: labels: - traefik.backend=blog - traefik.frontend.rule=Host:blog.your_domain - traefik.docker.network=web - traefik.port=80 networks: - internal - web depends_on: - mysql mysql: image: mysql:5.7 environment: MYSQL\_ROOT\_PASSWORD: networks: - internal labels: - traefik.enable=false adminer: image: adminer:4.6.3-standalone labels: - traefik.backend=adminer - traefik.frontend.rule=Host:db-admin.your_domain - traefik.docker.network=web - traefik.port=8080 networks: - internal - web depends_on: - mysql
保存文件并退出文本编辑器。
接下来,在启动容器之前,在shell中设置WORDPRESS_DB_PASSWORDMYSQL_ROOT_PASSWORD变量的值:
export WORDPRESS\_DB\_PASSWORD=secure\_database\_password export MYSQL\_ROOT\_PASSWORD=secure\_database\_password
用所需的数据库密码替换secure_database_password。记住对WORDPRESS_DB_PASSWORDMYSQL_ROOT_PASSWORD使用相同的密码。
设置这些变量后,使用docker-compose运行容器:
docker-compose up -d
现在再看看Traefik管理仪表板。您将看到,现在两个公开的服务器分别有backendfrontend:
notion image
导航到blog.your_domain,用您的域替换your_domain。您将被重定向到TLS连接,现在可以完成Wordpress设置:
notion image
现在通过在浏览器中访问db-admin.your_domain访问Adminer,再次用您的域替换your_domainmysql容器不暴露于外界,但adminer容器可以通过internal Docker网络访问它,他们使用mysql容器名作为主机名共享该网络。
在管理员登录屏幕上,使用用户名root,使用mysql作为服务器,并使用您为MYSQL_ROOT_PASSWORD设置的值作为密码。登录后,您将看到管理员用户界面:
notion image
这两个网站现在都在工作,你可以使用monitor.your_domain的仪表板来监视你的应用程序。
在本教程中,您将Traefik配置为将请求代理到Docker容器中的其他应用程序。
Traefik在应用程序容器级别的声明性配置可以轻松配置更多服务,并且当您将新应用程序添加到代理通信时,无需重新启动traefik容器,因为Traefek通过其监视的Docker套接字文件立即注意到更改。
要了解有关使用Traefik可以做什么的更多信息,请访问官方的Traefik文档。如果你想进一步探索Docker容器,请查看如何在Ubuntu 18.04上设置私有Docker注册表或如何使用Nginx保护Containerized Node.js应用程序,让我们加密和Docker Compose。
洗碗机_我对洗碗机一窍不通 家中新房装修上洗碗机我该如何选?「奇技淫巧」 Traefik “智能”反向代理(解放苦于配置的双手)