Del perímetro a la malla: Exposición de aplicaciones de la malla de servicios a través de Ingress de GKE

En este instructivo, se muestra cómo combinar Anthos Service Mesh con Cloud Load Balancing para exponer aplicaciones en una malla de servicios a los clientes de Internet.

Anthos Service Mesh es una malla de servicios administrada, basada en Istio, que proporciona una capa de comunicación estandarizada, observable y más segura para aplicaciones. Ya sea que uses Anthos Service Mesh, Traffic Director o Istio, una malla de servicios proporciona una plataforma de comunicación integral para clientes que se comunican en la malla. Sin embargo, conectar los clientes que están fuera de la malla a las aplicaciones alojadas en ella sigue siendo un desafío.

Puedes exponer una aplicación a los clientes de muchas maneras, según la ubicación en que estos se encuentren. En este instructivo, se muestra cómo exponer una aplicación a los clientes mediante la combinación de Cloud Load Balancing y Anthos Service Mesh para integrar balanceadores de cargas en una malla de servicios. Este instructivo está dirigido a profesionales avanzados que ejecutan Anthos Service Mesh o Istio en Google Kubernetes Engine.

Puerta de enlace de entrada de la malla

En Istio 0.8, se agregó la puerta de enlace de entrada de la malla, que proporciona un conjunto exclusivo de proxies cuyos puertos están expuestos al tráfico que proviene del exterior de la malla de servicios. Gracias a estos proxies de entrada de la malla, puedes controlar por separado el comportamiento de exposición de L4 y el comportamiento de enrutamiento de la aplicación. Los proxies también te permiten aplicar enrutamiento y políticas al tráfico externo a la malla antes de que llegue a un proxy de sidecar de la aplicación. La entrada de la malla define el tratamiento del tráfico cuando llega a un nodo en la malla, pero los componentes externos deben definir cómo llega el tráfico primero a la malla.

Para administrar este tráfico externo, necesitas un balanceador de cargas externo a la malla. En este instructivo, se usa Google Cloud Load Balancing aprovisionado a través de recursos de Ingress de GKE para automatizar la implementación. El ejemplo canónico de esta configuración es un servicio de balanceo de cargas externo que (en el caso de Google Cloud) implementa un balanceador de cargas de TCP/UDP público. Ese balanceador de cargas apunta a los NodePorts de un clúster de GKE. Estos NodePorts exponen los Pods de puerta de enlace de entrada de Istio, que enrutan el tráfico a los proxies de sidecar de la malla descendente. En el siguiente diagrama, se ilustra esta topología. El balanceo de cargas para el tráfico privado interno se parece a esta arquitectura, excepto que implementas un balanceador de cargas de TCP/UDP interno en su lugar.

Un balanceador de cargas externo enruta los clientes externos a la malla a través de proxies de puerta de enlace de entrada.

El uso del balanceo de cargas transparente de L4 con una puerta de enlace de entrada de la malla ofrece las siguientes ventajas:

  • Esta configuración simplifica la implementación del balanceador de cargas.
  • El balanceador de cargas proporciona una IP virtual estable (VIP), verificación de estado y distribución de tráfico confiable cuando se producen cambios en el clúster, interrupciones del nodo o interrupciones de procesos.
  • Todas las reglas de enrutamiento, la terminación de TLS y la política de tráfico se manejan en una sola ubicación en la puerta de enlace de entrada de la malla.

Ingress y servicios de GKE

Puedes proporcionar acceso a las aplicaciones a los clientes que se encuentran fuera del clúster de muchas maneras. En la siguiente tabla, se enumeran los componentes fundamentales de Kubernetes disponibles para implementar balanceadores de cargas en Google Cloud. El tipo de balanceador de cargas que usas para exponer las aplicaciones a los clientes depende en gran medida de si los clientes son externos o internos, qué tipo de asistencia de protocolo se requiere y si la malla de servicios abarca varios clústeres de GKE o si está en un solo clúster.

Todos los tipos de balanceadores de cargas de la siguiente tabla pueden exponer las aplicaciones alojadas en la malla, según el caso de uso.

Recurso de GKE Balanceador de cargas basado en la nube Características
Ingress para balanceo de cargas de HTTP(S) externo Balanceador de cargas de HTTP(S) externo

Proxies de L7 en puntos de presencia perimetrales (PoP) de Google

VIP pública

Con alcance mundial

Un solo clúster

Ingress para balanceo de cargas de HTTP(S) interno Balanceador de cargas de HTTP(S) interno

Proxies de L7 dentro de la red de nube privada virtual (VPC)

VIP privada

Con alcance regional

Un solo clúster

Servicio de LoadBalancer externo Balanceador de cargas de TCP/UDP externo

Transferencia de L4 en los PoP perimetrales de Google

VIP pública

Con alcance regional

Un solo clúster

Service de LoadBalancer interno Balanceadores de cargas de TCP/UDP internos

Transferencia de L4 en la red de enrutamiento de VPC

VIP privada

Con alcance regional

Un solo clúster

Ingress de varios clústeres (ingress externa de varios clústeres) Balanceador de cargas HTTP(S) externo

Proxies de L7 en los PoP perimetrales de Google

VIP pública

Con alcance mundial

Varios clústeres

