cnych / qikqiak.com

关注 chatgpt、容器、kubernetes、devops、python、golang、微服务等技术 🎉🎉🎉
https://www.qikqiak.com
1.33k stars 346 forks source link

Traefik 2.0 实现自动化 HTTPS #132

Open cnych opened 4 years ago

cnych commented 4 years ago

https://www.qikqiak.com/post/automatic-https-with-traefik2/

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

luojz1 commented 4 years ago

请教下题主,我自己有证书不用acme这样自动产生的方式,该怎么做,现在2.0资料好少.....

cnych commented 4 years ago

@luojz1 有自己的证书就和以前一样通过Secret创建下,然后挂载到 IngressRoute 的 tls 下面的 secretName 上就可以。

luojz1 commented 4 years ago

@cnych @luojz1 有自己的证书就和以前一样通过Secret创建下,然后挂载到 IngressRoute 的 tls 下面的 secretName 上就可以。

感谢楼主回答我哈,一直以为还要挂configmap呢,我去试一下.

snycloud commented 4 years ago

请教一下楼主, 我按照你的步骤安装下来其他都没有问题但是生成的证书好像不对, 没有申请到 lets encrypt 的证书, 而是TRAEFIK DEFAULT CERT, 自行签名的根证书, 是咋回事, 怎么排查

luojz1 commented 4 years ago

@cnych @luojz1 有自己的证书就和以前一样通过Secret创建下,然后挂载到 IngressRoute 的 tls 下面的 secretName 上就可以。

题主最后我用1.7的版本做完了自签名HTTPS的实验,traefik国内感觉还是有点小众,官方文档又乱,2.0这次更新变动又很大,慢慢做实验验证真的太浪费时间了,再等等文档都完善了,我再尝试2.0的实验吧,再次感谢题主即使的解答!!

starsliao commented 4 years ago

大佬好,请问下有使用dnsChallenge.provider=dnspod 的方式来自动生成证书么? 我使用一直报错:

time="2019-11-03T20:18:29Z" level=debug msg="legolog: [WARN] [aaa.xxx.com] acme: error cleaning up: API call failed: json: cannot unmarshal string into Go struct field DomainInfo.info.mine_total of type int "
time="2019-11-03T20:18:29Z" level=error msg="Unable to obtain ACME certificate for domains \"aaa.xxx.com\": unable to generate a certificate for the domains [aaa.xxx.com]: acme: Error -> One or more domains had a problem:\n[aaa.xxx.com] [aaa.xxx.com] acme: error presenting token: API call failed: json: cannot unmarshal string into Go struct field DomainInfo.info.mine_total of type int\n" providerName=default.acme routerName=default-traefik-web-https-f7bd9777289cb69a50bb rule="Host(`aaa.xxx.com`)"

麻烦给指导下哪里有问题?

cnych commented 4 years ago

@starsliao dns验证的方式也得把域名解析到外网IP才行吧,要正常的域名,而且要dns服务商支持才行。

starsliao commented 4 years ago

@cnych @starsliao dns验证的方式也得把域名解析到外网IP才行吧,要正常的域名,而且要dns服务商支持才行。

你好,我查过acme.sh的dns验证的方式说明不需要公网 ip, 不需要做域名解析,只需要 增加dns 的TXT记录即可完成验证。我也测试过使用acme调用API生成dnspod的域名确实可以正常生成证书。 所以很奇怪,在用traefik生成证书的时候报错那两句。

Taosky commented 4 years ago

@starsliao

@cnych @starsliao dns验证的方式也得把域名解析到外网IP才行吧,要正常的域名,而且要dns服务商支持才行。

你好,我查过acme.sh的dns验证的方式说明不需要公网 ip, 不需要做域名解析,只需要 增加dns 的TXT记录即可完成验证。我也测试过使用acme调用API生成dnspod的域名确实可以正常生成证书。 所以很奇怪,在用traefik生成证书的时候报错那两句。

裸域不要用cname就可以

54853315 commented 4 years ago

https://www.qikqiak.com/post/automatic-kubernetes-ingress-https-with-lets-encrypt/

k8s version :v1.16.3 helm version : v2.0.1 想上证书的域名:b-test.mydomain.com(域名其实不是这个,是真实公网可以访问的域名,在这里为了隐私所以改了),此域名有Html Code,访问80端口 能够返回HTTP 200。

emm,不知道为什么,按照这个走,是这样的:

