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



相关文章
|
14天前
|
存储 监控 安全
【专栏】探讨Docker Compose的核心概念、使用方法及最佳实践,助你轻松驾驭容器编排的世界
【4月更文挑战第27天】Docker Compose是款轻量级容器编排工具,通过YAML文件统一管理多容器应用。本文分三部分深入讨论其核心概念(服务、网络、卷和配置)、使用方法及最佳实践。从快速入门到高级特性,包括环境隔离、CI/CD集成、资源管理和安全措施。通过案例分析展示如何构建多服务应用,助力高效容器编排与管理。
|
4天前
|
前端开发 API 数据库
【Docker专栏】Docker Compose实战:编排多容器应用
【5月更文挑战第7天】Docker Compose是Docker的多容器管理工具,通过YAML文件简化多容器应用部署。它能一键启动、停止服务,保证开发、测试和生产环境的一致性。安装后,创建`docker-compose.yml`文件定义服务,如示例中的web和db服务。使用`docker-compose up -d`启动服务,通过`docker-compose ps`、`stop`、`down`和`logs`命令管理服务。
【Docker专栏】Docker Compose实战:编排多容器应用
|
10天前
|
负载均衡 Cloud Native Linux
Docker部署Traefik结合内网穿透远程访问Dashboard界面
Docker部署Traefik结合内网穿透远程访问Dashboard界面
|
11天前
|
存储 Linux 文件存储
Linux使用Docker部署Traefik容器并实现远程访问管理界面-1
Linux使用Docker部署Traefik容器并实现远程访问管理界面
|
11天前
|
Shell 应用服务中间件 nginx
6.Docker Compose
6.Docker Compose
|
17天前
|
NoSQL Redis Docker
[docker] Compose 简介
[docker] Compose 简介
|
22天前
|
网络协议 Linux 文件存储
Linux系统使用Docker搭建Traefik结合内网穿透实现公网访问管理界面
Linux系统使用Docker搭建Traefik结合内网穿透实现公网访问管理界面
|
22天前
|
NoSQL 数据库 Docker
《Docker 简易速速上手小册》第5章 Docker Compose 与服务编排(2024 最新版)
《Docker 简易速速上手小册》第5章 Docker Compose 与服务编排(2024 最新版)
46 0
|
1月前
|
NoSQL Redis Docker
Docker Compose、Swarm、Stack、Secret、Config
Docker Compose、Swarm、Stack、Secret、Config
|
2月前
|
存储 机器学习/深度学习 中间件
快速上手 Elasticsearch:Docker Compose 部署详解
本文介绍了如何使用Docker Compose快速搭建Elasticsearch学习环境。Elasticsearch是一款用于实时搜索和分析的分布式中间件,适用于多种场景,如搜索、日志分析、机器学习等。首先,创建docker网络,拉取最新版8.12.2镜像。接着,编写docker-compose.yml文件,配置单节点集群,设置端口映射、内存限制及数据卷挂载。然后,创建并配置数据卷目录,允许远程访问和跨域。最后,启动服务并验证,通过浏览器访问确认服务运行正常。本文为初学者提供了一个简便的Elasticsearch部署方法。
220 4
快速上手 Elasticsearch:Docker Compose 部署详解