Aunque el balanceador de cargas predeterminado para Anthos Service Mesh es el balanceador de cargas de TCP/UDP externo, en este instructivo, nos enfocamos en el balanceador de cargas de HTTP(S) externo que puedes implementar mediante el balanceo de cargas de HTTP(S) externo. El balanceador de cargas de HTTP(S) externo proporciona integración en servicios perimetrales como Identity-Aware Proxy (IAP), Google Cloud Armor y Cloud CDN, así como una red distribuida global de proxies perimetrales. En la siguiente sección, se describe la arquitectura y las ventajas de usar dos capas de balanceo de cargas de HTTP.

Entrada de la nube y entrada de la malla

La implementación del balanceo de cargas de L7 externo fuera de la malla, junto con una capa de entrada de la malla, ofrece ventajas significativas, en especial para el tráfico de Internet. Aunque las puertas de enlace de entrada de Anthos Service Mesh y de Istio proporcionan enrutamiento avanzado y administración del tráfico en la malla, algunas funciones se entregan mejor en el perímetro de la red. Aprovechar las herramientas de redes del perímetro de Internet a través del balanceo de cargas de HTTP(S) externo de Google Cloud puede proporcionar importantes beneficios de rendimiento, confiabilidad o seguridad en la entrada basada en la malla. Los beneficios son los siguientes:

Esta capa externa de balanceo de cargas de L7 se denomina entrada de la nube porque se compila en balanceadores de cargas administrados en la nube, y no en los proxies autoadministrados que usa la entrada de la malla. En la combinación de la entrada de la nube y de la malla, se usan funciones complementarias de la infraestructura de Google Cloud y la malla. En el siguiente diagrama, se muestra cómo puedes combinar la entrada de la nube y la entrada de la malla a fin de que funcionen como dos capas de balanceo de cargas para el tráfico de Internet.

La entrada de la nube actúa como puerta de enlace para el tráfico externo que ingresa a la malla a través de la red de VPC.

En esta topología, la capa de entrada de la nube origina el tráfico desde el exterior de la malla de servicios y lo dirige a la capa de entrada de la malla. Luego, la capa de entrada de la malla dirige el tráfico a los backends de aplicaciones alojadas en la malla.

Topología de la entrada de la nube y de la malla

En esta sección, se describen las funciones complementarias que cada capa de entrada cumple cuando se usan juntas. Estas funciones no son reglas concretas, sino lineamientos en los que se usan las ventajas de cada capa. Es probable que haya variaciones de este patrón, según tu caso de uso.

  • Entrada de la nube. Cuando se combina con la entrada de la malla, es más conveniente usar la capa de entrada de la nube para la seguridad perimetral y el balanceo de cargas global. Debido a que la capa de entrada de la nube está integrada en la protección contra DSD, los firewalls en la nube, la autenticación y los productos de encriptación en el perímetro, esta capa tiene un gran rendimiento en la ejecución de estos servicios fuera de la malla. La lógica de enrutamiento suele ser sencilla en esta capa, pero la lógica puede ser más compleja para entornos de varios clústeres y multirregionales. Debido a la función crítica de los balanceadores de cargas orientados a Internet, es probable que la capa de entrada de la nube se administre mediante un equipo de infraestructura que tenga un control exclusivo sobre cómo se exponen y protegen las aplicaciones en Internet. Este control también hace que esta capa sea menos flexible y dinámica que una infraestructura controlada por desarrolladores, una consideración que puede afectar a quién y cómo se proporciona acceso administrativo a esta capa.
  • Entrada de la malla. Cuando se combina con la entrada de la nube, la capa de entrada de la malla proporciona enrutamiento flexible cerca de la aplicación. Debido a esta flexibilidad, la entrada de la malla es mejor que la de la nube para una lógica de enrutamiento compleja y la visibilidad a nivel de la aplicación. La separación entre las capas de entrada también facilita a los propietarios de la aplicación el control directo de esta capa sin afectar a otros equipos. Cuando expones aplicaciones de la malla de servicios a través de un balanceador de cargas de L4 en lugar de un balanceador de cargas de L7, debes finalizar la TLS del cliente en la capa de entrada de la malla dentro de la malla para proteger las aplicaciones.

Verificaciones de estado

Una dificultad del uso de dos capas de balanceo de cargas de L7 es la verificación de estado. Debes configurar cada balanceador de cargas para verificar el estado de la siguiente capa a fin de garantizar que pueda recibir tráfico. En la topología del siguiente diagrama, se muestra cómo la entrada de la nube verifica el estado de los proxies de entrada de la malla, y la malla, a su vez, verifica el estado de los backends de la aplicación.

La entrada de la nube verifica el estado de la entrada de la malla, y la entrada de la malla verifica el estado de los backends de la aplicación.

Esta topología tiene las siguientes consideraciones:

  • Entrada de la nube. En este instructivo, debes configurar el balanceador de cargas de Google Cloud a través de la entrada para verificar el estado de los proxies de entrada de la malla en sus puertos de verificación de estado expuestos. Si un proxy de la malla no funciona o si el clúster, la malla o la región no están disponibles, el balanceador de cargas de Google Cloud detecta esta condición y no envía tráfico al proxy de la malla.
  • Entrada de la malla. En la aplicación de la malla, debes realizar verificaciones de estado directamente en los backends, de modo que puedas ejecutar el balanceo de cargas y la administración de tráfico de forma local.

Seguridad

