Tutorial

Cómo configurar un Ingress de Nginx con Cert-Manager en Kubernetes de DigitalOcean

Published on January 9, 2020
Español
Cómo configurar un Ingress de Nginx con Cert-Manager en Kubernetes de DigitalOcean

Introducción

Los Ingress de Kubernetes le permiten dirigir de manera flexible el tráfico del exterior de su clúster de Kubernetes a servicios dentro de su clúster. Esto se realiza usando recursos de Ingress, que definen reglas para dirigir el tráfico HTTP y HTTPS a servicios de Kubernetes, y controladores de Ingress, que implementan las reglas equilibrando la carga de tráfico y dirigiéndola a los servicios de backend correspondientes. Entre los controladores populares de Ingress se incluyen Nginx, Contour, HAProxy y Traefik. Los Ingress ofrecen una alternativa más eficiente y flexible para configurar varios servicios de LoadBalancer, cada uno de los cuales utiliza su propio equilibrador de cargas dedicado.

En esta guía, configuraremos el controlador de Ingress de Nginx mantenido por Kubernetes y crearemos algunos recursos de Ingress para dirigir el tráfico a varios servicios de backend ficticios. Una vez que configuremos el Ingress, instalaremos cert-manager en nuestro clúster para administrar y proporcionar certificados TLS, a fin de cifrar el tráfico de HTTP en el Ingress. En esta guía no se utiliza el administrador de paquetes de Helm. Para hallar una guía sobre la implementación del controlador de Ingress de Nginx con Helm, consulte Cómo configurar un Ingress de Nginx en Kubernetes de DigitalOcean usando Helm.

Requisitos previos

Antes de comenzar con esta guía, asegúrese de contar con lo siguiente:

  • Un clúster de Kubernetes 1.10, o una versión posterior, con control de acceso basado en roles (RBCA) activado
  • La herramienta de línea de comandos kubectl instalada en su equipo local y configurada para conectarse a su clúster. Puede leer más sobre la instalación de kubectl en la documentación oficial.
  • Un nombre de dominio y registros DNS A que puede orientar al equilibrador de cargas de DigitalOcean utilizado por el Ingress. Si usa DigitalOcean para administrar los registros DNS de su dominio, consulte Cómo administrar registros DNS para aprender a crear registros A.
  • La utilidad de línea de comandos wget instalada en su equipo local. Puede instalar wget usando el administrador de paquetes incorporado en su sistema operativo.

Cuando tenga estos componentes configurados, estará listo para comenzar con esta guía.

Paso 1: Configurar servicios de backend ficticios

Antes de implementar el controlador de Ingress, crearemos e implementaremos primero dos servicios echo ficticios a los que dirigiremos el tráfico externo usando el Ingress. Los servicios echo ejecutan el contenedor del servidor web hashicorp/http-echo, el cual muestra una página que contiene una cadena de texto transmitida cuando se inicia el servidor web. Para obtener más información sobre http-echo, consulte su repositorio de GitHub y para obtener más información sobre los Servicios de Kubernetes, consulte Servicios en los documentos oficiales de Kubernetes.

En su equipo local, cree y edite un archivo llamado echo1.yaml usando nano o su editor favorito:

  1. nano echo1.yaml

Pegue el siguiente manifiesto de servicio e implementación:

echo1.yaml
apiVersion: v1
kind: Service
metadata:
  name: echo1
spec:
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo1
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo1
spec:
  selector:
    matchLabels:
      app: echo1
  replicas: 2
  template:
    metadata:
      labels:
        app: echo1
    spec:
      containers:
      - name: echo1
        image: hashicorp/http-echo
        args:
        - "-text=echo1"
        ports:
        - containerPort: 5678

En este archivo, definimos un servicio llamado echo1 que dirige el tráfico hacia los Pods con el selector de etiquetas app: echo1. Acepta el tráfico de TCP en el puerto 80 y lo dirige al puerto 5678, el predeterminado de http-echo.

A continuación, definimos una implementación, también llamada echo1, que administra los Pods con el selector de etiquetas app: echo1. Especificamos que la implementación debe tener 2 réplicas de Pods y que los Pods deben iniciar un contenedor llamado echo1 ejecutando la imagen hashicorp/http-echo. Especificamos el parámetro text y lo fijamos en echo1, para que el servidor web http-echo muestre echo1. Por último, abrimos el puerto 5678 en el contenedor de Pods.

