我们了解到 Traefik 中使用 TCP 路由配置需要 SNI,而 SNI 又是依赖 TLS 的,所以需要配置证书才能正常访问 TCP 服务,其实 Traefik 除了支持我们手动配置 TLS 证书之外,还支持自动生成 TLS 证书,本文就来为大家介绍如何在 Traefik 2.0 中配置自动化 HTTPS 服务。

    我们这里就以 Traefik 的 WebUI 为例,之前我们开启了 KubernetesCRD 这个 Provider,通过创建一个 IngressRoute 对象来开启对 WebUI 的访问,资源清单如下所示:
    ingress-admin-webui.yaml

    1. apiVersion: traefik.containo.us/v1alpha1
    2. kind: IngressRoute
    3. metadata:
    4. name: traefik-webui
    5. namespace: kube-system
    6. spec:
    7. entryPoints:
    8. - web
    9. routes:
    10. - match: Host(`traefik.coolops.cn`)
    11. kind: Rule
    12. services:
    13. - name: traefik
    14. port: 8080

    要使用 Let’s Encrypt 来进行自动化 HTTPS,就需要首先开启 ACME,开启 ACME 需要通过静态配置的方式,也就是说可以通过环境变量、启动参数等方式来提供,我们这里还是直接使用启动参数的形式来开启,在 Traefik 的部署文件中添加如下命令行参数:
    traefik.yaml

    1. args:
    2. - --entrypoints.web.Address=:80
    3. - --entrypoints.websecure.Address=:443
    4. - --entrypoints.redis.Address=:6379
    5. - --entrypoints.foo
    6. - --api.insecure=true
    7. - --providers.kubernetescrd
    8. - --api
    9. - --api.dashboard=true
    10. - --accesslog
    11. # 使用 tls 验证这种方式
    12. - --certificatesresolvers.default.acme.tlsChallenge=true
    13. # # 邮箱配置
    14. - --certificatesResolvers.default.acme.email=rookieops@163.com
    15. # # 保存 ACME 证书的位置
    16. - --certificatesResolvers.default.acme.storage="acme.json"
    17. # # 下面是用于测试的ca服务,如果https证书生成成功了,则移除下面参数
    18. - --certificatesresolvers.default.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory

    这里我们使用的是 tlsChallenge 这种 ACME 验证方式,需要注意的是当使用这种验证时,Let’s Encrypt 到 Traefik 443 端口必须是可达的,除了这种验证方式外,还有 httpChallenge 和 dnsChallenge 两种验证方式,更常用的是 http 这种验证方式。

    上面我们相当于指定了一个名为 default 的证书解析器,然后要注意的是,一定要将这里的 WebUI 的域名traefik.rookieops.top解析到 Traefik 的所在节点,解析完成后,重新部署 Traefik:

    1. $ kubectl apply -f traefik.yaml

    部署完成后,我们需要让 WebUI 的域名去监听 443 端口,因为我们这里使用的是 tlsChallenge 这种验证方式,在上面的ingress-admin-webui.yaml文件中新建一个对象,用来监听 443 端口,如下所示:
    ingress-admin-webui.yaml

    1. apiVersion: traefik.containo.us/v1alpha1
    2. kind: IngressRoute
    3. metadata:
    4. name: traefik-webui
    5. namespace: kube-system
    6. spec:
    7. entryPoints:
    8. - web
    9. routes:
    10. - match: Host(`traefik.coolops.cn`)
    11. kind: Rule
    12. services:
    13. - name: traefik
    14. port: 8080
    15. ---
    16. apiVersion: traefik.containo.us/v1alpha1
    17. kind: IngressRoute
    18. metadata:
    19. name: traefik-webui-tls
    20. namespace: kube-system
    21. spec:
    22. entryPoints:
    23. - websecure # 注意这里是websecure这个entryPoint,监控443端口
    24. routes:
    25. - match: Host(`traefik.coolops.cn`)
    26. kind: Rule
    27. services:
    28. - name: traefik
    29. port: 8080
    30. tls:
    31. certResolver: default # 使用我们配置的 default 这个解析器

    这时候就可以用HTTPS去访问服务了。

    注意: Traefik 会自动跟踪其生成的 ACME 证书的到期日期。如果证书过期之前还不到 30 天了,Traefik 会尝试进行自动续订。

    同样的,我们通过 HTTP 协议也是可以访问到的,但是如果需要将 HTTP 请求强制跳转到 HTTPS 的话,就需要借助 Traefik 2.0 的提供的中间件来完成了,如下图。
    12.1.3、自动化HTTPS - 图1
    同样,在上面的 ingress-admin-webui.yaml 文件中添加一个 Middleware 的 CRD 对象,内容如下所示:
    ingress-admin-webui.yaml

    1. apiVersion: traefik.containo.us/v1alpha1
    2. kind: IngressRoute
    3. metadata:
    4. name: traefik-webui
    5. namespace: kube-system
    6. spec:
    7. entryPoints:
    8. - web
    9. routes:
    10. - match: Host(`traefik.coolops.cn`)
    11. kind: Rule
    12. services:
    13. - name: traefik
    14. port: 8080
    15. middlewares: # 使用上面新建的中间件
    16. - name: redirect-https
    17. ---
    18. apiVersion: traefik.containo.us/v1alpha1
    19. kind: IngressRoute
    20. metadata:
    21. name: traefik-webui-tls
    22. namespace: kube-system
    23. spec:
    24. entryPoints:
    25. - websecure # 注意这里是websecure这个entryPoint,监控443端口
    26. routes:
    27. - match: Host(`traefik.coolops.cn`)
    28. kind: Rule
    29. services:
    30. - name: traefik
    31. port: 8080
    32. tls:
    33. certResolver: default # 使用我们配置的 default 这个解析器
    34. ---
    35. apiVersion: traefik.containo.us/v1alpha1
    36. kind: Middleware
    37. metadata:
    38. name: redirect-https
    39. namespace: kube-system
    40. spec:
    41. redirectScheme:
    42. scheme: https

    这里我们就声明了一个名为 redirectSchemea 的中间件,该中间件可以将我们的请求跳转到另外的 scheme 请求,然后将该中间件配置到 HTTP 请求的服务上面。然后重新更新以下配置清单,这时候用HTTP方式去访问就可以自动跳转到HTTPS了。