image

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik
  namespace: example-testing
  annotations:
    kubernetes.io/ingress.class: "traefik"
    kubernetes.io/tls-acme: "true"
    cert-manager.io/issuer: "letsencrypt-staging"
spec:
  tls:
  - hosts:
    - b-test.mydomain.com
    secretName: example-testing-tls
  rules:
  - host: b-test.mydomain.com
    http:
      paths:
      - path: '/'
        backend:
          serviceName: traefik
          servicePort: 80

最后看一下日志:

> $ kubectl -n cert-manager log cert-manager-754d9b75d9-s82gq cert-manager | tail -3                                                                                  [±master ●]
I1221 04:07:01.192414       1 ingress.go:91] cert-manager/controller/challenges/http01/selfCheck/http01/ensureIngress "level"=0 "msg"="found one existing HTTP01 solver ingress" "dnsName"="b-test.mydomain.com" "related_resource_kind"="Ingress" "related_resource_name"="cm-acme-http-solver-m5wvg" "related_resource_namespace"="example-testing" "resource_kind"="Challenge" "resource_name"="letsencrypt-staging-292069265-4232741098-1586037050" "resource_namespace"="example-testing" "type"="http-01"
E1221 04:07:01.232087       1 sync.go:184] cert-manager/controller/challenges "msg"="propagation check failed" "error"="presented key (\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\t\u003chead\u003e\n\t\t\u003cmeta charset=\"utf-8\"\u003e\n\t\t\u003ctitle\u003eLoader #10\u003c/title\u003e\n\t\t\u003clink rel=\"stylesheet\" type=\"text/css\" href=\"css/style-10.css\" /\u003e\n\t\t\u003c!--[if IE]\u003e\n\t\t\u003cscript src=\"js/html5.js\"\u003e\u003c/script\u003e\n\t\t\u003c![endif]--\u003e\n\t\t\u003cstyle\u003e\n \n \na{\nbackground: #13A3A5;\npadding:5px;\nmargin:10px;\ndisplay:block;\nfont-weight:100;\ncursor:pointer;\nfont-size:1.5em;\nfloat:left;\ntext-decoration:none;\nfont-size:18px;\ncolor:white\n}\n\u003c/style\u003e\n\t\u003c/head\u003e\n\u003cbody\u003e\n\n\t\u003cdiv class=\"loader\"\u003e\n\t\t\u003cdiv\u003eW\u003c/div\u003e\n\t\t\u003cdiv\u003eA\u003c/div\u003e\n\t\t\u003cdiv\u003eH\u003c/div\u003e\n\t\t\u003cdiv\u003eA\u003c/div\u003e\n\t\t\u003cdiv\u003eH\u003c/div\u003e\n\t\t\u003cdiv\u003eA\u003c/div\u003e\n\t\t\u003cdiv\u003e\u003c/div\u003e\n\t\t\u003cdiv\u003e\u003c/div\u003e\n\t\t\u003cdiv\u003e\u003c/div\u003e\n\t\t\u003cdiv\u003e\u003c/div\u003e\n\t\u003c/div\u003e\n\n\n\u003c/body\u003e\n\u003c/html\u003e\n) did not match expected (G2OOCTGOqRA0H8jltxEynOofnrkCYofG4dKgJ0-igYk.bTsBHadaEUVsqKCLhCius-9InT_bf_jWImKRG2Xj2ww)" "dnsName"="b-test.mydomain.com" "resource_kind"="Challenge" "resource_name"="letsencrypt-staging-292069265-4232741098-1586037050" "resource_namespace"="example-testing" "type"="http-01"
I1221 04:07:01.232151       1 controller.go:135] cert-manager/controller/challenges "level"=0 "msg"="finished processing work item" "key"="example-testing/letsencrypt-staging-292069265-4232741098-1586037050"

日志大致就是说,能够通过这个域名访问到具体的HTML Code,但是这些并不是cert manager 所期待的G2OOCTGOqRA0H8jltxEynOofnrkCYofG4dKgJ0-igYk.bTsBHadaEUVsqKCLhCius-9InT_bf_jWImKRG2Xj2ww(验证文字)。

0.0 我也不知道怎么回事……该地址的项目是用helm部署的一个traefik项目:


 > $ helm -n example-testing ls                                                                                                                                                                                                            [±master ●]