En la topología anterior, se incluyen varios elementos de seguridad. Uno de los elementos más importantes es la forma en que configuras la encriptación y la implementación de certificados. Ingress para balanceo de cargas de HTTP(S) externo tiene una integración profunda en certificados administrados por Google. Esta integración aprovisiona de forma automática los certificados públicos, los adjunta a un balanceador de cargas y los renueva y los rota a través de la interfaz declarativa de Ingress de GKE. Los clientes de Internet se autentican con los certificados públicos y se conectan al balanceador de cargas externo como el primer salto en la nube privada virtual (VPC).

El siguiente salto, que está entre Google Front End (GFE) y el proxy de entrada de la malla, está encriptado de forma predeterminada. La encriptación a nivel de la red entre GFE y sus backends se aplica de forma automática. Sin embargo, si tus requisitos de seguridad determinan que el propietario de la plataforma retiene la propiedad de las claves de encriptación, puedes habilitar HTTPS entre la entrada del clúster (GFE) y la entrada de la malla (la instancia del proxy de Envoy). Cuando habilitas HTTP para esta ruta, puedes usar un certificado autofirmado o público a fin de encriptar el tráfico, ya que GFE no se autentica con él. A fin de evitar el manejo inadecuado de certificados, no uses el certificado público para el balanceador de cargas público en otro lugar. En cambio, te recomendamos que uses otros certificados en la malla de servicios.

Si la malla de servicios exige TLS, todo el tráfico se encripta entre proxies de sidecar y la entrada de la malla. En este instructivo, no se habilita HTTPS entre GFE y la capa de entrada de la malla, aunque es posible que esa arquitectura sea aplicable para tu entorno. En el siguiente diagrama, se ilustra la encriptación HTTPS del cliente al balanceador de cargas de Google Cloud, del balanceador de cargas al proxy de entrada de la malla y del proxy de entrada al proxy de sidecar.

La seguridad se implementa mediante certificados administrados ubicados fuera de la malla y certificados internos dentro de la malla.

Objetivos

  • Implementar un clúster de Google Kubernetes Engine (GKE) en Google Cloud
  • Implementar Anthos Service Mesh basada en Istio en el clúster de GKE
  • Implementar la aplicación Online Boutique en el clúster de GKE que expones a los clientes en Internet
  • Configurar Ingress de GKE para finalizar el tráfico de HTTPS público y dirigir ese tráfico a las aplicaciones alojadas en la malla de servicios

Costos

En este instructivo, se usan los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud sean aptos para obtener una prueba gratuita.

Cuando finalices este instructivo, podrás borrar los recursos creados para evitar que se te siga facturando. Para obtener más información, consulta cómo hacer una limpieza.

Antes de comenzar

  1. En la página del selector de proyectos de Google Cloud Console, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyecto

  2. Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.

  3. En Cloud Console, activa Cloud Shell.

    Activar Cloud Shell

    Ejecuta todos los comandos de terminal de este instructivo desde Cloud Shell.

  4. Configura un proyecto predeterminado de Google Cloud:

    export PROJECT=$(gcloud info --format='value(config.project)')
    export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT} --format="value(projectNumber)")
    gcloud config set project ${PROJECT}
    
  5. Habilita las API para este instructivo.

    Anthos Service Mesh

    En Anthos Service Mesh, habilita las siguientes funciones:

    • API de Google Kubernetes Engine (container.googleapis.com)
    • API de Compute Engine (compute.googleapis.com)
    • API de Cloud Monitoring (monitoring.googleapis.com)
    • API de Cloud Logging (logging.googleapis.com)
    • API de Cloud Trace (cloudtrace.googleapis.com)
    • API de autoridad certificada de Anthos Service Mesh (meshca.googleapis.com)
    • API de telemetría de malla (meshtelemetry.googleapis.com)
    • API de configuración de malla (meshconfig.googleapis.com)
    • API de credenciales de la cuenta de servicio de IAM (iamcredentials.googleapis.com)
    • API de Anthos (anthos.googleapis.com)
    • API de Resource Manager (cloudresourcemanager.googleapis.com)
    gcloud services enable \
        container.googleapis.com \
        compute.googleapis.com \
        monitoring.googleapis.com \
        logging.googleapis.com \
        cloudtrace.googleapis.com \
        meshca.googleapis.com \
        meshtelemetry.googleapis.com \
        meshconfig.googleapis.com \
        iamcredentials.googleapis.com \
        anthos.googleapis.com \
        cloudresourcemanager.googleapis.com
    

    Istio

    En Istio, habilita lo siguiente:

    • API de Google Kubernetes Engine (container.googleapis.com)
    • API de Compute Engine (compute.googleapis.com)
    • API de Cloud Monitoring (monitoring.googleapis.com)
    • API de Cloud Logging (logging.googleapis.com)
    • API de Cloud Trace (cloudtrace.googleapis.com)
    • API de credenciales de la cuenta de servicio de IAM (iamcredentials.googleapis.com)
    • API de Resource Manager (cloudresourcemanager.googleapis.com)
    gcloud services enable \
        container.googleapis.com \
        compute.googleapis.com \
        monitoring.googleapis.com \
        logging.googleapis.com \
        cloudtrace.googleapis.com \
        iamcredentials.googleapis.com \
        cloudresourcemanager.googleapis.com
    
  6. Clona el repositorio de código para obtener los archivos de este instructivo y crea un directorio de trabajo:

    mkdir -p ${HOME}/edge-to-mesh
    cd ${HOME}/edge-to-mesh
    export WORKDIR=`pwd`
    

    Cuando termines el instructivo, puedes borrar el directorio de trabajo.

Crea clústeres de GKE

