cert-manager - Acme Http Solver 返回 404

Goi*_*nas 4 kubernetes kubernetes-ingress cert-manager nginx-ingress

cert-manager有一个 kubernetes 集群,其中有一个服务的 nginx 入口,我正在尝试使用ACME设置 https 访问ClusterIssuer

我对 cert-manager 遵循的步骤相当满意,但我目前正处于对 http 求解器提出挑战的阶段,cert-manager 在集群中配置了该解决器作为挑战过程的一部分。当我描述服务生成的挑战时,我发现其状态处于待处理状态:

Reason:      Waiting for http-01 challenge propagation: failed to perform self check GET request 'http://www.example.com/.well-known/acme-challenge/nDWOHEMXgy70_wxi53ijEKjUHFlzg_UJJS-sv_ahGzg': Get "http://www.example.com/.well-known/acme-challenge/nDWOHEMXgy70_wxi53ijEKjUHFlzg_UJJS-sv_ahGzg": dial tcp xx.xx.xx.xxx:80: connect: connection timed out
Run Code Online (Sandbox Code Playgroud)

当我从 k8s 主机服务器调用求解器的 url 时:

curl -H "Host: www.example.com" http://192.168.1.11:31344/.well-known/acme-challenge/nDWOHEMXgy70_wxi53ijEKjUHFlzg_UJJS-sv_ahGzg
Run Code Online (Sandbox Code Playgroud)

我得到了 200 ok 回复。

注意:地址 192.168.1.11 是运行 httpsolver pod 的 k8s 节点的 IP。端口 31344 是 httpsolver pod 的 nodeIp 服务的内部端口。

我试图找出为什么挑战本身超时并且没有得到 200 回复。

我已经通过 4g(而不是 wifi)从我的手机测试了 http 解算器的 url,这样我得到 200 OK,这告诉我可以通过防火墙从外部访问 http 解算器,并通过 nginx 进入服务和 Pod正确的?那么,如果是这种情况,那么还有哪些其他原因导致 Let's Encrypt 无法从同一 URL 检索令牌?

--- 当前配置 ---

集群发行人:

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
 name: letsencrypt-staging
 namespace: cert-manager
spec:
 acme:
   # The ACME server URL
   server: https://acme-staging-v02.api.letsencrypt.org/directory
   # Email address used for ACME registration
   email: my.address@example.com
   # Name of a secret used to store the ACME account private key
   privateKeySecretRef:
     name: letsencrypt-staging
   # Enable the HTTP-01 challenge provider
   solvers:
   - selector: {}
     http01:
       ingress:
         class: nginx
Run Code Online (Sandbox Code Playgroud)

入口:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ing-myservice-web
  namespace: myservice
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-staging"
spec:
  tls:
  - hosts:
    - www.example.com
    secretName: secret-myservice-web-tls
  rules:
  - host: www.example.com
    http:
      paths:
      - backend:
          serviceName: svc-myservice-web
          servicePort: 8080
        path: /
  - host: www.example.co.uk
    http:
      paths:
        - backend:
            serviceName: svc-myservice-web
            servicePort: 8080
          path: /
Run Code Online (Sandbox Code Playgroud)

Goi*_*nas 5

在阅读了cert-manager工作原理的各个不同方面,阅读了其他人在其他帖子上的类似问题,并更好地了解了我的网络是如何设置的以及从外部看到的,我在下面介绍了我所学到的内容我的设置以及之后我为了cert-manager在 k8s 集群中为我的域服务工作所做的事情。

设置:

  • nginxkubernetes 集群,后端服务以入口控制器为前端,NodePort服务分别为 http 和 https 公开端口 25080 和 25443。
  • kubernetes 集群位于 ISP 公共 IP 后面的专用网络中。

解决方案:

  • 配置了在 k8s 集群外部的端口 80 上运行的本地http proxy,它将请求转发到 的nginx controllerIPNodePort和端口 25080。

  • 在我的网络上配置bind9为将 www 指向本地http proxy正在运行的主机。

  • 将 k8s 集群配置CoreDNS为指向bind9主机(而不是 8.8.4.4 等)

  • 配置我的专用网络的入口点路由器,将任何地址端口 80 发送到 的nginx controllerIPNodePort和端口 25080。

  • 配置我的专用网络的入口点路由器,将任何地址端口 443 发送到 的nginx controllerIPNodePort和端口 25443。

此解决方案的主要原因是我的 ISP 不允许我的专用网络中的主机通过网络的公共 IP 地址呼叫和返回网络。(我相信这对于 ISP 来说很常见,称为 Harpining 或 NAT Loopback,并且某些路由器具有打开它的功能)。

因此,为了让cert-managerhttp solverpod(在 k8s 集群内运行)能够完成挑战,它必须能够nginx controller通过本地托管的强制 www 的网络路由来到达http proxy,而不是出去到万维网并再次返回(我的 ISP 不允许)。

有了这个解决方案,http solverPod 就能够完成挑战,然后cert-manager能够成功颁发证书。

我确信(并且我希望)有更好、更干净的解决方案来解决这种情况,但我自己还没有遇到过任何解决方案,所以这是我目前采用的解决方案。