Una vez que esté satisfecho con su servicio ficticio y manifiesto de implementación, guarde y cierre el archivo.

A continuación, cree los recursos de Kubernetes usando kubectl apply con el indicador -f y especificando el archivo que acaba de guardar como un parámetro:

  1. kubectl apply -f echo1.yaml

Debería ver el siguiente resultado:

Output
service/echo1 created deployment.apps/echo1 created

Verifique que el servicio se haya iniciado de manera correcta confirmando que este tenga un ClusterIP, el IP interno en el que se expone el servicio:

  1. kubectl get svc echo1

Debería ver el siguiente resultado:

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo1 ClusterIP 10.245.222.129 <none> 80/TCP 60s

Esto indica que el servicio echo1 ahora se encuentra disponible de manera interna en 10.245.222.129 en el puerto 80. Reenviará el tráfico al containerPort 5678 en los Pods que seleccione.

Ahora que el servicio echo1 está activo y en ejecución, repita este proceso para el servicio echo2.

Cree y abra un archivo llamado echo2.yaml:

echo2.yaml
apiVersion: v1
kind: Service
metadata:
  name: echo2
spec:
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo2
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo2
spec:
  selector:
    matchLabels:
      app: echo2
  replicas: 1
  template:
    metadata:
      labels:
        app: echo2
    spec:
      containers:
      - name: echo2
        image: hashicorp/http-echo
        args:
        - "-text=echo2"
        ports:
        - containerPort: 5678

Aquí, básicamente utilizamos el mismo manifiesto de servicio e implementación de arriba, pero asignamos el nombre y la nueva etiqueta echo2 al servicio y a la implementación. Además, para proporcionar variedad, creamos solo una réplica de Pod. Nos aseguramos de fijar el parámetro de text en echo2 para que el servidor web muestre el texto echo2.

Guarde y cierre el archivo, y cree los recursos de Kubernetes usando kubectl:

  1. kubectl apply -f echo2.yaml

Debería ver el siguiente resultado:

Output
service/echo2 created deployment.apps/echo2 created

Una vez más, compruebe que el servicio esté activo y en ejecución:

  1. kubectl get svc

Debería ver ambos servicios echo1 y echo2 con ClusterIP asignados:

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo1 ClusterIP 10.245.222.129 <none> 80/TCP 6m6s echo2 ClusterIP 10.245.128.224 <none> 80/TCP 6m3s kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 4d21h

Ahora que nuestros servicios web ficticios de echo están activos y en ejecución, podemos implementar el controlador de Ingress de Nginx.

Paso 2: Configurar el controlador de Ingress de Nginx en Kubernetes

En este paso, implementaremos v0.26.1 del controlador de Ingress de Nginx mantenido por Kubernetes. Tenga en cuenta que hay varios controladores de Ingress de Nginx; la comunidad de Kubernetes mantiene el que utilizamos en esta guía y Nginx Inc. mantiene kubernetes-ingress. Las instrucciones de este tutorial están basadas en las de la Guía de instalación oficial del controlador de Ingress de Nginx en Kubernetes.

El controlador de Ingress de Nginx consta de un Pod que ejecuta el servidor web de Nginx y verifica el panel de control de Kubernetes en busca de objetos de recursos de Ingress nuevos y actualizados. Un recurso de Ingress es esencialmente una lista de reglas de enrutamiento de tráfico para los servicios de backend. Por ejemplo, una regla de Ingress puede especificar que el tráfico HTTP que llegue a la ruta /web1 deberá dirigirse hacía el servidor web de backend web1. Utilizando los recursos de Ingress, también puede aplicar enrutamiento basado en host: por ejemplo, dirigir las solicitudes que llegan de web1.yoyour_domain.com al servicio de backend de Kubernetes web1.

En este caso, debido a que implementamos el controlador de Ingress en un clúster de Kubernetes de DigitalOcean, el controlador creará un servicio LoadBalancer que hará aparecer un equilibrador de carga de DigitalOcean al cual se dirigirá todo el tráfico externo. Este equilibrador de carga dirigirá el tráfico externo al Pod del controlador de Ingress ejecutando Nginx, que posteriormente reenviará el tráfico a los servicios de backend correspondientes.

