Kubernetes cert-manager с letsencrypt, ожидающим выдачи сертификата

Я пытаюсь настроить кластер Azure Kubernetes с контроллером входящего трафика HTTPS для отдельных сред разработки, промежуточной и производственной среды. Я следовал руководству Microsoft Azure о том, как создать контроллер входящего трафика HTTPS на Служба Azure Kubernetes (AKS), которая позволяет мне настроить контроллер входящего трафика HTTPS для одного пространства имен, но моя конечная цель - иметь отдельные пространства имен для сред разработки, промежуточной и производственной среды. Согласно ответам на этот вопрос, способ сделать это чтобы входной контроллер находился в одном пространстве имен (ingress в моем случае), а затем отдельные правила входа для каждого пространства имен (dev в моем случае).

Поэтому я настраиваю входной контроллер nginx и диспетчер сертификатов в пространстве имен ingress:

# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

# Use Helm to deploy an NGINX ingress controller
helm install nginx-ingress ingress-nginx/ingress-nginx \
    --namespace ingress \
    --set controller.replicaCount=2 \
    --set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \
    --set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux \
    --set controller.admissionWebhooks.patch.nodeSelector."beta\.kubernetes\.io/os"=linux

# Label the ingress-basic namespace to disable resource validation
kubectl label namespace ingress cert-manager.io/disable-validation=true

# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io

# Update your local Helm chart repository cache
helm repo update

# Install the cert-manager Helm chart
helm install cert-manager jetstack/cert-manager \
  --namespace ingress \
  --version v0.16.1 \
  --set installCRDs=true \
  --set nodeSelector."kubernetes\.io/os"=linux \
  --set webhook.nodeSelector."kubernetes\.io/os"=linux \
  --set cainjector.nodeSelector."kubernetes\.io/os"=linux

Затем я создаю файл cluster-issuer.yml со следующим:

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt
    solvers:
    - http01:
        ingress:
          class: nginx
          podTemplate:
            spec:
              nodeSelector:
                "kubernetes.io/os": linux

который я обращаюсь с

$ kubectl apply -f cluster-issuer.yml

Затем я создаю правило входа в пространстве имен dev со следующим файлом ingress.yml:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-dev
  namespace: dev
  annotations:
    kubernetes.io/ingress.class: nginx
    ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    cert-manager.io/cluster-issuer: letsencrypt
    
spec:
  tls:
  - hosts:
    - domain.azure.com
    secretName: tls-secret-dev
  rules:
  - host: domain.azure.com
    http:
      paths:
      - backend:
          serviceName: my-service
          servicePort: 80
        path: /dev/my-service(/|$)(.*)

и примените его:

$ kubectl apply -f ingress.yml

Теперь проверяю, создан ли секрет:

$ kubectl get certificate -n dev
NAME             READY   SECRET           AGE
tls-secret-dev   False   tls-secret-dev   61s

Значит, при создании секрета что-то пошло не так. Если я смотрю на сертификат, кажется, что запрашивается сертификат, но дальше этого никогда не идет:

$ kubectl describe certificate tls-secret -n dev
Name:         tls-secret-dev
Namespace:    dev
Labels:       <none>
Annotations:  <none>
API Version:  cert-manager.io/v1beta1
Kind:         Certificate
...
Status:
  Conditions:
    Last Transition Time:        2021-02-16T13:47:33Z
    Message:                     Issuing certificate as Secret does not exist
    Reason:                      DoesNotExist
    Status:                      False
    Type:                        Ready
    Last Transition Time:        2021-02-16T13:47:33Z
    Message:                     Issuing certificate as Secret does not exist
    Reason:                      DoesNotExist
    Status:                      True
    Type:                        Issuing
  Next Private Key Secret Name:  tls-secret-dev-6ngw8
Events:
  Type    Reason     Age   From          Message
  ----    ------     ----  ----          -------
  Normal  Issuing    70s   cert-manager  Issuing certificate as Secret does not exist
  Normal  Generated  70s   cert-manager  Stored new private key in temporary Secret resource "tls-secret-dev-6ngw8"
  Normal  Requested  70s   cert-manager  Created new CertificateRequest resource "tls-secret-dev-vtlbd"

Глядя на запрос сертификата, создается заказ:

$ kubectl describe certificaterequest tls-secret-dev-vtlbd -n dev
Name:         tls-secret-dev-vtlbd
Namespace:    dev
Labels:       <none>
Annotations:  cert-manager.io/certificate-name: tls-secret-dev
              cert-manager.io/certificate-revision: 1
              cert-manager.io/private-key-secret-name: tls-secret-dev-6ngw8
API Version:  cert-manager.io/v1beta1
Kind:         CertificateRequest
...
Status:
  Conditions:
    Last Transition Time:  2021-02-16T13:47:33Z
    Message:               Waiting on certificate issuance from order dev/tls-secret-dev-vtlbd-526778456: ""
    Reason:                Pending
    Status:                False
    Type:                  Ready
Events:
  Type    Reason        Age   From          Message
  ----    ------        ----  ----          -------
  Normal  OrderCreated  3m3s  cert-manager  Created Order resource dev/tls-secret-dev-vtlbd-526778456

Проверка порядка - это то, где кажется, что след становится холодным:

$ kubectl describe order tls-secret-dev-vtlbd-526778456 -n dev
Name:         tls-secret-dev-vtlbd-526778456
Namespace:    dev
Labels:       <none>
Annotations:  cert-manager.io/certificate-name: tls-secret-dev
              cert-manager.io/certificate-revision: 1
              cert-manager.io/private-key-secret-name: tls-secret-dev-6ngw8
API Version:  acme.cert-manager.io/v1beta1
Kind:         Order
...
Status:
Events:  <none>

Вопрос: Как мне заставить диспетчер сертификатов перестать ждать выдачи сертификата, чтобы я мог завершить настройку контроллера входящего трафика HTTPS?


person mrp    schedule 16.02.2021    source источник
comment
Здравствуйте, вы настроили свой DNS (запись A) с вашим доменом так, чтобы он указывал на Службу типа LoadBalancer вашего nginx-ingress контроллера? Также ваши domain (domain.azure.com) в Ingress и email address ([email protected]) в ClusterIssuer являются значениями-заполнителями, а не вашими фактическими значениями случайно?   -  person Dawid Kruk    schedule 17.02.2021
comment
@DawidKruk Доменное имя и адрес электронной почты - это заполнители, да. Я не настраивал запись A, а вместо этого настроил полное доменное имя, как описано в связанном руководстве, на основе внешнего IP-адреса, предоставленного входным контроллером.   -  person mrp    schedule 17.02.2021
comment
Следуя этой теме, ваше domain.azure.com разрешение DNS указывает прямо на Ingress контроллер, верно? Если нет, попробуйте добавить эту A запись и сообщите, удалось ли вам сгенерировать этот сертификат.   -  person Dawid Kruk    schedule 19.02.2021