Las funciones que se describen en este instructivo requieren una versión 1.16 o posterior del clúster de GKE.

  1. En Cloud Shell, crea un archivo kubeconfig nuevo. Con este paso te aseguras de no causar un conflicto con el archivo kubeconfig (predeterminado) existente.

    touch edge2mesh_kubeconfig
    export KUBECONFIG=${WORKDIR}/edge2mesh_kubeconfig
    
  2. Define las variables de entorno para el clúster de GKE:

    export CLUSTER_NAME=edge-to-mesh
    export CLUSTER_LOCATION=us-west1-a
    
  3. Crea un clúster de GKE.

    Anthos Service Mesh

    gcloud beta container clusters create ${CLUSTER_NAME} \
        --machine-type=e2-standard-4 \
        --num-nodes=4 \
        --zone ${CLUSTER_LOCATION} \
        --enable-stackdriver-kubernetes \
        --enable-ip-alias \
        --workload-pool=${PROJECT}.svc.id.goog \
        --labels=mesh_id=proj-${PROJECT_NUMBER} \
        --release-channel rapid
    

    Istio

    gcloud beta container clusters create ${CLUSTER_NAME} \
        --machine-type=e2-standard-4 \
        --num-nodes=4 \
        --zone ${CLUSTER_LOCATION} \
        --enable-stackdriver-kubernetes \
        --enable-ip-alias \
        --release-channel rapid
    
  4. Asegúrate de que el clúster esté en ejecución:

    gcloud container clusters list
    

    El resultado es similar al siguiente:

    NAME          LOCATION    MASTER_VERSION  MASTER_IP      MACHINE_TYPE   NODE_VERSION    NUM_NODES  STATUS
    edge-to-mesh  us-west1-a  1.17.9-gke.600  34.83.193.134  n1-standard-4  1.17.9-gke.600  4          RUNNING
    
  5. Inicializa el proyecto si deseas prepararlo a fin de instalar Anthos Service Mesh (solo para instalaciones de Anthos Service Mesh).

    curl --request POST \
        --header "Authorization: Bearer $(gcloud auth print-access-token)" \
        --data '' \
        "https://meshconfig.googleapis.com/v1alpha1/projects/${PROJECT}:initialize"
    

    El resultado es similar al siguiente:

    {}
    

    Con este comando, se crea una cuenta de servicio que permite controlar los componentes del plano, como el proxy de sidecar, y acceder a los datos y recursos del proyecto de manera más segura. Este paso solo es necesario si instalas Anthos Service Mesh; no es necesario para Istio OSS.

  6. Conéctate al clúster.

    gcloud container clusters get-credentials edge-to-mesh --zone us-west1-a --project ${PROJECT}
    
  7. Otorga permisos de administrador del clúster al usuario actual (solo para instalaciones de Anthos Service Mesh):

    kubectl create clusterrolebinding cluster-admin-binding \
        --clusterrole=cluster-admin \
        --user="$(gcloud config get-value core/account)"
    

    Con estos permisos, puedes crear las reglas de control de acceso basado en funciones (RBAC) necesarias para Anthos Service Mesh.

Instala una malla de servicios

  1. En Cloud Shell, descarga el archivo de instalación de Istio o Anthos Service Mesh.

    Anthos Service Mesh

    export ASM_VERSION=1.6.5-asm.7
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-${ASM_VERSION}-linux-amd64.tar.gz
    tar xzf istio-${ASM_VERSION}-linux-amd64.tar.gz
    rm -rf istio-${ASM_VERSION}-linux-amd64.tar.gz
    

    Istio

    export ISTIO_VERSION=1.6.7
    curl -L https://istio.io/downloadIstio | ISTIO_VERSION=${ISTIO_VERSION} sh -
    
  2. Agrega la ruta a la utilidad de línea de comandos de istiocl, que viene incluida con Istio y Anthos Service Mesh. Para simplificar la instalación, en este instructivo se usa istioctl (un wrapper alrededor de kubectl). La ruta a la utilidad se agrega a la variable PATH.

    Anthos Service Mesh

    export PATH=${WORKDIR}/istio-${ASM_VERSION}/bin:$PATH
    istioctl version --remote=false
    

    El resultado es similar al siguiente:

    1.6.5-asm.7
    

    Istio

    export PATH=${WORKDIR}/istio-${ISTIO_VERSION}/bin:$PATH
    istioctl version --remote=false
    

    El resultado es similar al siguiente:

    1.6.7
    
  3. Prepara el archivo de configuración de Anthos Service Mesh. Para ello, descarga y configura el paquete kpt de Anthos Service Mesh (solo para las instalaciones de Anthos Service Mesh):

    sudo apt-get install google-cloud-sdk-kpt
    kpt pkg get \
    https://github.com/GoogleCloudPlatform/anthos-service-mesh-packages.git/asm@release-1.6-asm
    ${WORKDIR}/asm
    kpt cfg set ${WORKDIR}/asm gcloud.container.cluster ${CLUSTER_NAME}
    kpt cfg set ${WORKDIR}/asm gcloud.core.project ${PROJECT}
    kpt cfg set ${WORKDIR}/asm gcloud.compute.location ${CLUSTER_LOCATION}
    
  4. Instala el plano de control de Istio o de Anthos Service Mesh en el clúster edge-to-mesh mediante istioctl, su operador, y un perfil de implementación aumentado llamado demo. Como parte de la instalación, el perfil de demostración instala todos los componentes, incluidos los de observabilidad, como Grafana, Kiali o Jaeger.

    Anthos Service Mesh

    istioctl install -f ${WORKDIR}/asm/cluster/istio-operator.yaml --set values.gateways.istio-ingressgateway.type=ClusterIP
    

    El resultado es similar al siguiente:

    ! global.mtls.enabled is deprecated; use the PeerAuthentication resource instead
    ✔ Istio core installed
    ✔ Istiod installed
    ✔ Ingress gateways installed
    ✔ Installation complete
    

    Istio

    istioctl install --set profile=demo --set values.gateways.istio-ingressgateway.type=ClusterIP
    

    El resultado es similar al siguiente:

    ✔ Istio core installed
    ✔ Istiod installed
    ✔ Egress gateways installed
    ✔ Ingress gateways installed
    ✔ Addons installed
    ✔ Installation complete
    
  5. Asegúrate de que todas las implementaciones estén en funcionamiento:

    kubectl wait --for=condition=available --timeout=600s deployment --all -n istio-system
    

    Para Istio, el resultado es similar al siguiente:

    deployment.extensions/grafana condition met
    deployment.extensions/istio-egressgateway condition met
    deployment.extensions/istio-ingressgateway condition met
    deployment.extensions/istio-tracing condition met
    deployment.extensions/istiod condition met
    deployment.extensions/kiali condition met
    deployment.extensions/prometheus condition met
    

    En Anthos Service Mesh, el resultado es similar al siguiente:

    deployment.apps/istio-ingressgateway condition met
    deployment.apps/istiod condition met
    deployment.apps/promsd condition met
    

