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, pero también funciona para 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.
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 balanceadores de cargas HTTP(S) externos | Balanceador de cargas 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 balanceadores de cargas HTTP(S) internos | Balanceador de cargas 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 red |
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. 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 balanceador 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:
- Anuncio de VIP de Anycast global y terminación de HTTP y TLS distribuida a nivel mundial
- Defensa contra DSD y filtrado de tráfico en el perímetro con Google Cloud Armor
- Funcionalidad de puerta de enlace de API con IAP
- Creación y rotación automática de certificados públicos con certificados administrados por Google
- Balanceo de cargas de varios clústeres y multirregional en el perímetro con Ingress de varios clústeres
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.
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.
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 balanceadores de cargas de HTTP(S) externos 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 HTTP/2 con encriptación TLS entre la entrada del clúster (GFE) y la entrada de la malla (la instancia del proxy de Envoy). Cuando habilitas HTTP/2 con encriptación TLS 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. Esta capa adicional de encriptación se demuestra en esta guía. 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 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.
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
- 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
- Implementar la aplicación Online Boutique en el clúster de GKE que expones a los clientes en Internet
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
- Google Kubernetes Engine
- Compute Engine
- Cloud Load Balancing
- Anthos Service Mesh
- Google Cloud Armor
- Cloud Endpoints
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.
Antes de comenzar
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
-
In the Google Cloud console, activate Cloud Shell.
Ejecuta todos los comandos de terminal de este instructivo desde Cloud Shell.
Actualiza a la versión más reciente de Google Cloud CLI:
gcloud components update
Configura un proyecto predeterminado de Google Cloud:
export PROJECT=PROJECT export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT} --format="value(projectNumber)") gcloud config set project ${PROJECT}
Reemplaza
PROJECT
por el ID del proyecto que deseas usar para este instructivo.Cree 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.
En Cloud Shell, crea un archivo
kubeconfig
nuevo. Con este paso te aseguras de no causar un conflicto con el archivokubeconfig
(predeterminado) existente.touch edge2mesh_kubeconfig export KUBECONFIG=${WORKDIR}/edge2mesh_kubeconfig
Define las variables de entorno para el clúster de GKE:
export CLUSTER_NAME=edge-to-mesh export CLUSTER_LOCATION=us-west1-a
Habilita la API de Google Kubernetes Engine.
gcloud
gcloud services enable container.googleapis.com
Config Connector
En este instructivo, se incluyen recursos de Config Connector. Puedes usar estos recursos para completar las mismas tareas que completas en la pestaña
gcloud
. Para usar estos recursos, instala Config Connector y aplica los recursos de la manera que mejor se adapte a tu entorno.Usa el siguiente manifiesto
Services
:apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1 kind: Service metadata: annotations: cnrm.cloud.google.com/deletion-policy: "abandon" cnrm.cloud.google.com/disable-dependent-services: "false" name: container.googleapis.com spec: resourceID: container.googleapis.com projectRef: external: PROJECT
Crear un clúster de GKE
gcloud
gcloud container clusters create ${CLUSTER_NAME} \ --machine-type=e2-standard-4 \ --num-nodes=4 \ --zone ${CLUSTER_LOCATION} \ --enable-ip-alias \ --workload-pool=${PROJECT}.svc.id.goog \ --release-channel rapid \ --addons HttpLoadBalancing \ --labels mesh_id=proj-${PROJECT_NUMBER}
Config Connector
Usa los siguientes manifiestos
ContainerCluster
yContainerNodePool
:apiVersion: container.cnrm.cloud.google.com/v1beta1 kind: ContainerNodePool metadata: annotations: cnrm.cloud.google.com/project-id: PROJECT name: edge-to-mesh spec: clusterRef: name: edge-to-mesh location: us-west1-a nodeConfig: machineType: e2-standard-4 nodeCount: 4 --- apiVersion: container.cnrm.cloud.google.com/v1beta1 kind: ContainerCluster metadata: annotations: cnrm.cloud.google.com/project-id: PROJECT cnrm.cloud.google.com/remove-default-node-pool: "true" labels: mesh_id: proj-PROJECT_NUMBER name: edge-to-mesh spec: addonsConfig: httpLoadBalancing: disabled: false location: us-west1-a initialNodeCount: 1 releaseChannel: channel: RAPID workloadIdentityConfig: workloadPool: PROJECT.svc.id.goog
Reemplaza
PROJECT_NUMBER
por el valor de la variable de entornoPROJECT_NUMBER
que recuperaste antes.Para usar una entrada de la nube, debes tener habilitado el complemento de balanceo de cargas de HTTP. Los clústeres de GKE tienen habilitado el balanceo de cargas de HTTP de forma predeterminada; no debes inhabilitarlo.
Para usar Anthos Service Mesh administrado, debes aplicar la etiqueta
mesh_id
en el clúster.Asegúrate de que el clúster esté en ejecución:
gcloud container clusters list
El resultado es similar a este:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS edge-to-mesh us-west1-a v1.22.6-gke.300 35.233.195.59 e2-standard-4 v1.22.6-gke.300 4 RUNNING
Conéctese al clúster:
gcloud container clusters get-credentials ${CLUSTER_NAME} \ --zone ${CLUSTER_LOCATION} \ --project ${PROJECT}
Instala una malla de servicios
En esta sección, debes configurar Anthos Service Mesh administrado con la API de Fleet.
Habilite las API necesarias:
gcloud
gcloud services enable mesh.googleapis.com
Config Connector
Usa el siguiente manifiesto
Services
:apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1 kind: Service metadata: annotations: cnrm.cloud.google.com/deletion-policy: "abandon" cnrm.cloud.google.com/disable-dependent-services: "false" name: mesh.googleapis.com spec: resourceID: mesh.googleapis.com projectRef: external: PROJECT
Habilita Anthos Service Mesh en la flota:
gcloud
gcloud container fleet mesh enable
Config Connector
Usa el siguiente manifiesto
GKEHubFeature
:apiVersion: gkehub.cnrm.cloud.google.com/v1beta1 kind: GKEHubFeature metadata: name: servicemesh spec: projectRef: external: PROJECT location: global resourceID: servicemesh
Registra el clúster en la flota:
gcloud
gcloud container fleet memberships register ${CLUSTER_NAME} \ --gke-cluster ${CLUSTER_LOCATION}/${CLUSTER_NAME} \ --enable-workload-identity
Config Connector
Usa el siguiente manifiesto
GKEHubMembership
:apiVersion: gkehub.cnrm.cloud.google.com/v1beta1 kind: GKEHubMembership metadata: annotations: cnrm.cloud.google.com/project-id: PROJECT name: edge-to-mesh spec: location: global authority: issuer: https://container.googleapis.com/v1/projects/PROJECT/locations/us-west1-a/clusters/edge-to-mesh endpoint: gkeCluster: resourceRef: name: edge-to-mesh
Habilita la administración automática del plano de control y el plano de datos administrados:
gcloud
gcloud container fleet mesh update \ --management automatic \ --memberships ${CLUSTER_NAME}
Config Connector
Usa el siguiente manifiesto
GKEHubFeatureMembership
:apiVersion: gkehub.cnrm.cloud.google.com/v1beta1 kind: GKEHubFeatureMembership metadata: name: servicemesh-membership spec: projectRef: external: PROJECT_ID location: global membershipRef: name: edge-to-mesh featureRef: name: servicemesh mesh: management: MANAGEMENT_AUTOMATIC
Después de unos minutos, verifica que el estado del plano de control sea
ACTIVE
:gcloud container fleet mesh describe
El resultado es similar a este:
... membershipSpecs: projects/841956571429/locations/global/memberships/edge-to-mesh: mesh: management: MANAGEMENT_AUTOMATIC membershipStates: projects/841956571429/locations/global/memberships/edge-to-mesh: servicemesh: controlPlaneManagement: details: - code: REVISION_READY details: 'Ready: asm-managed-rapid' state: ACTIVE dataPlaneManagement: details: - code: OK details: Service is running. state: ACTIVE state: code: OK description: 'Revision(s) ready for use: asm-managed-rapid.' updateTime: '2022-09-29T05:30:28.320896186Z' name: projects/your-project/locations/global/features/servicemesh resourceState: state: ACTIVE ...
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.
Instala una puerta de enlace de entrada
Como práctica recomendada de seguridad, te recomendamos que implementes la puerta de enlace de entrada en un espacio de nombres diferente en el plano de control.
En Cloud Shell, crea un espacio de nombres
asm-ingress
dedicado:kubectl create namespace asm-ingress
Agrega una etiqueta de espacio de nombres al espacio de nombres
asm-ingress
:kubectl label namespace asm-ingress istio-injection=enabled
El resultado es similar a este:
namespace/asm-ingress labeled
Si etiquetas el espacio de nombres
asm-ingress
conistio-injection=enabled
, se indica a Anthos Service Mesh que inserte de manera automática proxies de sidecar de Envoy cuando se implementa una aplicación.Ejecuta el siguiente comando para crear el manifiesto
Deployment
comoingress-deployment.yaml
:cat <<EOF > ingress-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: asm-ingressgateway namespace: asm-ingress spec: selector: matchLabels: asm: ingressgateway template: metadata: annotations: # This is required to tell Anthos Service Mesh to inject the gateway with the # required configuration. inject.istio.io/templates: gateway labels: asm: ingressgateway spec: securityContext: fsGroup: 1337 runAsGroup: 1337 runAsNonRoot: true runAsUser: 1337 containers: - name: istio-proxy securityContext: allowPrivilegeEscalation: false capabilities: drop: - all privileged: false readOnlyRootFilesystem: true image: auto # The image will automatically update each time the pod starts. resources: limits: cpu: 2000m memory: 1024Mi requests: cpu: 100m memory: 128Mi serviceAccountName: asm-ingressgateway --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: asm-ingressgateway namespace: asm-ingress spec: maxReplicas: 5 minReplicas: 3 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: asm-ingressgateway --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: asm-ingressgateway namespace: asm-ingress rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: asm-ingressgateway namespace: asm-ingress roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: asm-ingressgateway subjects: - kind: ServiceAccount name: asm-ingressgateway --- apiVersion: v1 kind: ServiceAccount metadata: name: asm-ingressgateway namespace: asm-ingress EOF
Este
Deployment
tiene su propioServiceAccount
conRole
yRoleBinding
asociados, lo que permite que la puerta de enlace acceda a los certificados.Implementa
ingress-deployment.yaml
en el clúster para crear el recursoDeployment
:kubectl apply -f ingress-deployment.yaml
El resultado es similar a este:
deployment.apps/asm-ingressgateway configured role.rbac.authorization.k8s.io/asm-ingressgateway configured rolebinding.rbac.authorization.k8s.io/asm-ingressgateway configured serviceaccount/asm-ingressgateway created
Asegúrate de que todas las implementaciones estén en funcionamiento:
kubectl wait --for=condition=available --timeout=600s deployment --all -n asm-ingress
El resultado es similar a este:
deployment.apps/asm-ingressgateway condition met
Ejecuta el siguiente comando para crear el manifiesto
Service
comoingress-service.yaml
:cat <<EOF > ingress-service.yaml apiVersion: v1 kind: Service metadata: name: asm-ingressgateway namespace: asm-ingress annotations: cloud.google.com/neg: '{"ingress": true}' cloud.google.com/backend-config: '{"default": "ingress-backendconfig"}' cloud.google.com/app-protocols: '{"https":"HTTP2"}' # HTTP/2 with TLS encryption labels: asm: ingressgateway spec: ports: # status-port exposes a /healthz/ready endpoint that can be used with GKE Ingress health checks - name: status-port port: 15021 protocol: TCP targetPort: 15021 # Any ports exposed in Gateway resources should be exposed here. - name: http2 port: 80 targetPort: 8080 - name: https port: 443 targetPort: 8443 selector: asm: ingressgateway type: ClusterIP EOF
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 llamadoBackendConfig
. El controlador de Ingress usaBackendConfig
para configurar parámetros en el recursoBackendService
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.cloud.google.com/app-protocols: '{"https":"HTTP2"}'
indica a GFE que se conecte a la puerta de enlace de entrada de la malla de servicios mediante HTTP2 con TLS, como se describe en Ingress para balanceo de cargas de HTTP(S) externo y Descripción general del balanceo de cargas de HTTP(S) externo para obtener una capa adicional de encriptación.
Implementa
ingress-service.yaml
en el clúster para crear el recursoService
:kubectl apply -f ingress-service.yaml
El resultado es similar a este:
service/asm-ingressgateway created
Aplica la configuración del Service de backend
En Cloud Shell, ejecuta el siguiente comando para crear el manifiesto
BackendConfig
comoingress-backendconfig.yaml
:cat <<EOF > ingress-backendconfig.yaml apiVersion: cloud.google.com/v1 kind: BackendConfig metadata: name: ingress-backendconfig namespace: asm-ingress 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 puerto15021
de la ruta/healthz/ready
. Los parámetros de verificación de estado personalizados son obligatorios porque el puerto de entrega (443
) 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 enBackendConfig
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.
Implementa
ingress-backendconfig.yaml
en el clúster para crear el recursoBackendConfig
:kubectl apply -f ingress-backendconfig.yaml
El resultado es similar a este:
backendconfig.cloud.google.com/ingress-backendconfig created
Los parámetros
BackendConfig
y las anotaciones del Serviceasm-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.
gcloud
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"
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"
Config Connector
Usa el siguiente manifiesto ComputeSecurityPolicy
:
apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeSecurityPolicy
metadata:
annotations:
cnrm.cloud.google.com/project-id: PROJECT_ID
name: edge-fw-policy
spec:
rule:
- action: allow
description: "Default rule"
match:
versionedExpr: SRC_IPS_V1
config:
srcIpRanges:
- "*"
priority: 2147483647
- action: deny-403
description: "XSS attack filtering"
match:
expr:
expression: "evaluatePreconfiguredExpr('xss-stable')"
priority: 1000
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 asm-ingressgateway
.
Configura direcciones IP y DNS
En Cloud Shell, crea una IP estática global para el balanceador de cargas de Google Cloud:
gcloud
gcloud compute addresses create ingress-ip --global
Config Connector
Usa el siguiente manifiesto
ComputeAddress
:apiVersion: compute.cnrm.cloud.google.com/v1beta1 kind: ComputeAddress metadata: annotations: cnrm.cloud.google.com/project-id: PROJECT_ID name: ingress-ip spec: location: 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.
Obtén la dirección IP estática:
export GCLB_IP=$(gcloud compute addresses describe ingress-ip --global --format "value(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.
Ejecuta el siguiente comando para crear el archivo de especificación YAML 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.Implementa el archivo
dns-spec.yaml
en tu proyecto de Google Cloud:gcloud endpoints services deploy dns-spec.yaml
El resultado es similar a este:
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 [2021-11-14r0] 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
En Cloud Shell, ejecuta el siguiente comando para crear el manifiesto
ManagedCertificate
comomanaged-cert.yaml
:cat <<EOF > managed-cert.yaml apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: gke-ingress-cert namespace: asm-ingress 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.
Implementa el archivo
managed-cert.yaml
en el clúster de GKE:kubectl apply -f managed-cert.yaml
El resultado es similar a este:
managedcertificate.networking.gke.io/gke-ingress-cert created
Inspecciona el recurso
ManagedCertificate
para verificar el progreso de la generación del certificado:kubectl describe managedcertificate gke-ingress-cert -n asm-ingress
El resultado es similar a este:
Name: gke-ingress-cert Namespace: asm-ingress Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.gke.io/v1","kind":"ManagedCertificate","metadata":{"annotations":{},"name":"gke-ingress-cert","namespace":"... API Version: networking.gke.io/v1 Kind: ManagedCertificate Metadata: Creation Timestamp: 2020-08-05T20:44:49Z Generation: 2 Resource Version: 1389781 Self Link: /apis/networking.gke.io/v1/namespaces/asm-ingress/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 comoActive
.
Implementa el recurso Ingress
En Cloud Shell, ejecuta el siguiente comando para crear el manifiesto
Ingress
comoingress.yaml
:cat <<EOF > ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: gke-ingress namespace: asm-ingress annotations: kubernetes.io/ingress.allow-http: "false" kubernetes.io/ingress.global-static-ip-name: "ingress-ip" networking.gke.io/managed-certificates: "gke-ingress-cert" kubernetes.io/ingress.class: "gce" spec: defaultBackend: service: name: asm-ingressgateway port: number: 443 rules: - http: paths: - path: /* pathType: ImplementationSpecific backend: service: name: asm-ingressgateway port: number: 443 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 puerto80
del balanceador de cargas de Google Cloud. Esto evita que los clientes se conecten con tráfico no encriptado, porque el puerto443
solo escucha HTTPS y el puerto80
está inhabilitado.kubernetes.io/ingress.global-static-ip-name: "ingress-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.
Implementa
ingress.yaml
en el clúster:kubectl apply -f ingress.yaml
Inspecciona el recurso Ingress para verificar el progreso de la implementación del balanceador de cargas:
kubectl describe ingress gke-ingress -n asm-ingress
El resultado es similar a este:
... Annotations: ingress.kubernetes.io/https-forwarding-rule: k8s2-fs-fq3ng2uk-asm-ingress-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-asm-ingress-asm-ingressgateway-443-228c1881":"HEALTHY"} ingress.kubernetes.io/forwarding-rule: k8s2-fr-fq3ng2uk-asm-ingress-gke-ingress-qm3qqdor ingress.kubernetes.io/https-target-proxy: k8s2-ts-fq3ng2uk-asm-ingress-gke-ingress-qm3qqdor ingress.kubernetes.io/target-proxy: k8s2-tp-fq3ng2uk-asm-ingress-gke-ingress-qm3qqdor ingress.kubernetes.io/url-map: k8s2-um-fq3ng2uk-asm-ingress-gke-ingress-qm3qqdor ...
El recurso Ingress está listo cuando las anotaciones
ingress.kubernetes.io/backends
indican que los backends tienen el estadoHEALTHY
. 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.
Instala el certificado de puerta de enlace de entrada autofirmado
En los siguientes pasos, generarás e instalarás un certificado (como un recurso secret
de Kubernetes) que permite que el GFE establezca una conexión TLS con la puerta de enlace de entrada de la malla de servicios. Para obtener más detalles sobre los requisitos del certificado de puerta de enlace de entrada, consulta la guía de consideraciones del protocolo de backend seguro.
En Cloud Shell, crea la clave privada y el certificado con
openssl
:openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ -subj "/CN=frontend.endpoints.${PROJECT}.cloud.goog/O=Edge2Mesh Inc" \ -keyout frontend.endpoints.${PROJECT}.cloud.goog.key \ -out frontend.endpoints.${PROJECT}.cloud.goog.crt
Crea el
Secret
en el espacio de nombresasm-ingress
:kubectl -n asm-ingress create secret tls edge2mesh-credential \ --key=frontend.endpoints.${PROJECT}.cloud.goog.key \ --cert=frontend.endpoints.${PROJECT}.cloud.goog.crt
Configura la puerta de enlace de entrada para el balanceo de cargas externo
En los siguientes pasos, crearás un recurso Gateway
compartido en el espacio de nombres asm-ingress
. Por lo general, las puertas de enlace son propiedad de los administradores de la plataforma o el equipo de administradores de red. Por lo tanto, el recurso Gateway
se crea en el espacio de nombres asm-ingress
que pertenece al administrador de la plataforma y se puede usar en otros espacios de nombres a través de sus propias entradas VirtualService
.
En Cloud Shell, ejecuta el siguiente comando para crear el manifiesto
Gateway
comoingress-gateway.yaml
:cat <<EOF > ingress-gateway.yaml apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: asm-ingressgateway namespace: asm-ingress spec: selector: asm: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS hosts: - "*" # IMPORTANT: Must use wildcard here when using SSL, see note below tls: mode: SIMPLE credentialName: edge2mesh-credential EOF
Ten en cuenta que debes usar la entrada comodín
*
en el campohosts
enGateway
. GCLB no usa la extensión SNI en los backends. El uso de la entrada comodín envía el paquete encriptado (de GCLB) a la puerta de enlace de entrada de ASM. La puerta de enlace de Ingress de ASM desencripta el paquete y usa el encabezado del host HTTP (en el paquete desencriptado) para tomar decisiones de enrutamiento (basadas en entradasVirtualService
).Implementa
ingress-gateway.yaml
en el clúster:kubectl apply -f ingress-gateway.yaml
El resultado es similar a este:
gateway.networking.istio.io/asm-ingressgateway created
Instala la app de muestra Online Boutique
En Cloud Shell, crea un espacio de nombres
onlineboutique
dedicado:kubectl create namespace onlineboutique
Agrega una etiqueta de espacio de nombres al espacio de nombres
onlineboutique
:kubectl label namespace onlineboutique istio-injection=enabled
El resultado es similar a este:
namespace/onlineboutique labeled
Si etiquetas el espacio de nombres
onlineboutique
conistio-injection=enabled
, se indica a Anthos Service Mesh que inserte de manera automática proxies de sidecar de Envoy cuando se implementa una aplicación.Descarga los archivos YAML de Kubernetes para la app de muestra Online Boutique:
curl -LO \ https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/release/kubernetes-manifests.yaml
Implementa la app Online Boutique:
kubectl apply -f kubernetes-manifests.yaml -n onlineboutique
El resultado es similar a este:
deployment.apps/frontend created service/frontend created service/frontend-external created ...
Asegúrate de que todas las implementaciones estén en funcionamiento:
kubectl get pods -n onlineboutique
El resultado es similar a este:
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 ...
Ejecuta el siguiente comando para crear el manifiesto
VirtualService
comofrontend-virtualservice.yaml
:cat <<EOF > frontend-virtualservice.yaml apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: frontend-ingress namespace: onlineboutique spec: hosts: - "frontend.endpoints.${PROJECT}.cloud.goog" gateways: - asm-ingress/asm-ingressgateway http: - route: - destination: host: frontend port: number: 80 EOF
Ten en cuenta que
VirtualService
se crea en el espacio de nombres de la aplicación (onlineboutique
). Por lo general, el propietario de la aplicación decide y configura cómo y qué tráfico se enruta a la aplicaciónfrontend
para que el propietario de la app implementeVirtualService
.Implementa
frontend-virtualservice.yaml
en el clúster:kubectl apply -f frontend-virtualservice.yaml
El resultado es similar a este:
virtualservice.networking.istio.io/frontend-virtualservice created
Accede al siguiente vínculo:
echo "https://frontend.endpoints.${PROJECT}.cloud.goog"
Se mostrará el frontend de Online Boutique.
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.
Limpia
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
- En la consola de Google Cloud, ve a la página Administrar recursos.
- En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
- 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 Google Cloud que usaste en este instructivo, borra los recursos individuales:
Borra el recurso Ingress:
kubectl delete -f ingress.yaml
Borra el certificado administrado:
kubectl delete -f managed-cert.yaml
Borra la entrada de DNS de Endpoints:
gcloud endpoints services delete "frontend.endpoints.${PROJECT}.cloud.goog"
El resultado es similar a este:
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.
Cuando se te solicite continuar, ingresa Y.
El resultado es similar a este:
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
Borra la dirección IP estática:
gcloud compute addresses delete ingress-ip --global
El resultado es similar a este:
The following global addresses will be deleted: - [ingress-ip]
Cuando se te solicite continuar, ingresa Y.
El resultado es similar a este:
Deleted [https://www.googleapis.com/compute/v1/projects/edge2mesh/global/addresses/ingress-ip].
Borra el clúster de GKE:
gcloud container clusters delete $CLUSTER_NAME --zone $CLUSTER_LOCATION
¿Qué sigue?
- Obtén más información sobre las otras funciones que ofrece Ingress de GKE que puedes usar con la malla de servicios.
- Obtén más información sobre los distintos tipos de balanceo de cargas en la nube disponibles para GKE.
- Obtén información sobre las características y funciones que ofrece Anthos Service Mesh.
- Consulta cómo implementar Ingress en varios clústeres de GKE para el balanceo de cargas multirregional.
- Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.