NAME        NAMESPACE       REVISION    UPDATED                                 STATUS      CHART           APP VERSION
frontend    example-testing 1           2019-12-20 18:22:06.077054 +0800 CST    deployed    frontend-0.0.1  1.0.0
mysql       example-testing 1           2019-12-12 11:41:44.958771 +0800 CST    deployed    mysql-0.0.1     1.0.0
traefik     example-testing 1           2019-12-20 18:48:02.589962 +0800 CST    deployed    traefik-0.1.0   v2.0.1

稍微补充一下,由于我的集群每一台其实都被占用了80和443(原来的业务项目),因此我统一使用32001这个NodePort供SLB(负载均衡)去反映射。因此在访问域名时无需加端口。

我认为应该跟这个没关系,感觉还是配置上的问题,没有能够让cert manager 拦截到treafik服务,然后加一个验证地址返回验证文本的行为。

xavierskip commented 4 years ago

大佬好,请问下有使用dnsChallenge.provider=dnspod 的方式来自动生成证书么? 我使用一直报错:

time="2019-11-03T20:18:29Z" level=debug msg="legolog: [WARN] [aaa.xxx.com] acme: error cleaning up: API call failed: json: cannot unmarshal string into Go struct field DomainInfo.info.mine_total of type int "
time="2019-11-03T20:18:29Z" level=error msg="Unable to obtain ACME certificate for domains \"aaa.xxx.com\": unable to generate a certificate for the domains [aaa.xxx.com]: acme: Error -> One or more domains had a problem:\n[aaa.xxx.com] [aaa.xxx.com] acme: error presenting token: API call failed: json: cannot unmarshal string into Go struct field DomainInfo.info.mine_total of type int\n" providerName=default.acme routerName=default-traefik-web-https-f7bd9777289cb69a50bb rule="Host(`aaa.xxx.com`)"

麻烦给指导下哪里有问题?

dnspod api 返回的 json 的某个数据类型发生了变动。 https://github.com/decker502/dnspod-go/issues/9

cnych commented 4 years ago

是的,dnspod 官方把接口改了,类型从 string 改成了 int ,可以给 lego 提一个 PR 修复下 https://github.com/go-acme/lego/issues/1031

xxlaila commented 4 years ago

题主,有没有做过手动加载证书,https证书是公司自己购买的,每个环境对应一个域名证书(通配符的),怎么过根据不通的域名来加载对应的证书,我配置好久,就只能加载一个证书,多个证书不能加载, 如: dev环境: 证书: .dev.aaa.com test环境 证书: .test.aaa.com prod *.aaa.com

我在做l.aaa.com的时候可以加载*.aaa.com,l.dev或者l.test不能加载对应的证书

cnych commented 4 years ago

@xxlaila 咋会呢?自己的证书和以前用法一样,用Secret把证书包含进去,直接使用Secret就可以了。

xxlaila commented 4 years ago

@cnych 不行,我在使用的时候,域名xxx.aaa.com 的时候可以加载aaa.com证书。 当我在使用xxx.dev.a.com 或者是xxx.test.aaa.com,不能加载对应的dev.a.com 或test.aaa.com域名证书

ssl.toml文件

[tls]

  [[tls.certificates]]
    certFile = "/config/certs/aaa.com.crt"
    keyFile = "/config/certs/aaa.com.key"
    stores = ["default"]

  [[tls.crtificates]]
    crtFile = "/config/certs/dev.aaa.com.crt"
    keyFile = "/config/certs/dev.aaa.com.key"
    stores = ["adev"]

  [tls.options]
    [tls.options.default]
      minVersion = "VersionTLS12"
    [tls.options.mintls13]
      minVersion = "VersionTLS13"

http.toml文件

[http]
  [http.routers]
    [http.routers.Router0001]
      namespace = "default"
      entryPoints = ["web", "websecure"]
      service = "appv2-a"
      rule = "Host(`ll.aaa.com`)"
      middlewares = ["test-ipwhitelist", "test-redirectscheme"]
      priority = 42
      [http.routers.Router0001.tls]

  [http.services]
    [http.services.appv2-a]
      [http.services.appv2-a.loadBalancer]
      passHostHeader = true
      [[http.services.appv2-a.loadBalancer.servers]]
        url = "http://appv2.default.svc.cluster.local:80"

上述配置可以加载aaa.com证书,如果把ll.aaa.com,写成ll.dev.aaa.com,则无法加载dev.aaa.com证书。则加载(traefik)默认的证书,也不是aaa.com,dev.aaa.com 更不是啦

xxlaila commented 4 years ago

@cnych 我在进一步测试的发现,我自己手动生成的证书,没办法加载,但是我使用公司的证书的是ok的,又遇到这种问题么。