Comenzaremos creando primero los recursos de Kubernetes requeridos por el controlador de Ingress de Nginx. Estos consisten en ConfigMaps que contienen la configuración del controlador, roles de control de acceso basado en roles (RBAC), para otorgar al controlador acceso a la API de Kubernetes, y la implementación real del controlador de Ingress que utiliza v0.26.1 de la imagen del controlador de Ingress de Nginx. Para ver una lista completa de estos recursos necesarios, consulte el manifiesto del repositorio GitHub del controlador de Ingress de Nginx en Kubernetes.

Para crear estos recursos obligatorios, utilice kubectl apply y el indicador -f para especificar el archivo de manifiesto alojado en GitHub:

  1. kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.1/deploy/static/mandatory.yaml

En este caso, utilizamos apply para que en el futuro podamos implementar cambios apply en incrementos a los objetos del controlador de Ingress en lugar de sobrescribirlos por completo. Para obtener más información sobre apply, consulte Recursos de administración de los documentos oficiales de Kubernetes.

Debería ver el siguiente resultado:

Output
namespace/ingress-nginx created configmap/nginx-configuration created configmap/tcp-services created configmap/udp-services created serviceaccount/nginx-ingress-serviceaccount created clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created role.rbac.authorization.k8s.io/nginx-ingress-role created rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created deployment.apps/nginx-ingress-controller created

Este resultado también sirve como un resumen práctico de todos los objetos del controlador de Ingress creados a partir del manifiesto mandatory.yaml.

A continuación, crearemos el servicio LoadBalancer del controlador de Ingress, el cual creará un equilibrador de carga de DigitalOcean que equilibrará la carga y dirigirá el tráfico HTTP y HTTPS al Pod del controlador de Ingress implementado en el comando anterior.

Para crear el servicio LoadBalancer, una vez más utilice kubectl apply en un archivo de manifiesto que contenga la definición del servicio:

  1. kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.1/deploy/static/provider/cloud-generic.yaml

Debería ver el siguiente resultado:

Output
service/ingress-nginx created

Confirme que los pods del controlador de Ingress se hayan iniciado:

  1. kubectl get pods --all-namespaces -l app.kubernetes.io/name=ingress-nginx
Output
NAMESPACE NAME READY STATUS RESTARTS AGE ingress-nginx nginx-ingress-controller-7fb85bc8bb-lnm6z 1/1 Running 0 2m42s

Ahora, confirme que el equilibrador de carga de DigitalOcean se haya creado de manera exitosa obteniendo los detalles del servicio con kubectl:

  1. kubectl get svc --namespace=ingress-nginx

Después de algunos minutos, debería ver una dirección IP externa que corresponda a la dirección IP del equilibrador de carga de DigitalOcean:

Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx LoadBalancer 10.245.247.67 203.0.113.0 80:32486/TCP,443:32096/TCP 20h

Anote la dirección IP externa del equilibrador de carga, ya que la necesitará en un paso posterior.

Nota: Por defecto, para el servicio LoadBalancer de Ingress de Nginx se fijó service.spec.externalTrafficPolicy en el valor Local, que dirige todo el tráfico del equilibrador de carga a los nodos ejecutando los Pods de Ingress de Nginx. Los otros nodos experimentarán fallas de manera deliberada en las verificaciones de estado del equilibrador de carga, de modo que el tráfico de Ingress no se dirija a estos. Las políticas de tráfico externo están fuera del alcance de este tutorial, pero para obtener más información puede consultar Análisis detallado de las políticas de tráfico externo de Kubernetes e IP de origen para servicios con Type=LoadBalancer en los documentos oficiales de Kubernetes.

Este equilibrador de carga recibe tráfico en los puertos HTTP y HTTPS 80 y 443, y lo reenvía al Pod del controlador de Ingress. Luego, el controlador de Ingress dirigirá el tráfico al servicio de backend correspondiente.

Ahora podemos apuntar nuestros registros DNS hacia este equilibrador de carga externo y crear algunos recursos de Ingress para implementar reglas de enrutamiento de tráfico.

