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

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 一文搞定快速使用 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月前
|
关系型数据库 MySQL API
|
2月前
|
缓存 监控 持续交付
|
27天前
|
运维 开发者 Docker
Docker Compose:简化容器化应用的部署与管理
Docker Compose:简化容器化应用的部署与管理
|
27天前
|
Docker 微服务 容器
使用Docker Compose实现微服务架构的快速部署
使用Docker Compose实现微服务架构的快速部署
54 1
|
1月前
|
负载均衡 监控 开发者
深入浅出:掌握 Docker Compose 的高级用法
【10月更文挑战第22天】本文深入探讨了 Docker Compose 的高级用法,包括环境变量、服务扩展、网络配置和数据卷管理。通过实例详细介绍了如何利用这些功能提升开发效率和应用部署的灵活性。适合希望深入了解 Docker Compose 的开发者阅读。
|
27天前
|
NoSQL Redis Docker
【赵渝强老师】使用Docker Compose管理容器
Docker Compose 通过 YAML 文件管理多个容器,简化复杂系统的部署和管理。本文介绍了 Docker Compose 的基本概念,并通过一个包含 Redis DB 和 Python Web 模块的示例,展示了如何使用 Docker Compose 部署和管理多容器应用。手动部署和 Docker Compose 部署的对比突显了 Docker Compose 在系统复杂度增加时的优势。
|
27天前
|
前端开发 开发者 Docker
深入探索Docker Compose:简化多容器应用的部署
深入探索Docker Compose:简化多容器应用的部署
59 0
|
7月前
|
存储 机器学习/深度学习 中间件
快速上手 Elasticsearch:Docker Compose 部署详解
本文介绍了如何使用Docker Compose快速搭建Elasticsearch学习环境。Elasticsearch是一款用于实时搜索和分析的分布式中间件,适用于多种场景,如搜索、日志分析、机器学习等。首先,创建docker网络,拉取最新版8.12.2镜像。接着,编写docker-compose.yml文件,配置单节点集群,设置端口映射、内存限制及数据卷挂载。然后,创建并配置数据卷目录,允许远程访问和跨域。最后,启动服务并验证,通过浏览器访问确认服务运行正常。本文为初学者提供了一个简便的Elasticsearch部署方法。
860 4
快速上手 Elasticsearch:Docker Compose 部署详解
|
7月前
|
存储 数据可视化 数据安全/隐私保护
使用 Docker Compose 部署 Docker Registry
【1月更文挑战第2天】 在内网环境中,我们期望能够在本地共享镜像。为了解决这一问题,Docker Registry成为了我们的救星。Docker Registry是一个用于存储和管理Docker镜像的开源工具。通过在本地部署Docker Registry,您可以轻松地构建、存储和分享自己的Docker镜像。
417 3
使用 Docker Compose 部署 Docker Registry
|
7月前
|
Java Docker 微服务
如何使用Docker和Docker Compose部署微服务
【2月更文挑战第12天】
750 0