一文搞定快速使用 Docker Compose 玩转 Traefik v2(二)

本文涉及的产品
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 一文搞定快速使用 Docker Compose 玩转 Traefik v2(二)

Let's Encrypt 证书,HTTP challenge



微信图片_20220611113528.png


  • LE - Let's Encrypt. 提供免费证书的服务
  • Certificate - 存储在服务器文件中的加密密钥,允许进行加密通信并确认身份
  • ACME - 一种协议(精确商定的通信方式),以协商来自 LE 的证书。它是 traefik 的一部分。
  • DNS - 互联网上的服务器,将域名转换为 IP 地址


Traefik 使用 ACME 向 LE 请求特定域的证书,如 example.com。LE 用一些随机生成的文本来回答,然后 traefik 把这些文本放在服务器的特定位置。然后,LE 向 DNS 互联网服务器询问 example.com,结果指向了某个 IP 地址。LE 通过端口 80/443 查找该 IP 地址,查找包含该随机文本的文件。

如果存在,那么这证明了要求证书的人都控制了服务器和域,因为它显示了对 DNS 记录的控制权。证书已颁发,有效期为 3 个月,traefik 将在少于 30 天的时间内自动尝试续订。


现在我们来看看该怎么做。


创建一个具有 600 权限的空 acme.json 文件


该文件将存储证书以及有关证书的所有信息。


touch acme.json && chmod 600 acme.json


在 traefik.yml 中添加 443 入口点和证书解析器


在 entrypoint 部分中,新的 entrypoint 被添加为 websecure,端口 443

certificatesResolvers 是一个配置部分,它告诉 traefik 如何使用 acme resolver 获取证书。


certificatesResolvers:
  lets-encr:
    acme:
      #caServer: https://acme-staging-v02.api.letsencrypt.org/directory
      storage: acme.json
      email: whatever@gmail.com
      httpChallenge:
        entryPoint: web


  • 解析器的名称为 lets-encr,并使用 acme
  • 注释掉了 staging caServer 使 LE 颁发了一个 staging 证书,这是一个无效的证书,不会给绿锁,但没有限制,所以很适合测试。如果它在工作,它会说,我们加密。
  • Storage 告诉在哪里存储给定的证书 - acme.json
  • 邮件是 LE 发送证书过期通知的地方
  • httpChallenge 有一个入口点,因此 acme 在端口 80 上执行 http challenge

这就是 acme 所需要的一切

traefik.yml


## STATIC CONFIGURATION
log:
  level: INFO
api:
  insecure: true
  dashboard: true
entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
certificatesResolvers:
  lets-encr:
    acme:
      #caServer: https://acme-staging-v02.api.letsencrypt.org/directory
      storage: acme.json
      email: whatever@gmail.com
      httpChallenge:
        entryPoint: web


暴露/映射端口 443 并将 acme.json 挂载在 traefik-docker-compose.yml 中

注意:acme.json 不是 :ro - 只读

traefik-docker-compose.yml


version: "3.7"
services:
  traefik:
    image: "traefik:v2.1"
    container_name: "traefik"
    hostname: "traefik"
    env_file:
      - .env
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./traefik.yml:/traefik.yml:ro"
      - "./acme.json:/acme.json"
networks:
  default:
    external:
      name: $DEFAULT_NETWORK


向容器添加所需的标签


与第一章中的纯 HTTP 相比,它只是将路由器的入口点从 web 更改为 websecure, 并将名为 lets-encr 的证书解析器分配给现有路由器

whoami-docker-compose.yml


version: "3.7"
services:
  whoami:
    image: "containous/whoami"
    container_name: "whoami"
    hostname: "whoami"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.rule=Host(`whoami.$MY_DOMAIN`)"
      - "traefik.http.routers.whoami.tls.certresolver=lets-encr"
networks:
  default:
    external:
      name: $DEFAULT_NETWORK


nginx-docker-compose.yml