Paso 3: Crear el recurso de Ingress

Comencemos creando un recurso de Ingress mínimo para direccionar el tráfico orientado a un subdominio determinado hacia un servicio de backend correspondiente.

En esta guía, utilizaremos el dominio de prueba example.com. Deberá sustituirlo por el nombre de dominio que posea.

Primero crearemos una regla sencilla para direccionar el tráfico dirigido a echo1.example.com hacia el servicio de backend echo1 y el tráfico dirigido a echo2.example.com hacia el servicio de backend echo2.

Empiece abriendo un archivo llamado echo_ingress.yaml en su editor de texto favorito:

  1. nano echo_ingress.yaml

Pegue la siguiente definición de ingress:

echo_ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
spec:
  rules:
  - host: echo1.example.com
    http:
      paths:
      - backend:
          serviceName: echo1
          servicePort: 80
  - host: echo2.example.com
    http:
      paths:
      - backend:
          serviceName: echo2
          servicePort: 80

Cuando haya terminado de editar sus reglas de Ingress, guarde y cierre el archivo.

Aquí, especificamos que queremos crear un recurso de Ingress llamado echo-ingress y dirigir el tráfico según el encabezado del host. Una solicitud de encabezado de host HTTP especifica el nombre de dominio del servidor de destino. Para obtener más información sobre encabezados de solicitudes de hosts, consulte la página de definición de Mozilla Developer Network. Las solicitudes con el host echo1.example.com se dirigirán al backend echo1, configurado en el paso 1, y las solicitudes con el host echo2.example.com se dirigirán al backend echo2.

Ahora puede crear el Ingress usando kubectl:

  1. kubectl apply -f echo_ingress.yaml

Visualizará la siguiente salida que confirma la creación de Ingress:

Output
ingress.extensions/echo-ingress created

Para comprobar el Ingress, diríjase a su servicio de administración de DNS y cree registros A para echo1.example.com y echo2.example.com apuntando al IP externo del equilibrador de carga de DigitalOcean. El IP externo del equilibrador de carga es la dirección IP externa para el servicio de ingress-nginx, que obtuvimos en el paso anterior. Si usa DigitalOcean para administrar los registros DNS de su dominio, consulte Cómo administrar registros DNS para aprender a crear registros A.

Una vez que haya creado los registros DNS echo1.example.com y echo2.example.com necesarios, puede probar el controlador y el recurso de Ingress que creó usando la utilidad de línea de comandos curl.

Desde su computadora local, aplique curl al servicio echo1.

  1. curl echo1.example.com

Debe obtener la siguiente respuesta del servicio echo1:

Output
echo1

Esto confirma que su solicitud a echo1.example.com se está dirigiendo de manera correcta a través del Ingress de Nginx al servicio de backend echo1.

Ahora, realice la misma prueba para el servicio echo2:

  1. curl echo2.example.com

Debe obtener la siguiente respuesta del servicio echo2:

Output
echo2

Esto confirma que su solicitud a echo2.example.com se está dirigiendo de manera correcta a través del Ingress de Nginx al servicio de backend echo2.

En este punto, habrá configurado con éxito un Ingress mínimo de Nginx para realizar enrutamientos virtuales basados en host. En el siguiente paso, instalaremos cert-manager a fin de proporcionar certificados TLS para nuestro Ingress y habilitaremos el protocolo HTTPS por ser más seguro.

Paso 4: Instalar y configurar Cert-Manager

En este paso, instalaremos cert-manager en nuestro clúster. cert-manager es un servicio de Kubernetes que proporciona certificados TLS de Let´s Encrypt, y otras autoridades certificadoras, y administra sus ciclos de vida. Los certificados pueden solicitarse y configurarse aplicando a recursos de Ingress la anotación cert-manager.io/issuer, añadiendo una sección tls a la especificación de Ingress y configurando uno o más *Issuers *o *ClusterIssuers *para especificar su autoridad de certificación preferida. Para obtener más información sobre los objetos Issuer y ClusterIssuer, consulte la documentación oficial de cert-manager sobre objetos Issuer.

Antes de instalar cert-manager, crearemos primero un espacio de nombres en el que se pueda ejecutar:

  1. kubectl create namespace cert-manager

