cert-manager - Acme Http Solver возвращает 404

У меня есть кластер kubernetes с входом nginx в службу, которую я пытаюсь настроить с доступом https с использованием cert-manager и ACME 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

Когда я вызываю URL-адрес решателя с моего хост-сервера k8s:

curl -H "Host: www.example.com" http://192.168.1.11:31344/.well-known/acme-challenge/nDWOHEMXgy70_wxi53ijEKjUHFlzg_UJJS-sv_ahGzg

Я получаю 200 ок.

ПРИМЕЧАНИЕ. Адрес 192.168.1.11 - это IP-адрес узла k8s, на котором запущен модуль http-решателя. А порт 31344 - это внутренний порт службы nodeIp для модуля http-решателя.

Я пытаюсь понять, почему время ожидания само по себе истекает, и я не получаю обратно 200 очков.

Я протестировал URL-адрес http-решателя со своего мобильного телефона через 4g (вместо Wi-Fi), и таким образом я получил 200 OK, поэтому это говорит мне, что http-решатель доступен извне через брандмауэр и через nginx в службу и под Правильно? Итак, если это так, то по какой другой причине 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: [email protected]
   # 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

Вход:

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: /

person Going Bananas    schedule 16.10.2020    source источник
comment
Мне удалось доказать, что модуль http-решателя работает правильно, выполнив команду curl следующим образом: curl -I -H "Host: www.place.com" http://192.168.1.11:30421/.well-known/acme-challenge/nDWOHEMXgy70_wxi53ijEKjUHFlzg_UJJS-sv_ahGzg. Этот вызов возвращает 200 OK.   -  person Going Bananas    schedule 16.10.2020
comment
Что касается статуса проблемы 404, я думаю, что это может быть потому, что невозможно вызвать внешний IP-адрес (на который указывает мой домен) из моей собственной сети? т.е. из-за брандмауэра?   -  person Going Bananas    schedule 16.10.2020
comment
Я протестировал URL-адрес http-решателя со своего мобильного телефона через 4g (вместо Wi-Fi), поэтому это доказывает, что http-решатель доступен через брандмауэр и через nginx в службу и модуль, что хорошо, но, как говорится в моем последнем комментарии, я не Я не думаю, что можно вызвать URL-адрес задачи http-решателя из моей собственной сети. Так как же обойти это?   -  person Going Bananas    schedule 16.10.2020
comment
Текст в letsencrypt.org/docs/challenge-types/#dns-01 -challenge утверждает, что именно Let's Encrypt пытается получить токен с URL-адреса http-решателя, поэтому мой последний комментарий недействителен. Однако я могу получить токен со своего мобильного телефона через 4g (т. Е. Извне), так почему же Let's Encrypt?   -  person Going Bananas    schedule 16.10.2020
comment
1. Пожалуйста, отредактируйте свой вопрос, указав всю необходимую информацию, вместо того, чтобы размещать его как комментарий. Постарайтесь сделать его кратким и ясным. 2. Предоставьте свои конфигурации / yamls и шаги для воспроизведения вашей проблемы. Мы не можем сильно помочь, основываясь на том, что вы нам дали.   -  person Wytrzymały Wiktor    schedule 19.10.2020
comment
@ WytrzymałyWiktor Я переформулировал проблемный вопрос сообщения и добавил конфигурации ClusterIssuer, Ingress в соответствии с вашими предложениями. Помогло бы также включение каких-либо других конфигов?   -  person Going Bananas    schedule 20.10.2020
comment
Эй, проверьте этот пост, stackoverflow.com/questions/58423312/, я думаю, это поможет   -  person Tushar Mahajan    schedule 18.12.2020
comment
@TusharMahajan, я думаю, что сообщение, на которое вы ссылаетесь, предназначено для другого сценария, где nginx controller LoadBalanced с публичным провайдером и где http solver может звонить во всемирную паутину и обратно (что мой провайдер не позволяет).   -  person Going Bananas    schedule 18.12.2020


Ответы (1)


Прочитав о различных аспектах работы cert-manager, ознакомившись с аналогичными проблемами других людей в других сообщениях и получив лучшее понимание того, как моя сеть настроена и видна со стороны, я представляю ниже то, что я узнал. о моей настройке и о том, что я сделал после этого, чтобы cert-manager работал для моих доменных служб в кластере k8s внутри.

Настройка:

  • кластер kubernetes с внутренними службами, обслуживаемыми nginx контроллером входящего трафика с NodePort службой, открывающей порты 25080 и 25443 для http и https соответственно.
  • кластер kubernetes в частной сети за общедоступным IP-адресом интернет-провайдера.

Решение:

  • Настроен локальный http proxy, работающий на порту 80 за пределами кластера k8s, который перенаправляет запросы на NodePort IP nginx controller и порт 25080.

  • Настроил bind9 в моей сети, чтобы указать www на хост, на котором запущен локальный http proxy.

  • Настроил CoreDNS кластера k8s так, чтобы он указывал на хост bind9 (вместо 8.8.4.4 и т. Д.)

  • Настроил маршрутизатор точки входа моей частной сети для отправки любого адресного порта 80 на nginx controller NodePort IP и порт 25080.

  • Настроил маршрутизатор точки входа моей частной сети для отправки любого адресного порта 443 на NodePort IP nginx controller и порт 25443.

Основная причина этого решения заключается в том, что мой интернет-провайдер не позволяет хостам в моей частной сети звонить и возвращаться в сеть через общедоступный IP-адрес сети. (Я считаю, что это довольно распространено для интернет-провайдеров и называется Harpining или NAT Loopback, и у некоторых маршрутизаторов есть функция для его включения).

Таким образом, для того, чтобы модуль cert-manager http solver (работающий в кластере k8s) мог выполнить задачу, необходимо было, чтобы он мог достичь nginx controller путем принудительной сетевой маршрутизации для www через локально размещенный http proxy вместо выхода во всемирную паутину и обратно (что не позволяет мой провайдер).

С этим решением модуль http solver смог выполнить задачу, и после этого cert-manager смог успешно выдать сертификаты.

Я уверен (и надеюсь), что есть лучшие и более чистые решения для решения такого рода сценариев, но я сам еще не встречал ни одного, так что это решение, которое у меня сейчас есть.

person Going Bananas    schedule 17.12.2020