Instala la app de muestra Online Boutique

  1. En Cloud Shell, agrega una etiqueta de espacio de nombres al espacio de nombres default:

    kubectl label namespace default istio-injection=enabled
    

    Si etiquetas el espacio de nombres namespace, le indicas a Istio que inserte de manera automática proxies de sidecar de Envoy cuando se implementa una aplicación. El resultado es similar al siguiente:

    namespace/default labeled
    
  2. Descarga los archivos YAML de Kubernetes y de Istio para la app de muestra Online Boutique:

    curl -LO \
        https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/kubernetes-manifests.yaml
    curl -LO \
        https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/release/istio-manifests.yaml
    
  3. Implementa la app Online Boutique:

    kubectl apply -f kubernetes-manifests.yaml
    

    El resultado es similar al siguiente:

    deployment.apps/frontend created
    service/frontend created
    service/frontend-external created
    ...
    
  4. Asegúrate de que todas las implementaciones estén en funcionamiento:

    kubectl get pods
    

    El resultado es similar al siguiente:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-d854d8786-fjb7q                2/2     Running   0          3m
    cartservice-85b5d5b4ff-8qn7g             2/2     Running   0          2m59s
    checkoutservice-5f9bf659b8-sxhsq         2/2     Running   0          3m1s
    ...
    
  5. Implementa los manifiestos de Istio:

    kubectl apply -f istio-manifests.yaml
    

    El resultado es similar al siguiente:

    virtualservice.networking.istio.io/frontend created
    gateway.networking.istio.io/frontend-gateway created
    virtualservice.networking.istio.io/frontend-ingress created
    serviceentry.networking.istio.io/whitelist-egress-googleapis created
    serviceentry.networking.istio.io/whitelist-egress-google-metadata created
    

Implementa Ingress de GKE

En los siguientes pasos, debes implementar el balanceador de cargas de HTTP(S) externo a través del controlador de Ingress de GKE. El recurso Ingress automatiza el aprovisionamiento del balanceador de cargas, sus certificados TLS y la verificación de estado del backend. Además, debes usar Cloud Endpoints a fin de aprovisionar de forma automática un nombre de DNS público para la aplicación.

