Configurar un balanceador de carga de aplicación clásico para Cloud Service Mesh
Información general
Este documento está dirigido a los usuarios de Cloud Service Mesh que tienen el plano de control gestionado de Istiod y quieren configurar un balanceador de carga de aplicaciones clásico como puerta de enlace de entrada. El balanceador de carga de aplicación clásico también se conoce como balanceador de carga de aplicación externo clásico.
No utilices este documento si eres un nuevo usuario de Cloud Service Mesh. Los nuevos usuarios se configuran automáticamente con el plano de control gestionado de Cloud Service Mesh. No puedes usar la configuración descrita en este documento con el plano de control gestionado de Cloud Service Mesh
Cloud Load Balancing ofrece muchas funciones de edge gestionadas en la nube, como el balanceo de carga anycast global, los certificados gestionados por Google, Gestión de Identidades y Accesos, Cloud Next Generation Firewall y Cloud Intrusion Detection System. Cloud Service Mesh puede integrar estas funciones de forma fluida en el siguiente modelo de entrada de malla. La pasarela de Cloud de la malla de servicios proporciona una forma unificada de configurar la pasarela de entrada de Cloud Service Mesh con Cloud Load Balancing simultáneamente a través de la API Gateway de Kubernetes.
En comparación con nuestra guía de usuario anterior, Del perímetro a la malla: exponer aplicaciones en una malla de servicios a través de Ingress de GKE, con la pasarela de nube de malla de servicios, este modelo ahora se puede implementar a través de un recurso de pasarela de Kubernetes, lo que simplifica el proceso de implementar el balanceo de carga alojado en la nube y en el clúster.
Limitaciones de la vista previa
En la versión preliminar de esta función, se aplican las siguientes limitaciones:
- No se admiten las pasarelas multiclúster.
- Los clústeres Autopilot no se admiten.
- Solo se admite el balanceador de carga de aplicaciones clásico. No se admiten el balanceador de carga de aplicación externo global (a veces llamado "balanceador de carga avanzado") ni el balanceador de carga de aplicación interno.
- El tráfico entre el balanceador de carga de aplicación clásico y la puerta de enlace de entrada de Cloud Service Mesh se cifra mediante TLS. Sin embargo, el balanceador de carga de aplicaciones clásico no verificará el certificado proporcionado por la puerta de enlace de entrada de Cloud Service Mesh. Esta limitación se aplica a todos los usuarios del balanceador de carga HTTP(S) Google Cloud .
- Si se eliminan los
GatewayClasses
de Cloud Service Mesh de un clúster, no se volverán a instalar automáticamente. Sin embargo, esto no afectará a la usabilidad de la función. - La lógica de coincidencia de rutas no sigue las especificaciones de la API Gateway, sino que coincide en el orden de
HTTPRoute
. Esto cambiará en futuras versiones para seguir las especificaciones de la API Gateway.
Requisitos
- Cloud Service Mesh gestionado instalado en un clúster de Google Kubernetes Engine (GKE) que ejecute la versión 1.24 o posterior. No se admiten otros clústeres de GKE Enterprise.
- Solo para la versión v1beta1 de la API de Kubernetes Gateway.
Requisitos previos
Habilita las siguientes APIs en tu proyecto:
- compute.googleapis.com
- container.googleapis.com
- certificatemanager.googleapis.com
- serviceusage.googleapis.com
gcloud services enable \ compute.googleapis.com \ container.googleapis.com \ certificatemanager.googleapis.com \ serviceusage.googleapis.com
Desplegar una pasarela de nube de malla de servicios para una malla de un solo clúster
En esta sección se muestra cómo desplegar un recurso de Kubernetes Gateway, que despliega un balanceador de carga de aplicaciones clásico y una pasarela de entrada de Cloud Service Mesh.
Habilitar la API Gateway con Cloud Service Mesh gestionado
Habilita la API Gateway en tu clúster. El clúster de GKE debe tener la versión 1.24 o una posterior.
Instala Cloud Service Mesh gestionado con
rapid
oregular
como canal de lanzamiento.
Desplegar el recurso de pasarela
Al desplegar la pasarela de nube de malla de servicios, los recursos de Gateway de Kubernetes se usan para desplegar tanto Cloud Load Balancing como la pasarela de entrada de Cloud Service Mesh en un solo paso. Ten en cuenta que los recursos de Kubernetes Gateway son diferentes de los recursos de Istio Gateway.
Para obtener más información sobre las diferencias, consulta Pasarelas de Kubernetes y pasarelas de Istio. Cada Gateway de Kubernetes tiene un GatewayClass que indica su tipo y sus capacidades inherentes. El Gateway de nube de Service Mesh tiene un GatewayClass que puede desplegar tanto Cloud Load Balancing como el Gateway de entrada de Cloud Service Mesh.
Guarda el siguiente manifiesto de GatewayClass en un archivo llamado
l7-gateway-class.yaml
:apiVersion: gateway.networking.k8s.io/v1beta1 kind: GatewayClass metadata: name: asm-l7-gxlb spec: controllerName: mesh.cloud.google.com/gateway
Despliega GatewayClass en tu clúster:
kubectl apply -f l7-gateway-class.yaml
Verifica que GatewayClass esté presente después de la instalación:
kubectl get gatewayclasses.gateway.networking.k8s.io
La salida es similar a la siguiente:
NAME CONTROLLER asm-l7-gxlb mesh.cloud.google.com/gateway gke-l7-rilb networking.gke.io/gateway gke-l7-gxlb networking.gke.io/gateway
Puede que los recursos tarden unos minutos en desplegarse. Si no ves el resultado esperado, comprueba que has cumplido correctamente los requisitos previos.
También verá el siguiente GatewayClass:
gke-l7-gxlb networking.gke.io/gateway
Se usa para desplegar el balanceador de carga de aplicación clásico de Google Cloud subyacente.
Crea un espacio de nombres específico para tu pasarela de nube de malla de servicios:
kubectl create namespace istio-ingress
Guarda el siguiente manifiesto de Gateway en un archivo llamado
gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All
Despliega la pasarela en tu clúster en el espacio de nombres istio-ingress:
kubectl apply -f gateway.yaml
Verifica que se hayan creado los objetos de la API de Kubernetes Gateway:
kubectl get gateways.gateway.networking.k8s.io -n istio-ingress
La salida es similar a la siguiente:
NAME CLASS ADDRESS READY AGE asm-gw-gke-servicemesh-cloud-gw gke-l7-gxlb 34.111.114.64 True 9m40s asm-gw-istio-servicemesh-cloud-gw istio 9m44s servicemesh-cloud-gw asm-l7-gxlb 9m44s
Cuando se implemente este objeto de la API Gateway de Kubernetes, ocurrirá lo siguiente:
- Se ha implementado y configurado un balanceador de carga HTTP(S) externo. Puede tardar unos minutos en aparecer, pero, cuando lo haga, la pasarela indicará la dirección IP y se anotará con los nombres de los recursos del balanceador de carga de Compute Engine que se hayan creado.
- Se crea una implementación de la pasarela de entrada de Cloud Service Mesh en el espacio de nombres istio-ingress. De esta forma, se crean las instancias de proxy Envoy que recibirán el tráfico del balanceador de carga.
- El balanceador de carga cifrará y enrutará todo el tráfico a la pasarela de entrada de Cloud Service Mesh.
Ahora tienes toda la infraestructura necesaria para aceptar tráfico de Internet en tu malla. Ten en cuenta que esta es la implementación de Gateway más sencilla posible. En las siguientes secciones, añadiremos políticas y funciones adicionales para que esté listo para producción.
Implementación de aplicaciones y rutas
Para demostrar plenamente las funciones, desplegarás una aplicación en Cloud Service Mesh y recibirás tráfico de Internet a través de tu Gateway, por ejemplo.
Etiqueta el espacio de nombres
default
para habilitar la inyección de sidecar.kubectl label namespace default istio-injection=enabled istio.io/rev- --overwrite
Guarda el siguiente manifiesto de Gateway en un archivo llamado
whereami.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: whereami-v1 spec: replicas: 2 selector: matchLabels: app: whereami-v1 template: metadata: labels: app: whereami-v1 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080 env: - name: METADATA value: "whereami-v1" --- apiVersion: v1 kind: Service metadata: name: whereami-v1 spec: selector: app: whereami-v1 ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: whereami-v2 spec: replicas: 2 selector: matchLabels: app: whereami-v2 template: metadata: labels: app: whereami-v2 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080 env: - name: METADATA value: "whereami-v2" --- apiVersion: v1 kind: Service metadata: name: whereami-v2 spec: selector: app: whereami-v2 ports: - port: 8080 targetPort: 8080
Este manifiesto crea
Service/whereami-v1
,Service/whereami-v2
,Deployment/whereami-v1
yDeployment/whereami-v2
para whereami, una aplicación sencilla que genera JSON para indicar su identidad y ubicación. Implementarás dos versiones diferentes.Crea los servicios y las implementaciones:
kubectl apply -f whereami.yaml
Una vez que esté en funcionamiento, tendrás cuatro pods de whereami ejecutándose en tu clúster.
Comprueba que los cuatro pods se estén ejecutando:
kubectl get pods
La salida es similar a la siguiente:
whereami-v1-7c76d89d55-qg6vs 2/2 Running 0 28s whereami-v1-7c76d89d55-vx9nm 2/2 Running 0 28s whereami-v2-67f6b9c987-p9kqm 2/2 Running 0 27s whereami-v2-67f6b9c987-qhj76 2/2 Running 0 27s
Guarda el siguiente manifiesto de HTTPRoute en un archivo llamado
http-route.yaml
:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: where-route spec: parentRefs: - kind: Gateway name: servicemesh-cloud-gw namespace: istio-ingress hostnames: - "where.example.com" rules: - matches: - headers: - name: version value: v2 backendRefs: - name: whereami-v2 port: 8080 - backendRefs: - name: whereami-v1 port: 8080
Despliega
http-route.yaml
en tu clúster:kubectl apply -f http-route.yaml
Este HTTPRoute hace referencia a
servicemesh-cloud-gw
, lo que significa que configurará la pasarela de nube de la malla de servicios para que configure la pasarela de entrada de Cloud Service Mesh subyacente con estas reglas de enrutamiento. HTTPRoute realiza la misma función que VirtualService de Istio, pero usa la API Gateway de Kubernetes. Como la API Gateway es una especificación de software libre con muchas implementaciones subyacentes, es la API más adecuada para definir el enrutamiento en una combinación de diferentes balanceadores de carga (como los proxies y los balanceadores de carga de Cloud Service Mesh).Recupera la dirección IP de la pasarela para poder enviar tráfico a tu aplicación:
VIP=$(kubectl get gateways.gateway.networking.k8s.io asm-gw-gke-servicemesh-cloud-gw -o=jsonpath="{.status.addresses[0].value}" -n istio-ingress)
El resultado es una dirección IP.
echo $VIP 34.111.61.135
Envía tráfico a la dirección IP de la pasarela para validar que esta configuración funciona correctamente. Envía una solicitud con el encabezado
version: v2
y otra sin él para determinar si el enrutamiento se realiza correctamente en las dos versiones de la aplicación.curl ${VIP} -H "host: where.example.com" { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "whereami-v1", "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal", "pod_name": "whereami-v1-67d9c5d48b-zhr4l", "pod_name_emoji": "⚒", "project_id": "church-243723", "timestamp": "2021-02-08T18:55:01", "zone": "us-central1-a" } curl ${VIP} -H "host: where.example.com" -H "version: v2" { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "whereami-v2", "node_name": "gke-gke1-default-pool-9b3b5b18-hw5z.c.church-243723.internal", "pod_name": "whereami-v2-67d9c5d48b-zhr4l", "pod_name_emoji": "⚒", "project_id": "church-243723", "timestamp": "2021-02-08T18:55:01", "zone": "us-central1-a" }
Despliegue de la pasarela de producción
En la sección anterior se ha mostrado un ejemplo muy sencillo de una pasarela de nube de malla de servicios. Los siguientes pasos se basan en el ejemplo sencillo para mostrar una configuración lista para producción que demuestre las ventajas de delegar parte de la funcionalidad de enrutamiento de entrada en el balanceador de carga.
En el siguiente ejemplo, tomarás el servicemesh-cloud-gw
de la sección anterior y añadirás las siguientes funciones para crear una pasarela más segura y fácil de gestionar:
- Implementa la pasarela con una dirección IP estática que se conservará aunque cambie la infraestructura subyacente.
- Convierte la pasarela para que reciba tráfico HTTPS con un certificado autofirmado.
Crea una dirección IP externa estática. Una IP estática es útil porque la infraestructura subyacente puede cambiar en el futuro, pero la dirección IP se puede conservar.
gcloud compute addresses create whereami-ip \ --global \ --project PROJECT_ID
Crea un certificado autofirmado para el dominio
where-example-com
:openssl genrsa -out key.pem 2048 cat <<EOF >ca.conf [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @sans_list [dn_requirements] 0.organizationName = example commonName = where.example.com [sans_list] DNS.1 = where.example.com EOF
openssl req -new -key key.pem \ -out csr.pem \ -config ca.conf
openssl x509 -req \ -signkey key.pem \ -in csr.pem \ -out cert.pem \ -extfile ca.conf \ -extensions extension_requirements \ -days 365
gcloud compute ssl-certificates create where-example-com \ --certificate=cert.pem \ --private-key=key.pem \ --global \ --project PROJECT_ID
Hay muchas formas de generar certificados TLS. Se pueden generar manualmente en la línea de comandos, con certificados gestionados por Google o internamente mediante el sistema de infraestructura de clave pública (PKI) de tu empresa. En este ejemplo, generas manualmente un certificado autofirmado. Aunque los certificados autofirmados no se suelen usar en servicios públicos, permiten demostrar estos conceptos más fácilmente.
Para obtener más información sobre cómo crear un certificado autofirmado a través de un secreto de Kubernetes, consulta Proteger una pasarela.
Actualiza
gateway.yaml
con el siguiente archivo de manifiesto:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 allowedRoutes: namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: where-example-com addresses: - type: NamedAddress value: whereami-ip
Vuelve a desplegar la pasarela en tu clúster:
kubectl apply -f gateway.yaml
Obtén la dirección IP de la IP estática:
VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
Usa
curl
para acceder al dominio de la pasarela. Como el DNS no está configurado para este dominio, usa la opción --resolve para indicar a curl que resuelva el nombre de dominio en la dirección IP de la pasarela: mientras esperas.curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
Una vez completado, el resultado es similar al siguiente:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=where.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: where.example.com (matched) * issuer: O=example; CN=where.example.com * SSL certificate verify ok. ... { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "where-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "where-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
La salida detallada incluye un handshake de TLS correcto seguido de una respuesta de la aplicación, como la siguiente. De esta forma, se demuestra que TLS se está terminando correctamente en la puerta de enlace y que la aplicación responde al cliente de forma segura.
Has desplegado correctamente la siguiente arquitectura:
servicemesh-cloud-gw
y su asm-l7-gxlb
GatewayClass han abstraído algunos componentes internos de la infraestructura para simplificar la experiencia de usuario.
Cloud Load Balancing termina el tráfico TLS mediante un certificado interno y también comprueba el estado de la capa de proxy de la puerta de enlace de entrada de Cloud Service Mesh. El
whereami-route
desplegado en
Despliegue de aplicaciones y enrutamiento configura los
proxies de la puerta de enlace de entrada de Cloud Service Mesh para enrutar el tráfico al servicio correcto alojado en la malla.
En el siguiente ejemplo, tomarás el servicemesh-cloud-gw
de la sección anterior y añadirás las siguientes funciones para crear una pasarela más segura y fácil de gestionar:
- Implementa la pasarela con una dirección IP estática que se conservará aunque cambie la infraestructura subyacente.
- Convierte la pasarela para que reciba tráfico HTTPS con un certificado autofirmado.
Crea una dirección IP externa estática. Una IP estática es útil porque la infraestructura subyacente puede cambiar en el futuro, pero la dirección IP se puede conservar.
gcloud compute addresses create whereami-ip \ --global \ --project PROJECT_ID
Crea un certificado autofirmado para el dominio
where-example-com
:openssl genrsa -out key.pem 2048 cat <<EOF >ca.conf [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @sans_list [dn_requirements] 0.organizationName = example commonName = where.example.com [sans_list] DNS.1 = where.example.com EOF
openssl req -new -key key.pem \ -out csr.pem \ -config ca.conf
openssl x509 -req \ -signkey key.pem \ -in csr.pem \ -out cert.pem \ -extfile ca.conf \ -extensions extension_requirements \ -days 365
gcloud compute ssl-certificates create where-example-com \ --certificate=cert.pem \ --private-key=key.pem \ --global \ --project PROJECT_ID
Hay muchas formas de generar certificados TLS. Se pueden generar manualmente en la línea de comandos, con certificados gestionados por Google o internamente mediante el sistema de infraestructura de clave pública (PKI) de tu empresa. En este ejemplo, generas manualmente un certificado autofirmado. Aunque los certificados autofirmados no se suelen usar en servicios públicos, permiten demostrar estos conceptos más fácilmente.
Para obtener más información sobre cómo crear un certificado autofirmado a través de un secreto de Kubernetes, consulta Proteger una pasarela.
Actualiza
gateway.yaml
con el siguiente archivo de manifiesto:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: servicemesh-cloud-gw namespace: istio-ingress spec: gatewayClassName: asm-l7-gxlb listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https protocol: HTTPS port: 443 allowedRoutes: namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: where-example-com addresses: - type: NamedAddress value: whereami-ip
Vuelve a desplegar la pasarela en tu clúster:
kubectl apply -f gateway.yaml
Obtén la dirección IP de la IP estática:
VIP=$(gcloud compute addresses describe whereami-ip --global --format="value(address)")
Usa
curl
para acceder al dominio de la pasarela. Como el DNS no está configurado para este dominio, usa la opción --resolve para indicar a curl que resuelva el nombre de dominio en la dirección IP de la pasarela: mientras esperas.curl https://where.example.com --resolve where.example.com:443:${VIP} --cacert cert.pem -v
Una vez completado, el resultado es similar al siguiente:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=where.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: where.example.com (matched) * issuer: O=example; CN=where.example.com * SSL certificate verify ok. ... { "cluster_name": "gke1", "host_header": "where.example.com", "metadata": "where-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "where-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
La salida detallada incluye un handshake de TLS correcto seguido de una respuesta de la aplicación, como la siguiente. De esta forma, se demuestra que TLS se está terminando correctamente en la puerta de enlace y que la aplicación responde al cliente de forma segura.
Has desplegado correctamente la siguiente arquitectura:
servicemesh-cloud-gw
y su asm-l7-gxlb
GatewayClass han abstraído algunos componentes internos de la infraestructura para simplificar la experiencia de usuario.
Cloud Load Balancing termina el tráfico TLS mediante un certificado interno y también comprueba el estado de la capa de proxy de la puerta de enlace de entrada de Cloud Service Mesh. El
whereami-route
desplegado en
Despliegue de aplicaciones y enrutamiento configura los
proxies de la puerta de enlace de entrada de Cloud Service Mesh para enrutar el tráfico al servicio correcto alojado en la malla.
Siguientes pasos
- Consulta más información sobre la implementación de la API Gateway de Kubernetes en Google Kubernetes Engine (GKE).
- Consulta cómo habilitar funciones opcionales de Cloud Service Mesh gestionado.