cnych commented 4 years ago

@xxlaila 你这个完全没必要用这种静态的方式去配置证书,你用Secret创建一个证书的资源对象,然后在使用的时候指定上就可以了

codlin commented 4 years ago

配置好treafik,用阿里的dns,但好像traefik不发起证书请求,有谁遇到这种情况吗?

codlin commented 4 years ago

配置好treafik,用阿里的dns,但好像traefik不发起证书请求,有谁遇到这种情况吗?

已解决

aruruka commented 4 years ago

配置好treafik,用阿里的dns,但好像traefik不发起证书请求,有谁遇到这种情况吗?

已解决

我也遇到了,你怎么解决的啊?

codlin commented 4 years ago

配置好treafik,用阿里的dns,但好像traefik不发起证书请求,有谁遇到这种情况吗?

已解决

我也遇到了,你怎么解决的啊?

我的是certificatesResolvers配的有问题。下面是我现在的配置:

certificatesResolvers:
      ali:
        # Enable ACME (Let's Encrypt): automatic SSL.
        acme:
          email: "xxxx@gmail.com"
          storage: "/etc/traefik/acme/acme.json"
          # CA server to use.
          # Uncomment the line to use Let's Encrypt's staging server,
          # leave commented to go to prod.
          #
          # Optional
          # Default: "https://acme-v02.api.letsencrypt.org/directory"
          #
          # caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
          dnsChallenge:
            provider: alidns
            delayBeforeCheck: 0

email根据需要修改

aruruka commented 4 years ago

配置好treafik,用阿里的dns,但好像traefik不发起证书请求,有谁遇到这种情况吗?

已解决

我也遇到了,你怎么解决的啊?

我的是certificatesResolvers配的有问题。下面是我现在的配置:

certificatesResolvers:
      ali:
        # Enable ACME (Let's Encrypt): automatic SSL.
        acme:
          email: "xxxx@gmail.com"
          storage: "/etc/traefik/acme/acme.json"
          # CA server to use.
          # Uncomment the line to use Let's Encrypt's staging server,
          # leave commented to go to prod.
          #
          # Optional
          # Default: "https://acme-v02.api.letsencrypt.org/directory"
          #
          # caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
          dnsChallenge:
            provider: alidns
            delayBeforeCheck: 0

email根据需要修改

唉,我觉得我的问题不是配置写错了。我是用Traefik官方Helm chart部署的,配置了DNS chanllenge后启动没有看到有相关的错误日志。 不过我的环境是内网,通过NAT访问外网的。我的理解是这应该不影响DNS chanllenge正常工作。 我准备找个云主机用Traefik的k3s的实例来做一次,如果还不行我感觉就要放弃这个方式,用别的方式来自动获取证书了……

aruruka commented 4 years ago

配置好treafik,用阿里的dns,但好像traefik不发起证书请求,有谁遇到这种情况吗?

已解决

我也遇到了,你怎么解决的啊?

我的是certificatesResolvers配的有问题。下面是我现在的配置:

certificatesResolvers:
      ali:
        # Enable ACME (Let's Encrypt): automatic SSL.
        acme:
          email: "xxxx@gmail.com"
          storage: "/etc/traefik/acme/acme.json"
          # CA server to use.
          # Uncomment the line to use Let's Encrypt's staging server,
          # leave commented to go to prod.
          #
          # Optional
          # Default: "https://acme-v02.api.letsencrypt.org/directory"
          #
          # caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
          dnsChallenge:
            provider: alidns
            delayBeforeCheck: 0

email根据需要修改

唉,我觉得我的问题不是配置写错了。我是用Traefik官方Helm chart部署的,配置了DNS chanllenge后启动没有看到有相关的错误日志。 不过我的环境是内网,通过NAT访问外网的。我的理解是这应该不影响DNS chanllenge正常工作。 我准备找个云主机用Traefik的k3s的实例来做一次,如果还不行我感觉就要放弃这个方式,用别的方式来自动获取证书了……

今天抽时间重新部署了一遍,就好了。我觉得问题是出在CRD和RBAC定义那块。 问题是之前看log也没有啥明显的提示。

DeathKing commented 2 years ago

问题是之前看log也没有啥明显的提示。

@aruruka 我遇到了类似的问题。把 traefik 的日志等级调成 debug 也没看到它有明显的提示,似乎就没有发起过证书请求(从阿里云那边看AK和SK就没有使用过)。想请教你一下你是怎么 debug 的。