Aplica la configuración del Service de backend

  1. En Cloud Shell, observa el Service istio-ingressgateway para ver cómo se implementa antes de aplicar cualquier personalización:

    kubectl get svc -n istio-system istio-ingressgateway
    

    En el resultado, se muestran las anotaciones del Service de la instalación predeterminada. En el siguiente paso, debes actualizar las anotaciones del Service a fin de personalizarlo para este instructivo.

    NAME                   TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                                        AGE
    istio-ingressgateway   ClusterIP   10.44.15.44   <none>        15021/TCP,80/TCP,443/TCP,31400/TCP,15443/TCP   5m57s
    

    En una sección anterior de este instructivo, usaste los perfiles de instalación de Anthos Service Mesh o Istio para implementar istio-ingressgateway como un Service ClusterIP. En este perfil personalizado, no se implementa un balanceador de cargas de TCP/UDP como parte de la implementación de la malla de servicios, ya que en este instructivo se exponen apps a través de recursos de Ingress basados en HTTP. En este punto del instructivo, no se puede acceder a la aplicación desde fuera del clúster porque nada lo expone. En los pasos siguientes, implementarás los componentes necesarios para exponer la aplicación alojada en la malla a través del balanceador de cargas de HTTP(S) externo.

  2. Guarda el siguiente manifiesto en un archivo llamado ingress-service-patch.yaml:

    cat <<EOF > ingress-service-patch.yaml
    kind: Service
    metadata:
      name: istio-ingressgateway
      namespace: istio-system
      annotations:
        cloud.google.com/backend-config: '{"default": "ingress-backendconfig"}'
        cloud.google.com/neg: '{"ingress": true}'
    EOF
    

    Con este comando, se aplican parches al Service istio-ingressgateway con anotaciones personalizadas que usa Ingress de GKE.

    Este Service incluye las siguientes anotaciones que establecen parámetros para el balanceador de cargas de Ingress cuando se implementa:

    • cloud.google.com/backend-config hace referencia al nombre de un recurso personalizado llamado BackendConfig. El controlador de Ingress usa BackendConfig para configurar parámetros en el recurso BackendService de Google Cloud. Usa este recurso en el próximo paso para definir los parámetros personalizados de la verificación de estado de Google Cloud.
    • cloud.google.com/neg: '{"ingress": true}' habilita los backends de Ingress (en este caso, los proxies de entrada de la malla) para el balanceo de cargas nativo del contenedor. Para obtener un balanceo de cargas más eficiente y estable, estos backends usan grupos de extremos de red (NEG) en lugar de grupos de instancias.
  3. Aplica las anotaciones del parche al Service istio-ingressgateway:

    kubectl patch svc istio-ingressgateway -n istio-system --patch "$(cat ingress-service-patch.yaml)"
    

    El resultado es similar al siguiente:

    service/istio-ingressgateway patched
    
  4. Guarda el siguiente manifiesto BackendConfig como ingress-backendconfig.yaml:

    cat <<EOF > ingress-backendconfig.yaml
    apiVersion: cloud.google.com/v1
    kind: BackendConfig
    metadata:
      name: ingress-backendconfig
      namespace: istio-system
    spec:
      healthCheck:
        requestPath: /healthz/ready
        port: 15021
        type: HTTP
      securityPolicy:
        name: edge-fw-policy
    EOF
    

    BackendConfig es una definición de recurso personalizado (CRD) que define parámetros de backend para el balanceo de cargas de Ingress. Para obtener una lista completa de los parámetros de backend y frontend que puedes configurar a través de Ingress de GKE, consulta Características de Ingress.

    En este instructivo, se especifican verificaciones de estado personalizadas para los proxies de entrada de la malla en el manifiesto BackendConfig. Istio y Anthos Service Mesh exponen sus verificaciones de estado del proxy de sidecar en el puerto 15021 de la ruta /healthz/ready. Los parámetros de verificación de estado personalizados son obligatorios porque el puerto de entrega (80) de los proxies de entrada de la malla es diferente del puerto de verificación de estado (15021). Ingress de GKE usa los siguientes parámetros de verificación de estado en BackendConfig para configurar las verificaciones de estado del balanceador de cargas de Google Cloud. También se hace referencia a una política de seguridad que ayuda a proteger el tráfico de balanceo de cargas de diferentes tipos de ataques de red.

    • healthCheck.port define el puerto que recibe una verificación de estado según el balanceador de cargas de Google Cloud en la dirección IP de cada Pod.
    • healthCheck.requestPath define la ruta de acceso HTTP que recibe una verificación de estado en el puerto especificado.
    • type define el protocolo de la verificación de estado (en este caso, HTTP).
    • securityPolicy.name hace referencia al nombre de una política de seguridad de Cloud Armor.
  5. Implementa ingress-backendconfig.yaml en el clúster para crear el recurso BackendConfig:

    kubectl apply -f ingress-backendconfig.yaml
    

    El resultado es similar al siguiente:

    backendconfig.cloud.google.com/ingress-backendconfig created
    

    Los parámetros BackendConfig y las anotaciones del Service istio-ingressgateway no se aplican a un balanceador de cargas de Google Cloud hasta que se implementa el recurso Ingress. La implementación de Ingress vincula todos estos recursos.

Define políticas de seguridad

Google Cloud Armor proporciona defensa contra DSD y políticas de seguridad personalizables que puedes adjuntar a un balanceador de cargas a través de los recursos de Ingress. En los siguientes pasos, crearás una política de seguridad que usa reglas preconfiguradas para bloquear ataques de secuencias de comandos entre sitios (XSS). Esta regla ayuda a bloquear el tráfico que coincide con las firmas de ataques conocidas, pero permite el resto del tráfico. En tu entorno se pueden usar reglas diferentes; esto depende de tu carga de trabajo.

  1. En Cloud Shell, crea una política de seguridad llamada edge-fw-policy:

    gcloud compute security-policies create edge-fw-policy \
        --description "Block XSS attacks"
    
  2. Crea una regla de política de seguridad que use los filtros de XSS preconfigurados:

    gcloud compute security-policies rules create 1000 \
        --security-policy edge-fw-policy \
        --expression "evaluatePreconfiguredExpr('xss-stable')" \
        --action "deny-403" \
        --description "XSS attack filtering"
    

ingress-backendconfig hace referencia a edge-fw-policy en la sección anterior. Cuando se implementa el recurso Ingress, este vincula esta política de seguridad con el balanceador de cargas para ayudar a proteger cualquier backend del Service istio-ingressgateway.

