One place for hosting & domains

      Ingress

      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.

      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.
      • El administrador de paquetes de Helm instalado en su computadora local y Tiller instalado en su clúster, como se detalla en Cómo instalar software en clústeres de Kubernetes con el administrador de paquetes de Helm. Asegúrese de utilizar Helm v2.12.1 o una versión posterior. De lo contrario, podría experimentar problemas al instalar el chart de Helm de cert-manager. Para comprobar la versión de Helm que instaló, ejecute helm version en su máquina local.
      • 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:

      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 create con el indicador -f y especificando el archivo que acaba de guardar como un parámetro:

      • kubectl create -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:

      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:

      • kubectl create -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:

      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.24.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 Ingress que utiliza v0.24.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:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml

      En este caso, utilizamos apply en lugar de create 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.extensions/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:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml

      Debería ver el siguiente resultado:

      Output

      service/ingress-nginx created

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

      • kubectl get svc --namespace=ingress-nginx

      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:

      Pegue la siguiente definición de ingress:

      echo_ingress.yaml

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

      • 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.

      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:

      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 básico de Nginx para realizar enrutamientos virtuales basados en host. En el siguiente paso, instalaremos cert-manager usando Helm para 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, usaremos Helm para instalar 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 certmanager.k8s.io/issuer, añadiendo una sección tls a la especificación de Ingress y configurando uno o más *emisores *para especificar su autoridad de certificación preferida. Para obtener más información sobre los objetos de emisores, consulte la documentación oficial de cert-manager sobre emisores.

      Nota: Verifique que está utilizando Helm v2.12.1 o una versión posterior antes de instalar cert-manager. Para comprobar la versión de Helm que instaló, ejecute helm version en su equipo local.

      Antes de usar Helm para instalar cert-manager en nuestro clúster, debemos crear las Definiciones de recursos personalizados (CRD) de cert-manager. Créelos con apply de manera directa desde el repositorio de cert-manager de GitHub:

      • kubectl apply
      • -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

      Debería ver el siguiente resultado:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificates.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/issuers.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/orders.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/challenges.certmanager.k8s.io created

      A continuación, añadiremos una etiqueta al espacio de nombres kube-system, donde instalaremos cert-manager, para habilitar la validación avanzada de recursos mediante un webhook:

      • kubectl label namespace kube-system certmanager.k8s.io/disable-validation="true"

      Ahora, añadiremos el repositorio de Jetstack de Helm a Helm. Este repositorio contiene el chart de Helm de cert-manager.

      • helm repo add jetstack https://charts.jetstack.io

      Por último, podemos instalar el chart en el espacio de nombres de kube-system:

      • helm install --name cert-manager --namespace kube-system jetstack/cert-manager --version v0.8.0

      Debería ver el siguiente resultado:

      Output

      . . . NOTES: cert-manager has been deployed successfully! In order to begin issuing certificates, you will need to set up a ClusterIssuer or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). More information on the different types of issuers and how to configure them can be found in our documentation: https://cert-manager.readthedocs.io/en/latest/reference/issuers.html For information on how to configure cert-manager to automatically provision Certificates for Ingress resources, take a look at the `ingress-shim` documentation: https://cert-manager.readthedocs.io/en/latest/reference/ingress-shim.html

      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: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
       name: letsencrypt-staging
      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
         http01: {}
      

      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:

      • kubectl create -f staging_issuer.yaml

      Debería ver el siguiente resultado:

      Output

      clusterissuer.certmanager.k8s.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:

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

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-staging
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-staging
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          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:

      • kubectl apply -f echo_ingress.yaml

      Debería ver el siguiente resultado:

      Output

      ingress.extensions/echo-ingress configured

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

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 14m nginx-ingress-controller Ingress default/echo-ingress Normal UPDATE 1m (x2 over 13m) nginx-ingress-controller Ingress default/echo-ingress Normal CreateCertificate 1m cert-manager Successfully created Certificate "letsencrypt-staging"

      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:

      • kubectl describe certificate

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

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Generated 63s cert-manager Generated new private key Normal OrderCreated 63s cert-manager Created Order resource "letsencrypt-staging-147606226" Normal OrderComplete 19s cert-manager Order "letsencrypt-staging-147606226" completed successfully Normal CertIssued 18s 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:

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

      Debería ver el siguiente resultado:

      Output

      URL transformed to HTTPS due to an HSTS policy --2018-12-11 14:38:24-- https://echo1.example.com/ Resolving echo1.example.com (echo1.example.com)... 203.0.113.0 Connecting to echo1.example.com (echo1.example.net)|203.0.113.0|:443... connected. 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: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      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
          http01: {}
      

      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:

      • kubectl create -f prod_issuer.yaml

      Debería ver el siguiente resultado:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-prod created

      Actualice echo_ingress.yaml para usar este nuevo emisor:

      Realice los siguientes cambios al archivo:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-prod
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

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

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

      Implemente los cambios usando kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      Output

      ingress.extensions/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:

      • kubectl describe certificate letsencrypt-prod

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

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Generated 82s cert-manager Generated new private key Normal OrderCreated 82s cert-manager Created Order resource "letsencrypt-prod-2626449824" Normal OrderComplete 37s cert-manager Order "letsencrypt-prod-2626449824" completed successfully Normal CertIssued 37s cert-manager Certificate issued successfully

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

      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:

      • 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.



      Source link

      How to Set Up an Nginx Ingress with Cert-Manager on DigitalOcean Kubernetes


      Introdução

      Os Ingresses do Kubernetes permitem o roteamento do tráfego externo ao cluster do seu Kubernetes de maneira flexível para os Serviços dentro de seu cluster. Essa condição é alcançada quando usamos os Recursos de Ingress – que definem as regras para rotear o tráfego do HTTP e HTTPS para os Serviços do Kubernetes e para os *Controladores *do Ingress, os quais implementam as regras fazendo o balanceamento da carga do tráfego e o seu roteamento para os serviços de backend apropriados. Nginx, Contour, HAProxy e o Traefik são controladores Ingress populares. Os Ingresses fornecem uma alternativa mais eficiente e flexível para configurar vários serviços de LoadBalancer, cada qual usando seu próprio Load Balancer dedicado.

      Neste guia, vamos configurar o Controlador Ingress para Nginx – mantido pelo Kubernetes – e criaremos alguns Recursos de Ingress para rotear o tráfego para vários serviços de back-end fictício. Uma vez configurado o Ingress, vamos instalar o cert-manager no nosso cluster para gerenciar e fornecer certificados TLS para criptografar o tráfego de HTTP para o Ingress.

      Pré-requisitos

      Antes de começar com este guia, você deve ter o seguinte disponível:

      • Um cluster do Kubernetes 1.10+ com controle de acesso baseado em função (RBAC) habilitado
      • A ferramenta kubectl de linha de comando instalada em sua máquina local e configurada para se conectar ao seu cluster. Você pode ler mais sobre como instalar o kubectl na documentação oficial.
      • Um registro de nome de domínio e DNS A que você possa apontar para o DigitalOcean Load Balancer usado pelo Ingress. Se estiver usando o DigitalOcean para gerenciar os registros de DNS do seu domínio, consulte Como gerenciar os registros de DNS para aprender como criar um registro A.
      • O gerenciador de pacotes Helm instalado em sua máquina local e o Tiller instalados no seu cluster, como descrito no tópico Como instalar um software nos clusters do Kubernetes com o gerenciador de pacotes Helm. Certifique-se de que esteja usando o Helm v2.12.1 ou posterior, senão podem ocorrer problemas ao instalar o gráfico Helm cert-manager. Para verificar a versão do Helm que está instalada, execute a helm version em sua máquina local.
      • O utilitário de linha de comando wget instalado em sua máquina local. Você pode instalar o wget utilizando o gerenciador de pacotes integrado em seu sistema operacional.

      Assim que tiver esses componentes configurados, você estará pronto para começar com este guia.

      Passo 1 — Configurando os serviços de back-end fictício

      Antes de implantar o Controlador Ingress, primeiro vamos criar e implantar dois serviços de eco fictício para os quais vamos rotear o tráfego externo usando o Ingress. Os serviços de eco irão executar o contêiner de servidor Web hashicorp/http-echo, os quais retornarão uma página com uma string de texto transmitida quando o servidor Web for iniciado. Para aprender mais sobre o http-echo, consulte seu GitHub Repo e, para aprender mais sobre os Kubernetes Services, consulte o tópico Serviços dos documentos oficiais do Kubernetes.

      Na sua máquina local, crie e edite um arquivo chamado de eco1.yaml usando o nano ou seu editor favorito:

      Cole no manifesto de Serviço e implantação a seguir:

      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
      

      Neste arquivo, definimos um serviço chamado echo1 que faz o roteamento do tráfego para os Pods com o seletor de rótulo app: echo1. Ele aceita o tráfego TCP na porta 80 e o roteia para a porta 5678 -a porta padrão do http-echo.

      Em eguida, definimos uma Implantação, também chamada de echo1, a qual gerencia os Pods com o Seletor de rótulo app:echo1. Especificamos que a Implantação deve ter 2 réplicas de Pod e que os Pods devem iniciar um contêiner chamado echo1 executando a imagem hashicorp/http-echo. Passamos no parâmetro text e o configuramos para o echo1, para que o servidor Web http-echo retorne echo1. Por fim, abrimos a porta 5678 no contêiner do Pod.

      Assim que estiver satisfeito com seu serviço fictício e o manifesto de implantação, salve e feche o arquivo.

      Crie os recursos do Kubernetes usando o kubectl create com o sinalizador -f, especificando o arquivo que você acabou de salvar como um parâmetro:

      • kubectl create -f echo1.yaml

      Você deve ver o seguinte resultado:

      Output

      service/echo1 created deployment.apps/echo1 created

      Verifique se o serviço iniciou corretamente, confirmando que ele tem um ClusterIP, o IP interno no qual o serviço será exposto:

      Você deve ver o seguinte resultado:

      Output

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

      Isso indica que o serviço de echo1 está disponível internamente em 10.245.222.129 na porta 80. Ele encaminhará o tráfego para a containerPort 5678 nos Pods que ele selecionar.

      Agora que o serviço de echo1 está em execução, repita esse processo para o serviço echo2.

      Crie e abra um arquivo chamado 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
      

      Aqui, usamos basicamente o mesmo manifesto de Serviço e implantação acima, mas nomeamos e rotulamos novamente o Serviço e implantação echo2. Além disso, para darmos mais variedade, criaremos apenas 1 réplica do Pod. Nós garantimos que definimos o parâmetro text para o echo2 para que o servidor Web retorne o texto echo2.

      Salve e feche o arquivo e crie os recursos do Kubernetes usando o kubectl:

      • kubectl create -f echo2.yaml

      Você deve ver o seguinte resultado:

      Output

      service/echo2 created deployment.apps/echo2 created

      Novamente, verifique se o serviço está em execução:

      Você deve ver tanto o serviço echo1 como o serviço echo2 com ClusterIPs atribuídos:

      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

      Agora que nossos serviços de Web echo fictícios estão em execução, podemos seguir em frente para implantar o Controlador Ingress para o Nginx.

      Passo 2 — Configurando o Controlador Ingress do Kubernetes para Nginx

      Neste passo, vamos implantar a versão v0.24.1 do Controlador Ingress para Nginx mantido pelo Kubernetes. Note que existem vários Controladores Ingress para Nginx; a comunidade do Kubernetes mantém o controlador que iremos usar neste guia e a Nginx Inc. mantém o kubernetes-ingress. As instruções neste tutorial são baseadas controladores do Guia de instalação oficial para o Controlador Ingress da Kubernetes para Nginx.

      O Controlador Ingress para Nginx consiste de um Pod que executa o servidor Web Nginx e monitora o plano de controle do Kubernetes em relação aos objetos novos e atualizados de Recursos de Ingress. Um recurso Ingress é, essencialmente, uma lista de regras de roteamento de tráfego para serviços de back-end. Por exemplo, uma regra de Ingress pode especificar que o tráfego HTTP chegando no caminho /web1 deve ser direcionado para o servidor Web de back-end web1. Ao usar os recursos de Ingress, é possível realizar o roteamento baseado em host: por exemplo, roteando os pedidos que chegarem para o web1.your_domain.com para o Serviço de back-end do Kubernetes web1.

      Neste caso, devido a estarmos implantando o controlador Ingress para um cluster de Kubernetes da DigitalOcean, o controlador criará um serviço de LoadBalancer, que irá inicializar um balanceador de carga da DigitalOcean para o qual todo o tráfego externo será direcionado. Este balanceador de carga fará o roteamento do tráfego externo para o Pod do controlador Ingress que executa o Nginx, que, na sequência, encaminhará o tráfego para os serviços de back-end apropriados.

      Vamos começar criando os recursos necessários do Kubernetes pelo Controlador Ingress para Nginx. Tais recursos incluem os ConfigMaps que contêm a configuração do controlador, funções de controle de acesso baseado em função (RBAC) para conceder o acesso do controlador à API do Kubernetes, além da Implantação real do controlador Ingress que usa a versão v0.24.1 da imagem do controlador Ingress para Nginx. Para ver uma lista completa dos recursos necessários, consulte o manifesto do repositório Github do Controlador Ingress para Nginx do Kubernetes.

      Para criar esses recursos obrigatórios, utilize o kubectl apply e o sinalizador -f para especificar o arquivo do manifesto hospedado no GitHub:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml

      Usamos o recurso apply em vez do create para que, no futuro, possamos usar cada vez mais usar o apply para modificar os objetos do controlador Ingress, em vez de substituí-los completamente. Para aprender mais sobre o apply, consulte o tópico Gerenciando recursos dos documentos oficiais do Kubernetes.

      Você deve ver o seguinte 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.extensions/nginx-ingress-controller created

      Este resultado também serve como um resumo conveniente de todos os objetos do controlador Ingress criados a partir do manifesto mandatory.yaml.

      Em seguida, vamos criar o serviço LoadBalance do controlador Ingress, o qual criará um Load Balancer da Digital Ocean que irá balancear a carga e rotear o tráfego de HTTP e HTTPS para o Pod do Controlador Ingress implantado no comando anterior.

      Para criar o serviço do LoadBalancer, mais uma vez, utilize o kubectl apply - um arquivo de manifesto que contém a definição do serviço:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml

      Você deve ver o seguinte resultado:

      Output

      service/ingress-nginx created

      Agora, confirme que o Load Balancer da DigitalOcean foi criado com sucesso, buscando os detalhes do serviço com o kubectl:

      • kubectl get svc --namespace=ingress-nginx

      Você deve ver um endereço IP externo, correspondente ao endereço IP do Load Balancer da 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 o endereço de IP externo do Load Balancer, já que você precisará dele em um passo mais a frente.

      Nota: por padrão, o serviço LoadBalancer do Ingress para Nginx tem o service.spec.externalTrafficPolicy ajustado para o valor Local, o qual faz o roteamento do tráfego do balancedor de carga para os nós que executam os Pods do Ingress para Nginx. Os outros nós irão fracassar nas inspeções de integridade do balanceador de carga - propositadamente, de modo aque o tráfego do Ingress não seja roteado para os nós. As políticas de tráfego externas estão além do âmbito deste tutorial, mas para saber mais a respeito, consulte Um aprofundamento nas políticas de tráfego externo do Kubernetes e IP de origem para serviços com o Type=LoadBalancer dos documentos oficiais do Kubernetes.

      Este balanceador de carga recebe o tráfego nas portas HTTP e HTTPS 80 e 443 e o encaminha para o pod do controlador Ingress. Na sequência, o controlador Ingress irá rotear o tráfego para o serviço de back-end apropriado.

      Agora podemos apontar nossos registros de DNS neste Load Balancer externo e criar alguns recursos de Ingress para implementar regras de roteamento de tráfego.

      Passo 3 — Criando o Recurso do Ingress

      Vamos começar criando um recurso de Ingress mínimo para rotear o tráfego direcionado a um dado subdomínio para um serviço de back-end correspondente.

      Neste guia, vamos usar o domínio teste example.com. Você deve substituí-lo por um nome de domínio seu.

      Primeiramente, vamos criar uma regra simples para rotear o tráfego direcionado para echo1.example.com para o serviço de back-end do echo1 e o tráfego direcionado para o echo2.example.com para o serviço de back-end do echo2.

      Inicie abrindo um arquivo chamado echo_ingress.yaml no seu editor favorito:

      Cole na seguinte definição de ingresso:

      echo_ingress.yaml

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

      Quando terminar de editar suas regras do Ingress, salve e feche o arquivo.

      Aqui, especificamos que gostaríamos de criar um resurso de Ingress chamado echo-ingress e rotear o tráfeco com base no cabeçalho do Host. O cabeçalho de Host com um pedido de HTTP especifica o nome de domínio do servidor de destino. Para aprender mais sobre os cabeçalhos de pedidos do Host, consulte a página de definições da Rede de Desenvolvedores da Mozilla (MDN). Os pedidos junto ao host echo1.example.com serão direcionados para o back-end echo1 - configurado no Passo 1 - e os pedidos junto ao host echo2.example.com serão direcionados para o back-end echo2.

      Agora, você pode criar o Ingress usando o kubectl:

      • kubectl apply -f echo_ingress.yaml

      Você verá o seguinte resultado confirmando a criação do Ingress:

      Output

      ingress.extensions/echo-ingress created

      Para testar o Ingress, navegue até o seu serviço de gerenciamento DNS e crie registros A para o echo1.example.com e echo2.example.com apontando para o IP externo do balanceador de carga da DigitalOcean. O IP externo do balanceador de carga é o endereço IP externo do serviço ingress-nginx, que buscamos no passo anterior. Se estiver usando o DigitalOcean para gerenciar os registros de DNS do seu domínio, consulte Como gerenciar os registros de DNS para aprender como criar um registro A.

      Assim que você tiver criado os registros DNS echo1.example.com e echo2.example.com necessários, você pode testar controlador e o recurso do Ingress que criou, utilizando o utilitário de linha de comando curl.

      De sua máquina local, faça o curl do serviço echo1:

      Você deve obter a seguinte resposta do serviço echo1:

      Output

      echo1

      Isso confirma que seu pedido de echo1.example.com está sendo roteado corretamente através do Ingress para Nginx para o serviço de back-end echo1.

      Agora, faça o mesmo teste com o serviço echo2:

      Você deve obter a seguinte resposta do serviço echo2:

      Output

      echo2

      Isso confirma que seu pedido para o echo2.example.com está sendo roteado corretamente através do Ingress para Nginx para o serviço de back-end echo2.

      Neste ponto, você terá definido um Ingress para Nginx básico para executar o roteamento com base em host virtual. No próximo passo, vamos instalar o cert-manager usando o Helm para fornecer certificados TLS para nosso Ingress e habilitar o protocolo HTTPS mais seguro.

      Passo 4 — Instalando e configurando o Cert-Manager

      Neste passo, vamos usar o Helm para instalar o cert-manager no nosso cluster. O cert-manager é um serviço do Kubernetes que fornece certificados TLS do Let’s Encrypt e outras autoridades certificadoras e também gerencia seus ciclos de vida. Os certificados podem ser solicitados e configurados através de observações nos recursos do Ingress junto das notas técnicas do certmanager.k8s.io/issuer, anexando-se uma seção de tls para as especificações do Ingress e configurando-se um ou mais Emissores para especificar a autoridade certificadora de sua preferência. Para aprender mais sobre os objetos do Emissor, consulte a documentação oficial do cert-manager sobre Emissores.

      Nota: certifique-se de que esteja usando o Helm v2.12.1 ou posterior antes de instalar o cert-manager. Para verificar a versão do Helm que está instalada, execute a helm version em sua máquina local.

      Antes de usar o Helm para instalar o cert-manager no nosso cluster, precisamos criar as Definições de recursos personalizadas (CRDs) do cert-manager. Crie-as aplicando-as diretamente do repositório do Github do cert-manager:

      • kubectl apply
      • -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

      Você deve ver o seguinte resultado:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificates.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/issuers.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/orders.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/challenges.certmanager.k8s.io created

      Em seguida, vamos adicionar um rótulo no namespace kube-system, onde vamos instalar o cert-manager a fim de habilitarmos a validação de recursos avançados usando um webhook:

      • kubectl label namespace kube-system certmanager.k8s.io/disable-validation="true"

      Agora, vamos adicionar o repositório Jetstack Helm ao Helm. Esse repositório contém o gráfico Helm cert-manager.

      • helm repo add jetstack https://charts.jetstack.io

      Por fim, podemos instalar o gráfico no namespace kube-system:

      • helm install --name cert-manager --namespace kube-system jetstack/cert-manager --version v0.8.0

      Você deve ver o seguinte resultado:

      Output

      . . . NOTES: cert-manager has been deployed successfully! In order to begin issuing certificates, you will need to set up a ClusterIssuer or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). More information on the different types of issuers and how to configure them can be found in our documentation: https://cert-manager.readthedocs.io/en/latest/reference/issuers.html For information on how to configure cert-manager to automatically provision Certificates for Ingress resources, take a look at the `ingress-shim` documentation: https://cert-manager.readthedocs.io/en/latest/reference/ingress-shim.html

      Isso indica que a instalação do cert-manager foi bem-sucedida.

      Antes de começar a emitir certificados para nossos hosts do Ingress, precisamos criar um emissor, o qual especifica a autoridade certificadora da qual será possível obter os certificados x509 assinados. Neste guia, vamos usar a autoridade o certificado do Let’s Encrypt, que fornece certificados TLS gratuitos e também oferece um servidor de preparação para a realização dos testes da configuração do seu certificado e um servidor de produção para implantar certificados TLS verificáveis.

      Vamos criar um emissor teste para garantir que o mecanismo de fornecimento do certificado esteja funcionando corretamente. Abra um arquivo chamado staging_issuer.yaml no seu editor de texto favorito:

      nano staging_issuer.yaml
      

      Cole no manifesto do ClusterIssuer a seguir:

      staging_issuer.yaml

      apiVersion: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
       name: letsencrypt-staging
      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
         http01: {}
      

      Aqui, especificamos que queremos criar um objeto de ClusterIssuer chamado de letsencrypt-staging e usar o servidor de preparação do Let’s Encrypt. Mais tarde, vamos usar o servidor de produção para implantar nossos certificados. Entretanto, poderá haver solicitações de limitação de taxa em relação ao servidor, de modo que é melhor usar o URL de preparação para os testes.

      Depois, especificamos um endereço de e-mail para registrar o certificado e criamos um Kubernetes Secret chamado letsencrypt-staging para armazenar a chave privada da conta ACME. Também habilitamos o mecanismo de desafio do HTTP-01. Para aprender mais sobre esses parâmetros, consulte a documentação oficial do cert-manager sobre Emissores.

      Implemente o ClusterIssuer usando o kubectl:

      • kubectl create -f staging_issuer.yaml

      Você deve ver o seguinte resultado:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-staging created

      Agora que criamos o nosso emissor preparatório do Let’s Encrypt, estamos prontos para modificar o recurso do Ingress que criamos acima e habilitar a criptografia TLS para os caminhos do echo1.example.com e do echo2.example.com.

      Abra novamente o echo_ingress.yaml no seu editor favorito:

      Adicione o seguinte ao manifesto recurso do Ingress:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-staging
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-staging
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Aqui, adicionamos algumas anotações para especificar a ingress.class, a qual determina o controlador do Ingress que deve ser usado para implementar as regras do Ingress. Além disso, definimos o cluster-issuer para ser o letsencrypt-staging, o emissor de certificados que acabamos de criar.

      Por fim, adicionamos um bloco tls para especificar os hosts para os quais queremos adquirir certificados e especificar um secretName. Esse segredo irá conter a chave privada do TLS e o certificado emitido.

      Quando terminar de fazer as alterações, salve e feche o arquivo.

      Agora, vamos atualizar o recurso do Ingress existente usando o kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      Você deve ver o seguinte resultado:

      Output

      ingress.extensions/echo-ingress configured

      É possível usar o kubectl describe para rastrear o estado das alterações do Ingress que acabou de aplicar:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 14m nginx-ingress-controller Ingress default/echo-ingress Normal UPDATE 1m (x2 over 13m) nginx-ingress-controller Ingress default/echo-ingress Normal CreateCertificate 1m cert-manager Successfully created Certificate "letsencrypt-staging"

      Assim que o certificado tiver sido criado com sucesso, você poderá executar um describe adicional nele para confirmar que sua criação foi bem-sucedida:

      • kubectl describe certificate

      Você deve ver o seguinte resultado na seção Events:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Generated 63s cert-manager Generated new private key Normal OrderCreated 63s cert-manager Created Order resource "letsencrypt-staging-147606226" Normal OrderComplete 19s cert-manager Order "letsencrypt-staging-147606226" completed successfully Normal CertIssued 18s cert-manager Certificate issued successfully

      Isso confirma que o certificado TLS foi emitido com sucesso e a criptografia do HTTPS agora está ativa para os dois domínios configurados.

      Agora, estamos prontos para enviar um pedido para um servidor echo de back-end para testar o funcionamento correto do HTTPS.

      Execute o comando wget a seguir para enviar um pedido para o echo1.example.com e imprima os cabeçalhos de resposta para o STDOUT:

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

      Você deve ver o seguinte resultado:

      Output

      URL transformed to HTTPS due to an HSTS policy --2018-12-11 14:38:24-- https://echo1.example.com/ Resolving echo1.example.com (echo1.example.com)... 203.0.113.0 Connecting to echo1.example.com (echo1.example.net)|203.0.113.0|:443... connected. 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'.

      Isso indica que o HTTPS foi habilitado com sucesso, mas o certificado não pode ser verificado, já que ele é um certificado temporário falso emitido pelo servidor de preparação do Let’s Encrypt.

      Agora que testamos que tudo funciona usando esse certificado falso temporário, podemos implantar os certificados de produção para os dois hosts, o echo1.example.com e o echo2.example.com.

      Passo 5 — Implantando o emissor de produção.

      Neste passo, vamos modificar o procedimento usado para fornecer os certificados de preparo e gerar um certificado de produção válido e verificável para os nossos hosts de Ingress.

      Para começar, vamos primeiro criar um certificado de produção ClusterIssuer.

      Abra um arquivo chamado prod_issuer.yaml no seu editor favorito:

      nano prod_issuer.yaml
      

      Cole no manifesto seguinte:

      prod_issuer.yaml

      apiVersion: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      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
          http01: {}
      

      Note o URL diferente do servidor ACME e o nome da chave secreta do letsencrypt-prod.

      Quando terminar de editar, salve e feche o arquivo.

      Agora, implante esse Emissor usando o kubectl:

      • kubectl create -f prod_issuer.yaml

      Você deve ver o seguinte resultado:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-prod created

      Atualize o echo_ingress.yaml para usar este novo emissor:

      Faça as seguintes alterações no arquivo:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-prod
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Aqui, atualizamos tanto o ClusterIssuer quanto o nome secreto para o letsencrypt-prod.

      Assim que estiver satisfeito com suas alterações, salve e feche o arquivo.

      Implemente as alterações usando o kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      Output

      ingress.extensions/echo-ingress configured

      Espere alguns minutos para o servidor de produção do Let’s Encrypt emitir o certificado. Você pode rastrear o andamento do processo, usando a opção kubectl describe no objeto certificate:

      • kubectl describe certificate letsencrypt-prod

      Assim que você ver o seguinte resultado, significa que o certificado foi emitido com sucesso:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Generated 82s cert-manager Generated new private key Normal OrderCreated 82s cert-manager Created Order resource "letsencrypt-prod-2626449824" Normal OrderComplete 37s cert-manager Order "letsencrypt-prod-2626449824" completed successfully Normal CertIssued 37s cert-manager Certificate issued successfully

      Agora, vamos realizar um teste usando o curl para verificar se o HTTPS está funcionando corretamente:

      Você deve ver o seguinte:

      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>

      Isso indica que os pedidos do HTTP estão sendo redirecionados para usar o HTTPS.

      Execute o curl em https://echo1.example.com:

      • curl https://echo1.example.com

      Agora, você deve ver o seguinte resultado:

      Output

      echo1

      É possível executar o comando anterior com o sinalizador detalhado -v para uma busca mais aprofundada no handshake do certificado e para verificar as informações do certificado.

      Neste ponto, você já terá configurado o HTTPS com sucesso usando um certificado do Let’s Encrypt para o Ingress do seu Nginx.

      Conclusão

      Neste guia, você configurou um Ingress para Nginx para balancear carga e rotear pedidos externos para serviços de backend dentro do seu cluster do Kubernetes. Você também protegeu o Ingress, instalando o provedor de certificados cert-manager e configurando um certificado do Let’s Encrypt para dois caminhos de host.

      Existem muitas alternativas para o controlador Ingress para Nginx. Para saber mais, consulte o tópico Controladores Ingress da documentação oficial do Kubernetes.



      Source link

      Как настроить Nginx Ingress с Cert-Manager в DigitalOcean Kubernetes


      Введение

      Сущности Ingress в Kubernetes обеспечивают гибкую маршрутизацию внешнего трафика кластера Kubernetes среди служб внутри кластера. Это достигается с помощью ресурсов Ingress, которые определяют правила маршрутизации трафика HTTP и HTTPS для служб Kubernetes, и контроллеров Ingress, которые реализуют правила порседством балансировки нагрузки трафика и его перенаправления на соответствующие службы серверной части. В число популярных контроллеров Ingress входят Nginx, Contour, HAProxy и Traefik. Сущности Ingress — это более эффективная и гибкая альтернатива настройке множеству разных объектов служб LoadBalancer, каждый из которых использует собственный выделенный балансировщик нагрузки.

      В этом руководстве мы настроим контроллер Nginx Ingress, обслуживаемый Kubernetes, и создадим несколько ресурсов Ingress для маршуртизации трафика на фиктивные серверные службы. После настройки Ingress мы установим в наш кластер cert-manager для управления и распределения сертификатами TLS для шифрования трафика HTTP в Ingress.

      Предварительные требования

      Прежде чем начать прохождение этого обучающего модуля, вам потребуется следующее:

      • Кластер Kubernetes 1.10+ с включенным контролем доступа на основе ролей (RBAC)
      • Инструмент командной строки kubectl, установленный на локальном компьютере и настроенный для подключения к вашему кластеру. Дополнительную информацию об установке kubectl можно найти в официальной документации.
      • Доменное имя и записи DNS A, которые можно направить на балансировщик нагрузки DigitalOcean, используемый Ingress. Если вы используете DigitalOcean для управления записями DNS вашего домена, руководство Управление записями DNS поможет вам научиться создавать записи класса A.
      • Диспетчер пакетов Helm на локальном компьютере и Tiller на кластере, установленные в соответствии с указаниями обучающего модуля «Установка программного обеспечения на кластерах Kubernetes с диспетчером пакетов Helm». Убедитесь, что вы используете версию Helm 2.12.1 или более позднюю, иначе могут возникнуть проблемы с установкой таблицы cert-manager в Helm. Чтобы проверить установленную версию Helm, запустите команду helm version на локальном компьютере.
      • Инструмент командной строки wget, установленный на локальном компьютере. Вы можете установить wget с помощью диспетчера пакетов, встроенного в операционную систему.

      Проверив наличие этих компонентов, вы можете начинать прохождение этого обучающего модуля.

      Шаг 1 — Настройка фиктивных серверных служб

      Перед развертыванием контроллера Ingress мы создадим и развернем две фиктивных службы echo, на которые будем перенаправлять внешний трафик с помощью Ingress. Службы echo будут запускать контейнер hashicorp/http-echo, возвращающий страницу с текстовой строкой, переданной при запуске веб-сервера. Дополнительную информацию по http-echo можно получить в GitHub Repo, а дополнительную информацию о службах Kubernetes можно найти в разделе Services в официальной документации Kubernetes.

      Создайте на локальном компьютере файл echo1.yaml и откройте его в nano или другом текстовом редакторе:

      Вставьте в него следующий манифест служб и развертывания:

      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
      

      В этом файле мы определяем службу с именем echo1, которая перенаправляет трафик в поды с помощью селектора ярлыка app: echo1. Она принимает трафик TCP на порту 80 и перенаправляет его на порт 5678,используемый http-echo по умолчанию.

      Затем мы определяем развертывание с именем echo1, которое управляет подами с селектором app: echo1 Label Selector. Мы указываем, что в развертывании должно быть 2 копии пода, и что поды должны запускать контейнер echo1 с образом hashicorp/http-echo. Мы передаем параметр text и устанавливаем для него значение echo1, так что веб-сервер http-echo возвращает echo1. Наконец, мы открываем порт 5678 в контейнере подов.

      Проверив манифест фиктивной службы и развертывания, сохраните и закройте файл.

      Создайте ресурсы Kubernetes с помощью kubectl create с флагом -f, указав только что сохраненный файл в качестве параметра:

      • kubectl create -f echo1.yaml

      Вы должны увидеть следующий результат:

      Output

      service/echo1 created deployment.apps/echo1 created

      Убедитесь, что служба запустилась правильно, и проверьте наличие ClusterIP, внутреннего IP-адреса, по которому доступна служба:

      Вы должны увидеть следующий результат:

      Output

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

      Это означает, что служба echo1 доступна по внутреннему IP-адресу 10.245.222.129 на порту 80. Она будет перенаправлять трафик в порт контейнера 5678 на выбранных ей подах.

      Теперь служба echo1 запущена, и мы можем повторить процедуру для службы echo2.

      Создайте и откройте файл с именем 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
      

      Здесь мы используем тот же манифест служб и развертывания, что и выше, но будем использовать имя и ярлык echo2. Кроме того, для разнообразия мы создадим только 1 копию пода. Для параметра text мы установим значение echo2, чтобы веб-сервер возвращал текст echo2.

      Сохраните и закройте файл и создайте ресурсы Kubernetes с помощью kubectl:

      • kubectl create -f echo2.yaml

      Вы должны увидеть следующий результат:

      Output

      service/echo2 created deployment.apps/echo2 created

      Еще раз проверьте, запущена ли служба:

      Вы должны увидеть службы echo1 и echo2 с назначенными им значениями ClusterIP:

      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

      Теперь наши фиктивные веб-службы эхо запущены, и мы можем перейти к развертыванию контроллера Nginx Ingress.

      Шаг 2 — Настройка контроллера Kubernetes Nginx Ingress

      На этом шаге мы развернем версию v0.24.1 контроллера Nginx Ingress, обслуживаемого Kubernetes. Существует несколько контроллеров Nginx Ingress. Сообщество Kubernetes обслуживает контроллер, используемый в этом обучающем модуле, а Nginx Inc. обслуживает kubernetes-ingress. Указания этого обучающего модуля основаны на приведенных в официальном руководстве по установке контроллера Kubernetes Nginx Ingress.

      Контроллер Nginx Ingress состоит из пода, который запускает веб-сервер Nginx и наблюдает за плоскостью управления Kubernetes для обнаружения новых и обновленных объектов ресурсов Ingress. Ресурс Ingress фактически представляет собой список правил маршрутизации трафика для серверных служб. Например, правило Ingress может указывать, что входящий трафик HTTP на пути /web1 следует перенаправлять на веб-сервер web1. С помощью ресурсов Ingress также можно выполнять маршрутизацию на базе хоста: например, запросы маршрутизации для web1.your_domain.com на серверную службу Kubernetes web1.

      В данном случае мы развертываем контроллер Ingress в кластере DigitalOcean Kubernetes, и контроллер создаст службу LoadBalancer, запускающую балансировщик нагрузки DigitalOcean, на который будет направляться весь внешний трафик. Балансировщик нагрузки будет направлять внешний трафик на под контроллера Ingress под управлением Nginx, откуда трафик будет перенаправляться в соответствующие серверные службы.

      Для начала мы создадим необходимые ресурсы Kubernetes для контроллера Nginx Ingress. В их число входят карты ConfigMaps, содержащие конфигурацию контроллера, роли системы RBAC, предоставляющие контроллеру доступ Kubernetes API, и фактическое развертывание контроллера Ingress, использующее версию 0.24.1 образа контроллера Nginx Ingress. Чтоб просмотреть полный список требуемых ресурсов, ознакомьтесь с манифестом репозитория контроллера Kubernetes Nginx Ingress на GitHub.

      Для создания этих обязательных ресурсов используйте команду kubectl apply с флагом -f для указания файла манифеста, размещенного на GitHub:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml

      Мы используем apply вместо create ,чтобы в будущем мы могли применять изменения к объектам контроллера Ingress, а не перезаписывать их полностью. Дополнительную информацию о команде apply можно найти в разделе «Управление ресурсами» в официальной документации по Kubernetes.

      Вы должны увидеть следующий результат:

      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.extensions/nginx-ingress-controller created

      На этом экране результатов приведен удобный обзор всех объектов контроллера Ingress, созданных из манифеста mandatory.yaml.

      Далее мы создадим службу LoadBalancer контроллера Ingress, которая создаст балансировщик нагрузки DigitalOcean для балансировки и маршрутизации трафика HTTP и HTTPS на под контроллера Ingress, который мы развернули предыдущей командой.

      Для создания службы LoadBalancer мы снова используем команду kubectl apply с файлом манифеста, содержащим определение службы:

      • kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml

      Вы должны увидеть следующий результат:

      Output

      service/ingress-nginx created

      Убедитесь, что балансировщик нагрузки DigitalOcean создан успешно, получив детали службы с помощью команды kubectl:

      • kubectl get svc --namespace=ingress-nginx

      Вы должны использовать внешний IP-адрес, соответствующий IP-адресу балансировщика нагрузки 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

      Запишите внешний IP-адрес балансировщика нагрузки, поскольку он потребуется вам позднее.

      Примечание. По умолчанию служба Nginx Ingress LoadBalancer использует для параметра service.spec.externalTrafficPolicy значение Local, в результате чего весь трафик балансировщика нагрузки перенаправляется на узлы, где запущены поды Nginx Ingress. Другие узлы целенаправленно не будут проходить проверки балансировщика нагрузки, чтобы трафик Ingress не направлялся на эти узлы. Политики внешнего трафика не описываются в этом обучающем модуле, но дополнительную информацию можно найти в руководствах «Подробное описание политик внешнего трафика Kubernetes» и «Исходный IP для служб с типом Type=LoadBalancer» в официальной документации по Kubernetes.

      Этот балансировщик нагрузки принимает трафик на портах HTTP и HTTPS 80 и 443, и перенаправляет его на под контроллера Ingress. Контроллер Ingress перенаправляет трафик на соответствующую серверную службу.

      Теперь мы сделаем так, чтобы наши записи DNS указывали на этот внешний балансировщик нагрузки, и создадим некоторые ресурсы Ingress для внедрения правил маршрутизации трафика.

      Шаг 3 — Создание ресурсов Ingress

      Для начала мы создадим минимальный ресурс Ingress для перенаправления трафика указанного субдомена на соответствующую серверную службу.

      В этом обучающем модуле мы используем тестовый домен example.com. Вы должны заменить его вашим доменным именем.

      Вначале мы создадим простое правило для перенаправления адресованного echo1.example.com трафика на серверную службу echo1 и адресованного echo2.example.com трафика на серверную службу echo2.

      Для начала откройте файл echo_ingress.yaml в предпочитаемом редакторе:

      Вставьте следующее определение Ingress:

      echo_ingress.yaml

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

      Когда вы закончите редактирование правил Ingress, сохраните и закройте файл.

      Мы указали, что хотим создать ресурс Ingress с именем echo-ingress и перенаправлять трафик на базе заголовка Host. В запросе HTTP заголовок Host указывает доменное имя целевого сервера. Дополнительную информацию о заголовках Host можно найти на странице определений Mozilla Developer Network. Запросы хоста echo1.example.com будут перенаправляться на серверную службу echo1, настроенную на шаге 1, а запросы хоста echo2.example.com будут перенаправляться на серверную службу echo2.

      Теперь вы можете создать Ingress с помощью kubectl:

      • kubectl apply -f echo_ingress.yaml

      Вы увидите следующий экран результатов, подвтерждающий создание Ingress:

      Output

      ingress.extensions/echo-ingress created

      Чтобы протестировать Ingress, перейдите в службу управления DNS и создайте записи A для echo1.example.com и echo2.example.com, указывающие на внешний IP-адрес балансировщика нагрузки DigitalOcean. Внешний IP-адрес балансировщика нагрузки соответствует внешнему IP-адресу службы ingress-nginx, полученному на предыдущем шаге. Если вы используете DigitalOcean для управления записями DNS вашего домена, руководство Управление записями DNS поможет вам научиться создавать записи класса A.

      После создания необходимых записей echo1.example.com и echo2.example.com вы можете протестировать контроллер Ingress и созданные ресурсы с помощью утилиты командной строки curl.

      Выполните команду curl для службы echo1 на локальном компьютере:

      Вы должны получить следующий ответ от службы echo1:

      Output

      echo1

      Это подтверждает, что ваш запрос echo1.example.com правильно перенаправляется через Nginx ingress в серверную службу echo1.

      Теперь повторите этот тест для службы echo2:

      Вы должны получить следующий ответ от службы echo2:

      Output

      echo2

      Это подтверждает, что ваш запрос echo2.example.com правильно перенаправляется через Nginx ingress в серверную службу echo2.

      Вы успешно выполнили базовую настройку Nginx Ingress для маршрутизации на базе виртуального хоста. На следующем шаге мы установим cert-manager с помощью Helm для предоставления сертификатов TLS для Ingress и использования более защищенного протокола HTTPS.

      Шаг 4 — Установка и настройка Cert-Manager

      На этмо шаге мы используем Helm для установки cert-manager в нашем кластере. cert-manager — это служба Kubernetes, предоставляющая сертификаты TLS от Let’s Encrypt и других центров сертификации и управляющая их жизненными циклами. Сертификаты можно запрашивать и настраивать посредством аннотации ресурсов Ingress с помощью аннотации certmanager.k8s.io/issuer с добавлением раздела tls в спецификацию Ingress и настройкой одного или нескольких элементов Issuer для определения предпочитаемого центра сертификации. Дополнительную информацию об объектах Issuer можно найти в официальной документации cert-manager по элементам Issuer.

      Примечание. Перед установкой cert-manager убедитесь, что вы используете версию Helm 2.12.1 или более позднюю версию. Чтобы проверить установленную версию Helm, запустите команду helm version на локальном компьютере.

      Прежде чем использовать Helm для установки cert-manager в нашем кластере, нам нужно создать собственные определения ресурсов (CRD) для cert-manager. Используйте для их создания команду apply, чтобы применить их непосредственно из репозитория cert-manager на GitHub:

      • kubectl apply
      • -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.8/deploy/manifests/00-crds.yaml

      Вы должны увидеть следующий результат:

      Output

      customresourcedefinition.apiextensions.k8s.io/certificates.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/issuers.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/clusterissuers.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/orders.certmanager.k8s.io created customresourcedefinition.apiextensions.k8s.io/challenges.certmanager.k8s.io created

      Теперь мы добавим ярлык пространства имен kube-system, куда мы устанавливаем cert-manager, чтобы обеспечить расширенную проверку ресурсов с помощью webhook:

      • kubectl label namespace kube-system certmanager.k8s.io/disable-validation="true"

      Теперь мы добавим репозиторий Jetstack Helm в Helm. Этот репозиторий содержит таблицу Helm для cert-manager.

      • helm repo add jetstack https://charts.jetstack.io

      Наконец, мы установим таблицу в пространство имен kube-system:

      • helm install --name cert-manager --namespace kube-system jetstack/cert-manager --version v0.8.0

      Вы должны увидеть следующий результат:

      Output

      . . . NOTES: cert-manager has been deployed successfully! In order to begin issuing certificates, you will need to set up a ClusterIssuer or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). More information on the different types of issuers and how to configure them can be found in our documentation: https://cert-manager.readthedocs.io/en/latest/reference/issuers.html For information on how to configure cert-manager to automatically provision Certificates for Ingress resources, take a look at the `ingress-shim` documentation: https://cert-manager.readthedocs.io/en/latest/reference/ingress-shim.html

      Это означает, что установка cert-manager выполнена успешно.

      Прежде чем мы начнем выдачу сертификатов для наших хостов Ingress, нам нужно создать элемент Issuer, определяющий центр сертификации, откуда можно получить подписанные сертификаты x509. В этом обучающем модуле мы используем центр сертификации Let’s Encrypt, предоставляющий бесплатные сертификаты TLS и обеспечивающий сервер для тестирования конфигурации сертификатов и рабочий сервер для развертывания проверяемых сертификатов TLS.

      Создадим тестовый элемент Issuer, чтобы проверить правильность работы механизма распределения сертификатов. Откройте файл с именем staging_issuer.yaml в своем любимом текстовом редакторе:

      nano staging_issuer.yaml
      

      Вставьте в него следующий манифест ClusterIssuer:

      staging_issuer.yaml

      apiVersion: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
       name: letsencrypt-staging
      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
         http01: {}
      

      Здесь мы указываем, что хотим создать объект ClusterIssuer с именем letsencrypt-staging и использовать сервер размещения Let’s Encrypt. Далее мы будем использовать для развертывания сертификатов производственный сервер, но в на этом сервере может быть ограничено количество запросов, и поэтому для тестирования лучше всего использовать URL сервера размещения.

      Затем мы укажем адрес электронной почты для регистрации сертификата и создадим секрет Kubernetes с именем letsencrypt-staging для сохранения закрытого ключа учетной записи ACME. Также мы активируем механизм вызовов HTTP-01. Дополнительную информацию об этих параметрах можно найти в официальной документации cert-manager по элементам Issuer.

      Разверните ClusterIssuer с помощью kubectl:

      • kubectl create -f staging_issuer.yaml

      Вы должны увидеть следующий результат:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-staging created

      Теперь мы создали элемент Issuer для сервера размещения Let’s Encrypt и готовы изменить созданный выше ресурс Ingress и активировать шифрование TLS для путей echo1.example.com и echo2.example.com.

      Откройте echo_ingress.yaml в своем любимом редакторе еще раз:

      Добавьте в манифест ресурсов Ingress следующее:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-staging
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-staging
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Здесь мы добавим несколько аннотаций для указания класса Ingress.class, определяющего контроллер Ingress, который должен использоваться для реализации правил Ingress. Кроме того, мы определим для cluster-issuer элемент сертификации letsencrypt-staging, который мы только что создали.

      Наконец, мы добавим блок tls для указания хостов, для которых мы хотим получить сертификаты, а также укажем secretName. Этот секрет будет содержать закрытый ключ TLS и выданный сертификат.

      Когда вы закончите внесение изменений, сохраните и закройте файл.

      Теперь мы обновим существующие ресурсы Ingress с помощью команды kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      Вы должны увидеть следующий результат:

      Output

      ingress.extensions/echo-ingress configured

      Вы можете использовать команду kubectl describe для отслеживания состояния изменений Ingress, которые вы только что применили:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 14m nginx-ingress-controller Ingress default/echo-ingress Normal UPDATE 1m (x2 over 13m) nginx-ingress-controller Ingress default/echo-ingress Normal CreateCertificate 1m cert-manager Successfully created Certificate "letsencrypt-staging"

      После успешного создания сертификата вы можете запустить дополнительную команду describe, чтобы еще раз убедиться в успешном его создании:

      • kubectl describe certificate

      Вы должны увидеть следующие результаты в разделе Events:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Generated 63s cert-manager Generated new private key Normal OrderCreated 63s cert-manager Created Order resource "letsencrypt-staging-147606226" Normal OrderComplete 19s cert-manager Order "letsencrypt-staging-147606226" completed successfully Normal CertIssued 18s cert-manager Certificate issued successfully

      Это подтверждает, что сертификат TLS выдан успешно, и шифрование HTTPS активно для двух настроенных доменов.

      Теперь мы готовы отправить запрос на сервер echo для тестирования работы HTTPS.

      Запустите следующую команду wget для отправки запроса на echo1.example.com и распечатайте заголовки ответов в STDOUT:

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

      Вы должны увидеть следующий результат:

      Output

      URL transformed to HTTPS due to an HSTS policy --2018-12-11 14:38:24-- https://echo1.example.com/ Resolving echo1.example.com (echo1.example.com)... 203.0.113.0 Connecting to echo1.example.com (echo1.example.net)|203.0.113.0|:443... connected. 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'.

      Это означает, что протокол HTTPS успешно активирован, но сертификат не удается проверить, поскольку это фиктивный временный сертификат, выданный сервером размещения Let’s Encrypt.

      Мы убедились, что с временным фиктивным сертификатом все работает и можем развернуть два производственных сертификата для двух хостов echo1.example.com и echo2.example.com.

      Шаг 5 — Развертывание элемента Issuer в производственной среде

      На этом шаге мы изменим процедуру, используемую для выделения фиктивных сертификатов, и генерируем действительный производственный сертификат для наших хостов Ingress.

      Вначале мы создадим производственный сертификат ClusterIssuer.

      Откройте файл с именем prod_issuer.yaml в своем любимом редакторе:

      nano prod_issuer.yaml
      

      Вставьте в него следующий манифест:

      prod_issuer.yaml

      apiVersion: certmanager.k8s.io/v1alpha1
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-prod
      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
          http01: {}
      

      Обратите внимание на другой URL сервера ACME и имя секретного ключа letsencrypt-prod.

      Когда вы закончите редактирование, сохраните и закройте файл.

      Теперь разверните элемент Issuer с помощью kubectl:

      • kubectl create -f prod_issuer.yaml

      Вы должны увидеть следующий результат:

      Output

      clusterissuer.certmanager.k8s.io/letsencrypt-prod created

      Обновите echo_ingress.yaml для использования нового элемента Issuer:

      Внесите в файл следующие изменения:

      echo_ingress.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
        annotations:  
          kubernetes.io/ingress.class: nginx
          certmanager.k8s.io/cluster-issuer: letsencrypt-prod
      spec:
        tls:
        - hosts:
          - echo1.example.com
          - echo2.example.com
          secretName: letsencrypt-prod
        rules:
        - host: echo1.example.com
          http:
            paths:
            - backend:
                serviceName: echo1
                servicePort: 80
        - host: echo2.example.com
          http:
            paths:
            - backend:
                serviceName: echo2
                servicePort: 80
      

      Здесь мы обновим ClusterIssuer и секретное имя на letsencrypt-prod.

      После внесения изменений сохраните и закройте файл.

      Разверните изменения с помощью команды kubectl apply:

      • kubectl apply -f echo_ingress.yaml

      Output

      ingress.extensions/echo-ingress configured

      Подождите несколько минут, чтобы дать производственному серверу Let’s Encrypt выдать сертификат. Вы можете отслеживать ход выполнения с помощью команды kubectl describe для объекта certificate:

      • kubectl describe certificate letsencrypt-prod

      Следующий экран результатов означает, что сертификат успешно установлен:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Generated 82s cert-manager Generated new private key Normal OrderCreated 82s cert-manager Created Order resource "letsencrypt-prod-2626449824" Normal OrderComplete 37s cert-manager Order "letsencrypt-prod-2626449824" completed successfully Normal CertIssued 37s cert-manager Certificate issued successfully

      Теперь мы проведем тестирование с помощью curl, чтобы подтвердить правильную работу HTTPS:

      Вы должны увидеть следующее:

      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>

      Это означает, что запросы HTTP перенаправляются для использования HTTPS.

      Запустите curl на https://echo1.example.com:

      • curl https://echo1.example.com

      Вы должны увидеть следующий результат:

      Output

      echo1

      Вы можете запустить предыдущую команду с флагом -v для получения развернутой информации о соединении сертификата и проверки информации о сертификате.

      Вы успешно настроили HTTPS с помощью сертификата Let’s Encrypt для вашего Nginx Ingress.

      Заключение

      В этом обучающем модуле вы настроили Nginx Ingress для балансировки нагрузки и перенаправления внешних запросов на серверные службы внутри кластера Kubernetes. Также вы защитили Ingress, установив элемент обеспечения сертификата cert-manager и установив для двух путей хоста сертификат Let’s Encrypt.

      Существует множество альтернатив использованию контроллера Nginx Ingress. Дополнительную информацию можно найти в разделе «Контроллеры Ingress» в официальной документации Kubernetes.



      Source link