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

简介: 一文搞定快速使用 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



相关文章
|
2月前
|
关系型数据库 MySQL 数据库
Docker Compose-实战
Docker Compose-实战
91 5
|
2月前
|
网络协议 NoSQL Redis
Docker Compose--模板文件
Docker Compose--模板文件
198 29
|
2月前
|
网络协议 Ubuntu Docker
Docker Compose--命令说明
Docker Compose--命令说明
415 30
|
2月前
|
Linux Docker Windows
Docker Compose
Docker Compose
124 29
|
2月前
|
Docker 容器
在openEuler 22.03 LTS上安装Docker CE和Docker Compose
以上就是在openEuler 22.03 LTS上安装Docker CE和Docker Compose的过程。希望这个指南能帮助你顺利完成安装。
428 12
|
4月前
|
弹性计算 运维 Ubuntu
在阿里云ECS云服务器上安装、配置及高效使用Docker与Docker Compose
本文介绍了在阿里云ECS上使用Ubuntu系统安装和配置Docker及Docker Compose的详细步骤。通过这些工具,可以快速部署、弹性扩展和高效管理容器化应用,满足开发和运维需求。内容涵盖Docker的安装、镜像源配置、创建Web程序镜像以及使用Docker Compose部署WordPress等实际操作,并分享了使用体验,展示了阿里云实例的高性能和稳定性。
916 4
|
5月前
|
消息中间件 Kafka Docker
docker compose 安装 kafka
通过本文的步骤,您可以快速在本地使用 Docker Compose 安装并配置 Kafka 和 Zookeeper。Docker Compose 简化了多容器应用的管理,方便快速搭建和测试分布式系统。
642 2
|
8月前
|
运维 开发者 Docker
Docker Compose:简化容器化应用的部署与管理
Docker Compose:简化容器化应用的部署与管理
|
8月前
|
Docker 微服务 容器
使用Docker Compose实现微服务架构的快速部署
使用Docker Compose实现微服务架构的快速部署
201 1
|
8月前
|
前端开发 开发者 Docker
深入探索Docker Compose:简化多容器应用的部署
深入探索Docker Compose:简化多容器应用的部署
220 0