Configura direcciones IP y DNS

  1. En Cloud Shell, crea una IP estática global para el balanceador de cargas de Google Cloud:

    gcloud compute addresses create ingress-ip --global
    

    El recurso Ingress usa esta IP estática, que permite que la IP continúe siendo la misma, incluso si el balanceador de cargas externo cambia.

  2. Obtén la dirección IP estática:

    export GCLB_IP=$(gcloud compute addresses describe ingress-ip --global --format=json | jq -r '.address')
    echo ${GCLB_IP}
    

    A fin de crear una asignación estable y fácil de usar para la IP de Ingress, debes tener un registro DNS público. Puedes usar el proveedor de DNS y la automatización que desees. En este instructivo, se usa Endpoints en lugar de crear una zona de DNS administrada. Endpoints proporciona un registro DNS administrado por Google gratuito para una IP pública.

  3. Guarda la siguiente especificación YAML en un archivo llamado dns-spec.yaml:

    cat <<EOF > dns-spec.yaml
    swagger: "2.0"
    info:
      description: "Cloud Endpoints DNS"
      title: "Cloud Endpoints DNS"
      version: "1.0.0"
    paths: {}
    host: "frontend.endpoints.${PROJECT}.cloud.goog"
    x-google-endpoints:
    - name: "frontend.endpoints.${PROJECT}.cloud.goog"
      target: "${GCLB_IP}"
    EOF
    

    La especificación YAML define el registro DNS público en el formato frontend.endpoints.${PROJECT}.cloud.goog, en el que ${PROJECT} es tu número de proyecto único.

  4. Implementa el archivo dns-spec.yaml en tu proyecto de Cloud:

    gcloud endpoints services deploy dns-spec.yaml
    

    El resultado es similar al siguiente:

    Operation finished successfully. The following command can describe the Operation details:
     gcloud endpoints operations describe operations/rollouts.frontend.endpoints.edge2mesh.cloud.goog:442b2b38-4aee-4c60-b9fc-28731657ee08
    
    Service Configuration [2020-04-28r0] uploaded for service [frontend.endpoints.edge2mesh.cloud.goog]
    

    Ahora que la IP y el DNS están configurados, puedes generar un certificado público para proteger el frontend de Ingress. Ingress de GKE admite certificados administrados por Google como recursos de Kubernetes, lo que te permite aprovisionarlos a través de medios declarativos.