version: "3.7"
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    hostname: nginx
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.entrypoints=websecure"
      - "traefik.http.routers.nginx.rule=Host(`nginx.$MY_DOMAIN`)"
      - "traefik.http.routers.nginx.tls.certresolver=lets-encr"
networks:
  default:
    external:
      name: $DEFAULT_NETWORK


运行容器


稍等一分钟

容器现在只能在 https 上工作并且具有 greenlock

检查 acme.json 的内容

如果要重新开始,请删除acme.json


Let's Encrypt 证书在 cloudflare 上 DNS challenge



微信图片_20220611113629.png


  • LE - Let's Encrypt. 提供免费证书的服务
  • Certificate - 存储在服务器文件中的加密密钥,允许进行加密通信并确认身份
  • ACME - 一种协议(精确商定的通信方式),以协商来自 LE 的证书。它是 traefik 的一部分。
  • DNS - 互联网上的服务器,将域名转换为 IP 地址


Traefik 使用 ACME 向 LE 请求特定域的证书,如 example.com。LE 用一些随机生成的文本来回答,然后 traefik 把这些文本放在服务器的特定位置。然后,LE 向 DNS 互联网服务器询问 example.com,结果指向了某个 IP 地址。LE 通过端口 80/443 查找该 IP 地址,查找包含该随机文本的文件。


如果存在,那么这证明了要求证书的人都控制了服务器和域,因为它显示了对 DNS 记录的控制权。证书已颁发,有效期为 3 个月,traefik 将在少于 30 天的时间内自动尝试续订。


与 httpChallenge 相比的好处是能够使用通配符证书。这些是验证所有子域 *.example.com 的证书 另外,无需打开任何端口。

但 traefik 需要能够对 DNS 记录进行自动更改,因此需要管理网站 DNS 的人对此提供支持。这就是为什么选择 cloudflare。

现在我们来看看该怎么做。为所有规划的子域添加类型 A DNS 记录

[whoami, nginx, *] 是示例子域,每个子域都应有一个指向 traefik IP 的 A 记录。


创建一个具有 600 权限的空 acme.json 文件


touch acme.json && chmod 600 acme.json


将 443 入口点和证书解析器添加到 traefik.yml


在 entrypoint 部分中,新的 entrypoint 被添加为 websecure,端口 443

certificatesResolvers 是一个配置部分,它告诉 traefik 如何使用 acme resolver 获取证书。


certificatesResolvers:
lets-encr:
  acme:
    #caServer: https://acme-staging-v02.api.letsencrypt.org/directory
    email: whatever@gmail.com
    storage: acme.json
    dnsChallenge:
      provider: cloudflare
      resolvers:
        - "1.1.1.1:53"
        - "8.8.8.8:53"


  • 解析器的名称为 lets-encr,并使用 acme
  • 注释掉了 staging caServer 使 LE 颁发了一个 staging 证书,这是一个无效的证书,不会给绿锁,但没有限制,所以很适合测试。如果它在工作,它会说,我们加密。
  • Storage 告诉在哪里存储给定的证书 - acme.json
  • 邮件是 LE 发送证书过期通知的地方
  • dnsChallenge 是由一个 provider 指定的,


在这个例子中是 cloudflare。每个提供程序在 .env 文件中需要不同名称的环境变量, 但这是稍后的内容,这里只需要提供程序的名称

  • 解析器是在挑战期间使用的知名 DNS 服务器的 IP

traefik.yml


## STATIC CONFIGURATION
log:
  level: INFO
api:
  insecure: true
  dashboard: true
entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"
providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
certificatesResolvers:
  lets-encr:
    acme:
      #caServer: https://acme-staging-v02.api.letsencrypt.org/directory
      email: whatever@gmail.com
      storage: acme.json
      dnsChallenge:
        provider: cloudflare
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"


.env 文件中添加所需的变量


我们知道根据支持的提供商列表添加哪些变量