A continuación, instalaremos cert-manager y sus definiciones de recursos personalizados (CRD) como Issuers y ClusterIssuers. Realice esto utilizando apply en el manifiesto directamente desde el repositorio de GitHub de cert-manager:

  1. kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.12.0/cert-manager.yaml

Debería ver el siguiente resultado:

Output
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/challenges.acme.cert-manager.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.cert-manager.io created . . . deployment.apps/cert-manager-webhook created mutatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created validatingwebhookconfiguration.admissionregistration.k8s.io/cert-manager-webhook created

Para verificar nuestra instalación, consulte el espacio de nombres de cert-manager para ejecutar pods:

  1. kubectl get pods --namespace cert-manager
Output
NAME READY STATUS RESTARTS AGE cert-manager-5c47f46f57-jknnx 1/1 Running 0 27s cert-manager-cainjector-6659d6844d-j8cbg 1/1 Running 0 27s cert-manager-webhook-547567b88f-qks44 1/1 Running 0 27s

Esto indica que la instalación de cert-manager se realizó de manera correcta.

Antes de comenzar a emitir certificados para nuestros hosts de Ingress, debemos crear un emisor, el cual especifica la autoridad de certificación de la que se pueden obtener certificados firmados x509. En esta guía, usaremos la autoridad de certificación de Let´s Encrypt, que proporciona certificados TLS gratuitos y ofrece un servidor de ensayo para probar la configuración de sus certificados y un servidor de producción para implementar certificados de TLS verificables.

Crearemos un emisor de prueba para asegurarnos de que el mecanismo de suministro de certificados funcione de manera correcta. Abra un archivo llamado staging_issuer.yaml en su editor de texto favorito:

nano staging_issuer.yaml

Pegue el siguiente manifiesto de ClusterIssuer:

staging_issuer.yaml
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: your_email_address_here
   # Name of a secret used to store the ACME account private key
   privateKeySecretRef:
     name: letsencrypt-staging
   # Enable the HTTP-01 challenge provider
   solvers:
   - http01:
       ingress:
         class:  nginx

Aquí especificamos que deseamos crear un objeto de ClusterIssuer llamado letsencrypt-staging y usar el servidor de ensayo de Let´s Encrypt. Más adelante usaremos el servidor de producción para implementar nuestros certificados, pero el servidor de producción puede limitar las solicitudes que se hagan con el mismo. Por ello, para fines de prueba es mejor usar la URL de ensayo.

A continuación, especificaremos una dirección de correo electrónico para registrar el certificado y crearemos un Secreto de Kubernetes llamado letsencrypt-staging para almacenar la clave privada de la cuenta de ACME. También habilitaremos el mecanismo de comprobación HTTP-01. Para obtener más información sobre estos parámetros, consulte la documentación oficial de cert-manager sobre emisores.

Implemente el ClusterIssuer usando kubectl:

  1. kubectl create -f staging_issuer.yaml

Debería ver el siguiente resultado:

Output
clusterissuer.cert-manager.io/letsencrypt-staging created

Ahora que creamos nuestro emisor de ensayo de Let´s Encrypt, estamos listos para modificar el recurso de Ingress que creamos previamente y habilitar el cifrado TLS para las rutas de echo1.example.com y echo2.example.com.

Abra echo_ingress.yaml de nuevo en su editor favorito:

  1. nano echo_ingress.yaml

Añada lo siguiente al manifiesto de recurso de Ingress:

echo_ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-staging"
spec:
  tls:
  - hosts:
    - echo1.hjdo.net
    - echo2.hjdo.net
    secretName: echo-tls
  rules:
  - host: echo1.hjdo.net
    http:
      paths:
      - backend:
          serviceName: echo1
          servicePort: 80
  - host: echo2.hjdo.net
    http:
      paths:
      - backend:
          serviceName: echo2
          servicePort: 80

Aquí agregamos algunas anotaciones para especificar la ingress.class, que determina el controlador de Ingress que debería utilizarse para implementar las reglas de Ingress. Además, definimos que el cluster-issuer es letsencrypt-staging, el emisor de certificados que acabamos de crear.