Aprovisiona un certificado TLS

  1. En Cloud Shell, guarda el siguiente manifiesto YAML como managed-cert.yaml:

    cat <<EOF > managed-cert.yaml
    apiVersion: networking.gke.io/v1beta2
    kind: ManagedCertificate
    metadata:
      name: gke-ingress-cert
      namespace: istio-system
    spec:
      domains:
        - "frontend.endpoints.${PROJECT}.cloud.goog"
    EOF
    

    En este archivo YAML, se especifica que el nombre de DNS creado a través de Endpoints se usa para aprovisionar un certificado público. Como Google administra completamente el ciclo de vida de estos certificados públicos, estos se generan y se rotan de forma automática con regularidad, sin intervención directa del usuario.

  2. Implementa el archivo managed-cert.yaml en el clúster de GKE:

    kubectl apply -f managed-cert.yaml
    

    El resultado es similar al siguiente:

    managedcertificate.networking.gke.io/gke-ingress-cert created
    
  3. Inspecciona el recurso ManagedCertificate para verificar el progreso de la generación del certificado:

    kubectl describe managedcertificate gke-ingress-cert -n istio-system
    

    El resultado es similar al siguiente:

    Name:         gke-ingress-cert
    Namespace:    istio-system
    Labels:       <none>
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                    {"apiVersion":"networking.gke.io/v1beta2","kind":"ManagedCertificate","metadata":{"annotations":{},"name":"gke-ingress-cert","namespace":"...
    API Version:  networking.gke.io/v1beta2
    Kind:         ManagedCertificate
    Metadata:
      Creation Timestamp:  2020-08-05T20:44:49Z
      Generation:          2
      Resource Version:    1389781
      Self Link:           /apis/networking.gke.io/v1beta2/namespaces/istio-system/managedcertificates/gke-ingress-cert
      UID:                 d74ec346-ced9-47a8-988a-6e6e9ddc4019
    Spec:
      Domains:
        frontend.endpoints.edge2mesh.cloud.goog
    Status:
      Certificate Name:    mcrt-306c779e-8439-408a-9634-163664ca6ced
      Certificate Status:  Provisioning
      Domain Status:
        Domain:  frontend.endpoints.edge2mesh.cloud.goog
        Status:  Provisioning
    Events:
      Type    Reason  Age   From                            Message
      ----    ------  ----  ----                            -------
      Normal  Create  44s   managed-certificate-controller  Create SslCertificate mcrt-306c779e-8439-408a-9634-163664ca6ced
    

    Cuando el certificado está listo, el Certificate Status aparece como Active.

Implementa el recurso Ingress

  1. En Cloud Shell, guarda el siguiente manifiesto de Ingress como ingress.yaml:

    cat <<EOF > ingress.yaml
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: gke-ingress
      namespace: istio-system
      annotations:
        kubernetes.io/ingress.allow-http: "false"
        kubernetes.io/ingress.global-static-ip-name: "ingress-ip"
        networking.gke.io/managed-certificates: "gke-ingress-cert"
    spec:
      rules:
      - host: frontend.endpoints.${PROJECT}.cloud.goog
        http:
          paths:
          - backend:
              serviceName: istio-ingressgateway
              servicePort: 80
    EOF
    

    En este manifiesto, se define un recurso Ingress que vincula todos los recursos anteriores. En el manifiesto, se especifican los siguientes campos:

    • kubernetes.io/ingress.allow-http: "false" inhabilita el tráfico de HTTP en el puerto 80 del balanceador de cargas de Google Cloud. Esto evita que los clientes se conecten con tráfico no encriptado, porque el puerto 443 solo escucha HTTPS y el puerto 80 está inhabilitado.
    • kubernetes.io/ingress.global-static-ip-name: "${GCLB_IP}" vincula la dirección IP creada antes con el balanceador de cargas. Este vínculo permite que la dirección IP y el balanceador de cargas se creen por separado, de modo que la IP pueda reutilizarse de manera independiente del ciclo de vida del balanceador de cargas.
    • networking.gke.io/managed-certificates: "gke-ingress-cert" vincula este balanceador de cargas con el recurso de certificado SSL administrado por Google creado antes.
    • host: frontend.endpoints.${project}.cloud.google.com especifica el encabezado del host HTTP que escucha esta IP del balanceador de cargas. Este campo usa el nombre de DNS que usas para publicitar tu aplicación.
  2. Implementa ingress.yaml en el clúster:

    kubectl apply -f ingress.yaml
    
  3. Inspecciona el recurso Ingress para verificar el progreso de la implementación del balanceador de cargas:

    kubectl describe ingress gke-ingress -n istio-system
    

    El resultado es similar al siguiente:

    ...
    Annotations:
      ingress.kubernetes.io/https-forwarding-rule:       k8s2-fs-fq3ng2uk-istio-system-gke-ingress-qm3qqdor
      ingress.kubernetes.io/ssl-cert:                    mcrt-306c779e-8439-408a-9634-163664ca6ced
      networking.gke.io/managed-certificates:            gke-ingress-cert
      kubernetes.io/ingress.global-static-ip-name:  ingress-ip
      ingress.gcp.kubernetes.io/pre-shared-cert:    mcrt-306c779e-8439-408a-9634-163664ca6ced
      ingress.kubernetes.io/backends:               {"k8s-be-31610--07bdde06b914144a":"HEALTHY","k8s1-07bdde06-istio-system-istio-ingressgateway-443-228c1881":"HEALTHY"}
      ingress.kubernetes.io/forwarding-rule:        k8s2-fr-fq3ng2uk-istio-system-gke-ingress-qm3qqdor
      ingress.kubernetes.io/https-target-proxy:     k8s2-ts-fq3ng2uk-istio-system-gke-ingress-qm3qqdor
      ingress.kubernetes.io/target-proxy:           k8s2-tp-fq3ng2uk-istio-system-gke-ingress-qm3qqdor
      ingress.kubernetes.io/url-map:                k8s2-um-fq3ng2uk-istio-system-gke-ingress-qm3qqdor
    ...
    

    El recurso Ingress está listo cuando las anotaciones ingress.kubernetes.io/backends indican que los backends tienen el estado HEALTHY. En las anotaciones, también se muestran los nombres de distintos recursos de Google Cloud que se aprovisionan, incluidos los servicios de backend, los certificados SSL y los proxies de destino HTTPS.

    Una vez que se aprovisione tu certificado y que Ingress esté listo, se podrá acceder a tu aplicación.

  4. Accede al siguiente vínculo:

    echo "https://frontend.endpoints.${PROJECT}.cloud.goog"
    

    Se mostrará el frontend de Online Boutique.

    Productos que se muestran en la página principal de Online Boutique.

  5. Para ver los detalles del certificado, haz clic en Consulta la información del sitio en la barra de direcciones del navegador y, luego, haz clic en Certificado (Válido).

    En el visualizador de certificados, se muestran los detalles del certificado administrado, incluida la fecha de vencimiento y quién emitió el certificado.

Ahora tienes un balanceador de cargas de HTTPS global que funciona como frontend en tu aplicación alojada en la malla de servicios.

Realiza una limpieza

Una vez que hayas terminado el instructivo, puedes limpiar los recursos que creaste en Google Cloud para que no se te cobre por ellos en el futuro. Puedes borrar el proyecto por completo o borrar los recursos del clúster y, luego, borrar el clúster.

Borra el proyecto

  1. En Cloud Console, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

Borra los recursos individuales

Si deseas conservar el proyecto de Cloud que usaste en este instructivo, borra los recursos individuales:

  1. Borra el recurso Ingress:

    kubectl delete -f gke-ingress.yaml
    
  2. Borra el certificado administrado:

    kubectl delete -f managed-cert.yaml
    
  3. Borra la entrada de DNS de Endpoints:

    gcloud endpoints services delete "frontend.endpoints.${PROJECT}.cloud.goog"
    

    El resultado es similar al siguiente:

    Are you sure? This will set the service configuration to be deleted, along
    with all of the associated consumer information. Note: This does not
    immediately delete the service configuration or data and can be undone using
    the undelete command for 30 days. Only after 30 days will the service be
    purged from the system.
    
  4. Cuando se te solicite continuar, ingresa Y.

    El resultado es similar al siguiente:

    Waiting for async operation operations/services.frontend.endpoints.edge2mesh.cloud.goog-5 to complete...
    Operation finished successfully. The following command can describe the Operation details:
     gcloud endpoints operations describe operations/services.frontend.endpoints.edge2mesh.cloud.goog-5
    
  5. Borra la dirección IP estática:

    gcloud compute addresses delete ingress-ip --global
    

    El resultado es similar al siguiente:

    The following global addresses will be deleted:
    
     - [ingress-ip]
    
  6. Cuando se te solicite continuar, ingresa Y.

    El resultado es similar al siguiente:

    Deleted
    [https://www.googleapis.com/compute/v1/projects/edge2mesh/global/addresses/ingress-ip].
    
  7. Borra el clúster de GKE:

    gcloud container clusters delete $CLUSTER_NAME --zone $CLUSTER_LOCATION
    

¿Qué sigue?