对于 cloudflare 变量是

  • CF_API_EMAIL - cloudflare login
  • CF_API_KEY - global api key

.env


MY_DOMAIN=example.com
DEFAULT_NETWORK=traefik_net
CF_API_EMAIL=whateverbastard@gmail.com
CF_API_KEY=8d08c87dadb0f8f0e63efe84fb115b62e1abc


暴露/映射端口 443 并将 acme.json 挂载在 traefik-docker-compose.yml 中

注意:acme.json 不是 :ro - 只读

traefik-docker-compose.yml


version: "3.7"
services:
  traefik:
    image: "traefik:v2.1"
    container_name: "traefik"
    hostname: "traefik"
    env_file:
      - .env
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./traefik.yml:/traefik.yml:ro"
      - "./acme.json:/acme.json"
  networks:
    default:
      external:
        name: $DEFAULT_NETWORK


在容器上添加所需的标签


与第一章中简单的 http 相比

  • 路由器的入口点从 web 切换到 websecure
  • 分配给路由器的名为 lets-encr 的证书解析器
  • 定义将要获得证书的主域的标签,在这里是 whoami.example.com,域名是从 .env 文件中提取的

whoami-docker-compose.yml


version: "3.7"
services:
  whoami:
    image: "containous/whoami"
    container_name: "whoami"
    hostname: "whoami"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.rule=Host(`whoami.$MY_DOMAIN`)"
      - "traefik.http.routers.whoami.tls.certresolver=lets-encr"
      - "traefik.http.routers.whoami.tls.domains[0].main=whoami.$MY_DOMAIN"
networks:
  default:
    external:
      name: $DEFAULT_NETWORK


nginx-docker-compose.yml


version: "3.7"
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    hostname: nginx
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.entrypoints=websecure"
      - "traefik.http.routers.nginx.rule=Host(`nginx.$MY_DOMAIN`)"
      - "traefik.http.routers.nginx.tls.certresolver=lets-encr"
      - "traefik.http.routers.nginx.tls.domains[0].main=nginx.$MY_DOMAIN"
networks:
  default:
    external:
      name: $DEFAULT_NETWORK


运行容器


docker-compose -f traefik-docker-compose.yml up -d
docker-compose -f whoami-docker-compose.yml up -d
docker-compose -f nginx-docker-compose.yml up -d


DNS 挑战的全部重点就是获取通配符!


很公平

因此,对于通配符,这些标签将加入 traefik compose。

  • 与以前一样使用相同的 lets-encr 证书解析器,它在 traefik.yml 中定义
  • 子域(*.example.com)的通配符被设置为要获取证书的主域
  • 裸域(只是简单的example.com)设置为sans(主题备用名称)


同样,您确实需要 * .example.comexample.com

在 DNS 控制面板中设置为 A 记录,指向 traefik 的 IP

traefik-docker-compose.yml


version: "3.7"
services:
  traefik:
    image: "traefik:v2.1"
    container_name: "traefik"
    hostname: "traefik"
    env_file:
      - .env
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./traefik.yml:/traefik.yml:ro"
      - "./acme.json:/acme.json"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.tls.certresolver=lets-encr"
      - "traefik.http.routers.traefik.tls.domains[0].main=*.$MY_DOMAIN"
      - "traefik.http.routers.traefik.tls.domains[0].sans=$MY_DOMAIN"
networks:
  default:
    external:
      name: $DEFAULT_NETWORK


现在,如果容器想作为子域进行访问,则只需要一个具有 url 规则的常规路由器,位于 443 端口入口点,并使用相同的 lets-encr 证书解析器

whoami-docker-compose.yml


version: "3.7"
services:
  whoami:
    image: "containous/whoami"
    container_name: "whoami"
    hostname: "whoami"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.rule=Host(`whoami.$MY_DOMAIN`)"
      - "traefik.http.routers.whoami.tls.certresolver=lets-encr"
networks:
  default:
    external:
      name: $DEFAULT_NETWORK


nginx-docker-compose.yml


version: "3.7"
services:
  nginx:
    image: nginx:latest
    container_name: nginx
    hostname: nginx
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.entrypoints=websecure"
      - "traefik.http.routers.nginx.rule=Host(`nginx.$MY_DOMAIN`)"
      - "traefik.http.routers.nginx.tls.certresolver=lets-encr"
networks:
  default:
    external:
      name: $DEFAULT_NETWORK


这是apache,但这次运行在裸域 example.com

apache-docker-compose.yml


version: "3.7"
services:
  apache:
    image: httpd:latest
    container_name: apache
    hostname: apache
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.apache.entrypoints=websecure"
      - "traefik.http.routers.apache.rule=Host(`$MY_DOMAIN`)"
      - "traefik.http.routers.apache.tls.certresolver=lets-encr"
networks:
  default:
    external:
      name: $DEFAULT_NETWORK


转发 HTTP 流量到 HTTPS


微信图片_20220611113732.png


http 停止使用 https 设置,最好将 http(80) 重定向到 https(443)。

Traefik 有专门的中间件 — redirectscheme。


traefik.yml 本身设置为文件提供程序时,可以在动态部分的 traefik.yml 中的多个位置声明此重定向。

或在任何正在运行的容器中使用标签,此示例在 traefik compose 中进行操作。

使用 traefik 中的标签添加新路由和重定向方案


- "traefik.enable=true"


在这个 traefik 容器上启用 traefik,不是说这里需要到服务的典型路由,而是说没有它其他标签就不能工作


- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"


创建一个名为 redirect-to-https 的新中间件,输入 “redirectscheme” 并为其分配方案 https


- "traefik.http.routers.redirect-https.rule=hostregexp(`{host:.+}`)"


创建一个名为 redirect-https 的新路由,并使用一个正则表达式规则来捕获所有传入请求


- "traefik.http.routers.redirect-https.entrypoints=web"


声明此路由器在哪个入口点上侦听 - Web(端口80)


- "traefik.http.routers.redirect-https.middlewares=redirect-to-https"


将新创建的 redirectscheme 中间件分配给此新创建的路由。

traefik-docker-compose.yml


version: "3.7"
services:
  traefik:
    image: "traefik:v2.1"
    container_name: "traefik"
    hostname: "traefik"
    env_file:
      - .env
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./traefik.yml:/traefik.yml:ro"
      - "./acme.json:/acme.json"
    labels:
      - "traefik.enable=true"
      ## DNS CHALLENGE
      - "traefik.http.routers.traefik.tls.certresolver=lets-encr"
      - "traefik.http.routers.traefik.tls.domains[0].main=*.$MY_DOMAIN"
      - "traefik.http.routers.traefik.tls.domains[0].sans=$MY_DOMAIN"
      ## HTTP REDIRECT
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.routers.redirect-https.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.redirect-https.entrypoints=web"
      - "traefik.http.routers.redirect-https.middlewares=redirect-to-https"
networks:
  default:
    external:
      name: $DEFAULT_NETWORK



相关文章
|
1月前
|
Kubernetes 监控 Docker
Docker Compose与Kubernetes的比较
【6月更文挑战第11天】本文探讨了Docker Compose与Kubernetes在容器编排中的角色。Docker Compose适合简单部署和开发环境,提供一键启动多容器的便利;而Kubernetes则适用于大规模生产环境,具备自动化运维、集群管理和负载均衡等功能。Python在容器编排中扮演重要角色,示例代码展示了如何使用Python的Docker SDK和Kubernetes客户端进行部署、扩展和日志管理。通过Python,开发者可以实现自定义监控、自动水平扩展和实时日志监控等高级功能,增强了容器编排的灵活性和自动化。
55 1
Docker Compose与Kubernetes的比较
|
12天前
|
运维 Kubernetes 负载均衡
docker、docker compose、k8s有什么区别?
Docker 这个东西所扮演的角色,容易理解,它是一个容器引擎,也就是说实际上我们的容器最终是由Docker创建,运行在Docker中,其他相关的容器技术都是以Docker为基础,它是我们使用其他容器技术的核心。
47 1
|
18天前
|
安全 关系型数据库 开发者
Docker Compose凭借其简单易用的特性,已经成为开发者在构建和管理多容器应用时不可或缺的工具。
Docker Compose是容器编排利器,简化多容器应用管理。通过YAML文件定义服务、网络和卷,一键启动应用环境。核心概念包括服务(组件集合)、网络(灵活通信)、卷(数据持久化)。实战中,编写docker-compose.yml,如设置Nginx和Postgres服务,用`docker-compose up -d`启动。高级特性涉及依赖、环境变量、健康检查和数据持久化。最佳实践涵盖环境隔离、CI/CD、资源管理和安全措施。案例分析展示如何构建微服务应用栈,实现一键部署。Docker Compose助力开发者高效驾驭复杂容器场景。
32 1
|
18天前
|
存储 监控 安全
Docker Compose:轻松实现容器编排的利器
【7月更文挑战第2天】 1. **基础与概念**:服务(多容器实例)、网络(灵活通信)、卷(数据持久化)和配置(安全管理)。 2. **实战指南**:安装Compose,编写`docker-compose.yml`文件,启动应用,并介绍依赖、环境变量、健康检查和数据持久化。 3. **最佳实践**:环境隔离、CI/CD集成、资源管理、日志监控、安全策略及案例分析,展示完整应用栈搭建。
38 1
|
27天前
|
NoSQL Redis Docker
使用 Docker Compose 接管现有容器的文档
使用 Docker Compose 接管现有容器的文档
28 2
|
21天前
|
消息中间件 监控 RocketMQ
Docker Compose 一键快速部署 RocketMQ
Docker Compose 一键快速部署 RocketMQ
34 0
|
1月前
|
关系型数据库 持续交付 数据库
简化多容器应用部署:深入理解 Docker Compose
简化多容器应用部署:深入理解 Docker Compose
167 0
|
2月前
|
存储 机器学习/深度学习 中间件
快速上手 Elasticsearch:Docker Compose 部署详解
本文介绍了如何使用Docker Compose快速搭建Elasticsearch学习环境。Elasticsearch是一款用于实时搜索和分析的分布式中间件,适用于多种场景,如搜索、日志分析、机器学习等。首先,创建docker网络,拉取最新版8.12.2镜像。接着,编写docker-compose.yml文件,配置单节点集群,设置端口映射、内存限制及数据卷挂载。然后,创建并配置数据卷目录,允许远程访问和跨域。最后,启动服务并验证,通过浏览器访问确认服务运行正常。本文为初学者提供了一个简便的Elasticsearch部署方法。
505 4
快速上手 Elasticsearch:Docker Compose 部署详解
|
2月前
|
存储 数据可视化 数据安全/隐私保护
使用 Docker Compose 部署 Docker Registry
【1月更文挑战第2天】 在内网环境中,我们期望能够在本地共享镜像。为了解决这一问题,Docker Registry成为了我们的救星。Docker Registry是一个用于存储和管理Docker镜像的开源工具。通过在本地部署Docker Registry,您可以轻松地构建、存储和分享自己的Docker镜像。
249 3
使用 Docker Compose 部署 Docker Registry
|
9月前
|
SQL 关系型数据库 数据库
SQL Server 简介与 Docker Compose 部署
SQL Server 是由微软公司开发的一款强大的关系型数据库管理系统(RDBMS),广泛应用于企业级应用程序和数据存储。使用 Docker Compose,您可以轻松地将 SQL Server 实例部署到容器化环境中,并方便地进行数据库管理。在本文中,我将简要介绍 SQL Server 的基本概念,并详细阐述如何使用 Docker Compose 部署 SQL Server 容器。
294 2
SQL Server 简介与 Docker Compose 部署