Por último, agregamos un bloque de tls a fin de especificar los hosts para los que queremos adquirir certificados y especificamos un secretName. Este secreto contendrá la clave privada TLS y el certificado emitido.

Cuando haya terminado de realizar cambios, guarde y cierre el archivo.

Ahora actualizaremos el recurso de Ingress existente usando kubectl apply:

  1. kubectl apply -f echo_ingress.yaml

Debería ver el siguiente resultado:

Output
ingress.networking.k8s.io/echo-ingress configured

Puede usar kubectl describe para rastrear el estado de los cambios de Ingress que acaba de aplicar:

  1. kubectl describe ingress
Output
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 14m nginx-ingress-controller Ingress default/echo-ingress Normal CreateCertificate 67s cert-manager Successfully created Certificate "echo-tls" Normal UPDATE 53s nginx-ingress-controller Ingress default/echo-ingress

Una vez que el certificado se haya creado con éxito, puede ejecutar un describe adicional sobre este para confirmar aún más que se creó de forma correcta:

  1. kubectl describe certificate

Debería ver el siguiente resultado en la sección Events:

Output
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal GeneratedKey 2m12s cert-manager Generated a new private key Normal Requested 2m12s cert-manager Created new CertificateRequest resource "echo-tls-3768100355" Normal Issued 47s cert-manager Certificate issued successfully

Esto confirma que el certificado TLS se realizó de forma correcta y que el cifrado HTTPS ahora está activo para los dos dominios configurados.

Ahora estamos listos para enviar una solicitud a un servidor de backend echo y probar que HTTPS funciona bien.

Ejecute el siguiente comando wget para enviar una solicitud a echo1.example.com e imprimir los encabezados de respuesta en STDOUT:

  1. wget --save-headers -O- echo1.example.com

Debería ver el siguiente resultado:

Output
. . . HTTP request sent, awaiting response... 308 Permanent Redirect . . . ERROR: cannot verify echo1.example.com's certificate, issued by ‘CN=Fake LE Intermediate X1’: Unable to locally verify the issuer's authority. To connect to echo1.example.com insecurely, use `--no-check-certificate'.

Esto indica que HTTPS se habilitó con éxito, pero el certificado no puede verificarse porque es un certificado temporal de carácter falso emitido por el servidor de ensayo de Let´s Encrypt.

Ahora que probamos que todo funciona usando este certificado temporal falso, podemos implementar certificados de producción para los dos hosts echo1.example.com y echo2.example.com.

Paso 5: Implementar el emisor de producción

En este paso, modificaremos el procedimiento utilizado para proporcionar certificados de ensayo, y generaremos un certificado de producción válido y verificable para nuestros hosts de Ingress.

Para comenzar, crearemos primero un certificado de producción ClusterIssuer.

Abra un archivo llamado prod_issuer.yaml en su editor favorito:

nano prod_issuer.yaml

Pegue el siguiente manifiesto:

prod_issuer.yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
  namespace: cert-manager
spec:
  acme:
    # The ACME server URL
    server: https://acme-v02.api.letsencrypt.org/directory
    # Email address used for ACME registration
    email: your_email_address_here
    # Name of a secret used to store the ACME account private key
    privateKeySecretRef:
      name: letsencrypt-prod
    # Enable the HTTP-01 challenge provider
    solvers:
    - http01:
        ingress:
          class: nginx

Observe la URL del servidor de ACME diferente y el nombre de clave secreta letsencrypt-prod.

Cuando finalice la edición, guarde y cierre el archivo.

Ahora, implemente este emisor usando kubectl:

  1. kubectl create -f prod_issuer.yaml

Debería ver el siguiente resultado:

Output
clusterissuer.cert-manager.io/letsencrypt-prod created

Actualice echo_ingress.yaml para usar este nuevo emisor:

  1. nano echo_ingress.yaml

Realice el siguiente cambio en el archivo:

echo_ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - echo1.hjdo.net
    - echo2.hjdo.net
    secretName: echo-tls
  rules:
  - host: echo1.hjdo.net
    http:
      paths:
      - backend:
          serviceName: echo1
          servicePort: 80
  - host: echo2.hjdo.net
    http:
      paths:
      - backend:
          serviceName: echo2
          servicePort: 80

Aquí, actualizamos el nombre de ClusterIssuer a letsencrypt-prod.

Una vez que esté satisfecho con sus cambios, guarde y cierre el archivo.

Implemente los cambios usando kubectl apply:

  1. kubectl apply -f echo_ingress.yaml
Output
ingress.networking.k8s.io/echo-ingress configured

Espere unos minutos para que el servidor de producción de Let´s Encrypt emita el certificado. Puede supervisar el progreso de la operación usando kubectl describe en el objeto certificate:

  1. kubectl describe certificate echo-tls

El certificado se habrá emitido de forma correcta cuando visualice el siguiente resultado:

Output
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal GeneratedKey 8m10s cert-manager Generated a new private key Normal Requested 8m10s cert-manager Created new CertificateRequest resource "echo-tls-3768100355" Normal Requested 35s cert-manager Created new CertificateRequest resource "echo-tls-4217844635" Normal Issued 10s (x2 over 6m45s) cert-manager Certificate issued successfully

Ahora, realizaremos una prueba usando curl para verificar que HTTPS funcione de forma correcta:

  1. curl echo1.example.com

Debería ver lo siguiente:

Output
<html> <head><title>308 Permanent Redirect</title></head> <body> <center><h1>308 Permanent Redirect</h1></center> <hr><center>nginx/1.15.9</center> </body> </html>

Esto indica que las solicitudes HTTP se redirigen para emplear HTTPS.

Ejecute curl en https://echo1.example.com:

  1. curl https://echo1.example.com

Ahora, debería ver el siguiente resultado:

Output
echo1

Puede ejecutar el comando anterior con el indicador verbose -v para profundizar en el protocolo de enlace del certificado y para verificar la información del certificado.

En este punto, habrá configurado con éxito HTTPS usando un certificado de Let´s Encrypt para su Ingress de Nginx.

Conclusión

A través de esta guía, configuró un Ingress de Nginx para equilibrar las cargas y dirigir las solicitudes externas a los servicios de backend dentro de su clúster de Kubernetes. También protegió el Ingress instalando el proveedor de certificado cert-manager y configurando un certificado de Let´s Encrypt para dos rutas de host.

Existen muchas alternativas al controlador de Ingress de Nginx. Para obtener más información, consulte Controladores de Ingress en la documentación oficial de Kubernetes.

Para hallar una guía sobre la implementación del controlador de Ingress de Nginx con el administrador de paquetes Helm para Kubernetes, consulte Cómo configurar un Ingress de Nginx en Kubernetes de DigitalOcean usando Helm.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
3 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Definitivamente esta es la solución al problema

https://github.com/jetstack/cert-manager/issues/466#issuecomment-715588848

todo lo que sucede es que los pods no pueden acceder al propio cluster a traves del loadBalancer ya que se trafican internamente y eso impide que se satisfagan los challenges de validación del dominio.

Este deploy implementa un proxy horquilla que reescribe las salidas del cluster y las dirige al loadBalancer para que funcione correctamente.

Entre muchos de los posibles problemas que puedes encontrar a la hora de realizar un despliegue de este tipo, el que produce que el Challenge de validar la propiedad del dominio no funcione se debe a que los pods en tu cluster no consiguen acceder al propio cluster a traves de un dominio que apunta al loadbalancer del nginx controller.

Es un problema de configuración de red de K8s, solo me ha ocurrido en clusters de DigitalOcean, en los de AWS habiendo desplegado el Nginx Controller mediante Helms, no me ha ocurrido esta incidencia.

D.O. algun workarround para que un pod pueda validar el Challenge?

https://cert-manager.io/docs/configuration/acme/http01/

Hola, gracias por la orientación, pero sigo el mismo tutorial, solo cambiando por mi dominio y mi correo, y el cert manager no completa la creacion del certificado de prueba, solo queda esperando. Que puedo hacer?

Status: Conditions: Last Transition Time: 2020-04-20T15:22:40Z Message: Waiting for CertificateRequest “letsencrypt-staging-26023181” to complete Reason: InProgress Status: False Type: Ready Events: Type Reason Age From Message


Normal GeneratedKey 47m cert-manager Generated a new private key Normal Requested 47m cert-manager Created new CertificateRequest resource “letsencrypt-staging-26023181”

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel