Configuración de Active Directory con clúster de Dataproc Kerberizado

En una publicación anterior, proporcionamos un módulo terraform para implementar clústeres de Dataproc con Kerberos y confiar con MIT KDC para administrar los principales de cuentas de usuario / servicio. Si bien MIT KDC brinda la capacidad de comenzar a funcionar rápidamente, es más común en las empresas tener un sistema de administración de identidad existente, como Active Directory, que se usaría para administrar los usuarios y los principales de las cuentas de servicio para la autenticación con Hadoop.

Si bien podemos automatizar esta implementación con terraform, en esta publicación recorreremos manualmente los pasos a continuación para familiarizarnos con estos conceptos.

  1. Configurar los servicios de dominio de Active Directory (controlador de dominio)
  2. Cree un clúster de Dataproc con confianza unidireccional para AD DS
  3. Cree un usuario con una contraseña y un director de cuenta de servicio con una tabla de claves (almacenada en Secret Manager ) para la autenticación.
  4. Ejecute el comando Hadoop en Dataproc que demuestra la autenticación
Nota importante: esta guía no cubre las mejores prácticas de implementación, incluida la seguridad, alta disponibilidad, arquitecturas híbridas, VPC y otros elementos esenciales que son necesarios para los entornos de producción. Consulte las Prácticas recomendadas para ejecutar Active Directory en Google Cloud e Implementar un entorno de Microsoft Active Directory tolerante a fallas para comenzar.

Visión general

El diagrama y la configuración a continuación representan la implementación de este ejemplo. Abarca un servidor de Active Directory de espacio aislado con confianza entre dominios con Dataproc y utiliza Secrets Manager para almacenar keytabs para cuentas no humanas. Simplificamos nuestro ejemplo al usar un solo proyecto de GCP para todos los componentes, pero los proyectos, las redes privadas y los firewalls separados deben configurarse en un escenario del mundo real.

El dominio para el reino de AD y Dataproc:

 Dominio de Active Directory : FOO.INTERNAL
Instancia del servidor: directorio activo-2016
 Reino del clúster de Dataproc: ANALYTICS.FOO.INTERNAL
Clúster de Dataproc: clúster de análisis
[Confianza unidireccional de Dataproc con autenticación Kerberos de AD]

La arquitectura anterior incorpora los siguientes aspectos clave:

  • Usuarios / cuentas de servicio en Active Directory Corporate Server
  • Los principales de servicio de Dataproc se administran mediante KDC en el clúster. No es necesario crear entidades de servicio en AD.
  • La confianza unidireccional se puede crear en Active Directory antes de la creación del clúster de Dataproc. Esto proporciona flexibilidad para que los clústeres efímeros se unan a AD de forma dinámica.
  • Administrador de secretos para almacenar / rotar keytabs agregado por el administrador de Active Directory y solo accesible por el administrador de clúster de Analytics Dataproc.

Prerrequisitos

Los siguientes requisitos previos son necesarios para configurar instancias de Windows y Dataproc GCE en nuestro proyecto. No cubriremos la configuración de la VPC y otros aspectos como se mencionó anteriormente. Los siguientes pasos se pueden ejecutar en cloud shell o terminal local.

1. Configurar el entorno / cuentas (modificar según sea necesario) :
Cree su proyecto de GCP (en nuestro ejemplo se usa ad-kerberos ), inicialice su sdk de gcloud , configure la región / zona predeterminada y comencemos.

 # propiedades
exportar PROYECTO = $ (gcloud info --format = 'valor (config.project)')
export ZONE = $ (gcloud info --format = 'value (config.properties.compute.zone)')
export REGION = $ {ZONE% - *}
exportar SUBRED = predeterminado
exportar BUCKET_SECRETS = $ {PROJECT} -us-dataproc-secrets
 # cuentas de administrador / servicio de gcp
exportar GCP_ADMIN = $ (gcloud info --format = 'value (config.account)')
exportar SERVICE_ACCOUNT_AD = directorio-activo-sa
exportar SERVICE_ACCOUNT_DL = dataproc-analytics-cluster-sa
 # crear una cuenta de servicio de gcp para el clúster de dataproc
Las cuentas de servicio de gcloud iam crean "$ {SERVICE_ACCOUNT_DL}" \
--description = "dataproc sa" \
--display-name = $ {SERVICE_ACCOUNT_DL}
 # crear una cuenta de servicio gcp para la instancia de gce del directorio activo
Las cuentas de servicio de gcloud iam crean $ {SERVICE_ACCOUNT_AD} \
--description = "directorio activo sa" \
--display-name = $ {SERVICE_ACCOUNT_AD}
 # habilitar el acceso privado a Google en la subred
Actualización de subredes de redes de computación de gcloud $ {SUBNETWORK} --region = $ {REGION} --enable-private-ip-google-access
 # Rol de IAM para el túnel IAP a AD y Dataproc (si es necesario)
proyectos de gcloud add-iam-policy-binding $ {PROJECT} \
--member = user: $ {GCP_ADMIN} \
--role = roles / iap.tunnelResourceAccessor
 # Rol de IAM para el clúster de dataproc
proyectos de gcloud add-iam-policy-binding $ {PROJECT} --member = serviceAccount: $ {SERVICE_ACCOUNT_DL}@${PROJECT}.iam.gserviceaccount.com --role = roles / dataproc.worker

2. Configura Cloud KMS, Secret Manager y secretos
En la segunda mitad de nuestro ejemplo, usaremos Cloud KMS para la configuración de Dataproc con Kerberos y Secret Manager para almacenar una tabla de claves de Active Directory para la cuenta core-data-svc. Los configuramos en los siguientes pasos para su uso posterior.

2.1. Cree el llavero de claves de Cloud KMS, la clave de Cloud KMS y asigne funciones de IAM.

 # propiedades
exportar KMS_KEY_RING_LOCATION = us
exportar KMS_KEY_RING_NAME = dataproc-key-ring
exportar KMS_KEY_NAME = clave de proceso de datos
exportar KMS_KEY_URI = proyectos / $ {PROJECT} / ubicaciones / $ {KMS_KEY_RING_LOCATION} / keyRings / $ {KMS_KEY_RING_NAME} / cryptoKeys / $ {KMS_KEY_NAME}
 # crear llavero kms
Los llaveros de gcloud kms crean $ {KMS_KEY_RING_NAME} \
--proyecto $ {PROYECTO} \
--ubicación $ {KMS_KEY_RING_LOCATION}
 # crear clave kms
Las claves de gcloud kms crean $ {KMS_KEY_NAME} \
--proyecto $ {PROYECTO} \
--ubicación $ {KMS_KEY_RING_LOCATION} \
--encriptación de propósito \
- llavero $ {KMS_KEY_RING_NAME}
 # permitir que dataproc descifre el rol de IAM en la clave kms para la creación de clústeres
gcloud kms keys add-iam-policy-binding $ {KMS_KEY_NAME} --location $ {KMS_KEY_RING_LOCATION} --keyring $ {KMS_KEY_RING_NAME} --member = serviceAccount: $ {SERVICE_ACCOUNT_DL}@${PROJECT}.iam.gserviceaccount.com - -role = roles / cloudkms.cryptoKeyDecrypter
 # permitir que AD descifre el rol de IAM en la clave kms para el secreto compartido
gcloud kms keys add-iam-policy-binding $ {KMS_KEY_NAME} --location $ {KMS_KEY_RING_LOCATION} --keyring $ {KMS_KEY_RING_NAME} --member = serviceAccount: $ {SERVICE_ACCOUNT_AD}@${PROJECT}.iam.gserviceaccount.com - -role = roles / cloudkms.cryptoKeyDecrypter

2.2. Genere secretos aleatorios para el principal raíz de Dataproc y el principal compartido con Active Directory.

 # crear secreto
openssl rand -base64 32 | sed 's / \ /// g'> cluster_secret.txt
openssl rand -base64 32 | sed 's / \ /// g'> trust_secret.txt
 # crear un depósito en el proyecto para los secretos (restringir el acceso)
gsutil mb gs: // $ BUCKET_SECRETS
 # cifrar el secreto del clúster y almacenarlo en un depósito restringido
cat cluster_secret.txt \
| gcloud kms encrypt --ciphertext-file - --plaintext-file \
- --key "$ {KMS_KEY_URI}" | gsutil cp - gs: // $ {BUCKET_SECRETS} /analytics-cluster_principal.encrypted
 # cifrar el secreto de confianza y almacenarlo en un depósito restringido
cat trust_secret.txt | gcloud kms encrypt \
--archivo-de-texto-cifrado - --archivo-de-texto-simple - --key "$ {KMS_KEY_URI}" \
| gsutil cp - gs: // $ {BUCKET_SECRETS} /trust_analytics-cluster_ad_principal.encrypted
 # permitir el acceso del directorio activo a secretos compartidos
gsutil iam ch serviceAccount: $ {SERVICE_ACCOUNT_AD} @ $ {PROJECT} .iam.gserviceaccount.com: objectViewer gs: // $ {BUCKET_SECRETS}

2.3. Cree un secreto en Secret Manager y asigne roles de IAM para almacenar la tabla de claves core-data-svc.

 # propiedades
exportar KEYTAB_SECRET = keytab-core-data-svc
 # crear un secreto de administrador secreto para almacenar la tabla de claves de Kerberos
Los secretos de gcloud crean $ {KEYTAB_SECRET}
 # rol para el sumador de secretos de la cuenta de host de AD para keytab
gcloud secrets add-iam-policy-binding $ {KEYTAB_SECRET} --member = serviceAccount: $ {SERVICE_ACCOUNT_AD}@${PROJECT}.iam.gserviceaccount.com --role = roles / secretmanager.secretVersionAdder
 # rol para los secretos de la cuenta del host de dataproc acccessor para keytab
gcloud secrets add-iam-policy-binding $ {KEYTAB_SECRET} --member = serviceAccount: $ {SERVICE_ACCOUNT_DL}@${PROJECT}.iam.gserviceaccount.com --role = roles / secretmanager.secretAccessor

Configurar el controlador de dominio de Active Directory

En Google Cloud, las imágenes base de Windows Server están disponibles en Compute Engine. Crearemos el controlador de dominio con el centro de datos de Windows Server 2016 para nuestro ejemplo y realizaremos una instalación liviana. Consulte la guía Implementación de un entorno de Microsoft Active Directory tolerante a fallas para obtener una configuración más completa que incluya VPC, DNS, implementación de múltiples zonas, etc.

Cree una instancia de Active Directory. Navegue a Compute Engine> Instancias de VM> Crear instancia .

[Instancia de Google Compute Engine con imagen de Windows]

Configure el disco de arranque Sistema operativo Windows Server y la versión Windows Server 2016 Datacenter .

[Imagen pública del centro de datos de Windows Server 2016]

Para la instancia de GCE, usaremos la cuenta de servicio active-directory-sa que tiene roles de IAM específicos configurados anteriormente.

[Cuenta de servicio de instancia de GCE]

Configure la interfaz de red con IP externa en Ninguno para usar solo la IP interna para la instancia. Si solo usa IP interna, consulte los pasos más adelante en esta guía para configurar RDP a través de un túnel IAP.

[Interfaz de red sin IP externa]

Una vez que el servidor haya terminado de inicializarse, configure la contraseña de Windows .

[Instancia de Windows Server active-directory-2016]

Establecer una nueva contraseña para el usuario.

[Solicitud de restablecimiento de contraseña de Windows]

Inicie sesión en Windows Server mediante Escritorio remoto

La siguiente sección cubre el acceso al servidor de Windows mediante IP interna, pero hay varias opciones disponibles.

  • Si se configura una IP externa ( no se recomienda ), instale la extensión Chrome RDP para Google Cloud Platform , y se puede crear una sesión RDP directamente desde la consola a través del menú desplegable de instancias de directorio activo 2016.
  • Si la IP interna está configurada, configure IAP para el reenvío TCP , cree un túnel y use un cliente RDP (es decir, un cliente Mac ) siguiendo los pasos a continuación.

Inicializar túnel para RDP sobre IAP

 gcloud compute start-iap-tunnel active-directory-2016 3389 --local-host-port = localhost: 3389 --zone = us-central1-a
Probando si la conexión del túnel funciona.
Escuchando en el puerto [3389].

Inicie el cliente de escritorio remoto de Microsoft

Agregue el host localhost y conéctese usando el nombre de usuario / contraseña establecidos anteriormente.

[Escritorio remoto de Microsoft para Mac]

Establecer contraseña de administrador

Después de conectarse a Windows Server, configure la contraseña de administrador . Este paso es necesario para promover el servidor al controlador de dominio.

Navegue a la administración de usuarios a través de Herramientas> Administración de equipos

[Administración de equipos de Active Directory Server Manager]

A continuación, seleccione Usuarios y grupos locales> Usuarios> Administrador> Haga clic con el botón derecho y seleccione Establecer contraseña

[La administración de la computadora estableció la contraseña del administrador]

Configurar los servicios de dominio y el controlador de dominio

Seleccione Agregar roles y funciones a la configuración.

[Administrador del servidor de Active Directory Agregar funciones y características]

A continuación, seleccione el tipo de instalación basada en roles .

[Asistente para agregar funciones y funciones]

Agregar rol de servicios de dominio de Active Directory .

[Asistente para agregar funciones y funciones]

Continúe con los valores predeterminados para Funciones y Servicios de dominio de Active Directory y luego Instale los servicios.

[Asistente para agregar funciones y funciones]

A continuación, promueva este servidor a un controlador de dominio desde el Panel del Administrador del servidor.

[Promocionar servidor a controlador de dominio]

Seleccione Agregar un bosque nuevo y agregue el dominio raíz. En nuestro ejemplo, usamos foo.internal .

[Asistente de configuración de servicios de dominio de Active Directory]

Establezca la contraseña para el modo de restauración y continúe.

[Asistente de configuración de servicios de dominio de Active Directory]

Continúe con el FOO predeterminado para el nombre de dominio NetBIOS en Opciones de DNS y continúe.

[Asistente de configuración de servicios de dominio de Active Directory]

Continúe con la instalación después de la revisión. El servidor se reiniciará automáticamente para completar la instalación.

[Asistente de configuración de servicios de dominio de Active Directory]

Felicitaciones , ahora se ha instalado el controlador de dominio. A continuación, usaremos los secretos encriptados que creamos en la sección de requisitos previos para configurar la confianza desde el KDC del clúster de Dataproc a Active Directory.

Agregar KDC externo al servidor de Active Directory

A continuación, configuramos el dominio externo de Dataproc KDC, ANALYTICS.FOO.INTERNAL, en Active Directory para establecer la confianza unidireccional, aunque todavía no hemos creado el clúster de Dataproc.

Abra powershell (haga clic con el botón derecho y ejecútelo como administrador ) y ejecute lo siguiente:

 # establecer variables de powershell
$ KMS_KEY_URI = "proyectos / ad-kerberos / ubicaciones / us / keyRings / dataproc-key-ring / cryptoKeys / dataproc-key"
$ BUCKET_SECRETS = "ad-kerberos-us-dataproc-secrets"
 # agregar dominio KDC externo a Active Directory
ksetup / addkdc ANALYTICS.FOO.INTERNAL analytics-cluster-m.us-central1-acad-kerberos.internal
 # verificar que se agregó el reino
PS C: \ Usuarios \ jhambleton> ksetup
reino predeterminado = foo.internal (Dominio NT)
ANALYTICS.FOO.INTERNAL:
kdc = analytics-cluster-m.us-central1-acad-kerberos.internal
 # recuperar secreto de confianza
gsutil cp gs: //$BUCKET_SECRETS/trust_analytics-cluster_ad_principal.encrypted.
$ secret = gcloud kms decrypt --ciphertext-file. \ trust_analytics-cluster_ad_principal.encrypted --plaintext-file - --key "$ {KMS_KEY_URI}"
 # crear confianza unidireccional
netdom trust ANALYTICS.FOO.INTERNAL / Domain FOO.INTERNAL / add / realm / passwordt: $ secreto
 # Configure el soporte de otro dominio para el cifrado AES de Kerberos
ksetup / setenctypeattr ANALYTICS.FOO.INTERNAL AES256-CTS-HMAC-SHA1-96 AES128-CTS-HMAC-SHA1-96

Cree un clúster de Dataproc con confianza unidireccional para AD Domain Controller

En su terminal local o shell de nube, cree un archivo YAML para las configuraciones de Dataproc Kerberos (asegúrese de que estas configuraciones estén definidas correctamente).

 #####
# kerberos_dataproc.yaml config
#
enable_kerberos: verdadero
reino: ANALYTICS.FOO.INTERNAL
root_principal_password_uri:
gs: //ad-kerberos-us-dataproc-secrets/analytics-cluster_principal.encrypted
kms_key_uri:
proyectos / ad-kerberos / ubicaciones / us / keyRings / dataproc-key-ring / cryptoKeys / dataproc-key
cross_realm_trust:
reino: FOO.INTERNAL
kdc: directorio-activo-2016.us-central1-acad-kerberos.internal
admin_server: directorio-activo-2016.us-central1-acad-kerberos.internal
shared_password_uri:
gs: //ad-kerberos-us-dataproc-secrets/trust_analytics-cluster_ad_principal.encrypted
tgt_lifetime_hours: 1

Cree el clúster de Dataproc.

 Los clústeres de gcloud dataproc crean un clúster de análisis \
--enable-component-gateway \
--no-address \
--region $ {REGION} \
--zone $ {ZONE} \
--subnet predeterminado \
--image-versión 1.5-debian \
--service-account ${SERVICE_ACCOUNT_DL}@${PROJECT}.iam.gserviceaccount.com \
--scopes ' https://www.googleapis.com/auth/cloud-platform' \
--proyecto $ {PROYECTO} \
--archivo-de-configuración -kerberos ./kerberos_dataproc.yaml

Crear una entidad de servicio de Alice y core-data-svc

A continuación, creemos nuestro primer usuario de prueba Alice en Active Directory. Navegar a
Herramientas> Usuarios y equipos de Active Directory .

[Directorio activo de usuarios y computadoras]

Crear nueva unidad organizativa.

[Nueva unidad organizativa]

Cree la unidad organizativa de GCP Data Lake y la unidad organizativa de usuarios dentro de ella.

[Nueva unidad organizativa: GCP Data Lake OU]

Los usuarios de GCP Data Lake OU contendrán cuentas de usuario especiales específicas para el lago de datos únicamente (es decir, cuentas de servicio AD para ejecutar trabajos programados).

[GCP Data Lake OU]

Cree un nuevo usuario en Usuarios de nivel superior.

[Crear nuevo usuario]

Agregue Alice como el nuevo usuario (¡configuramos el pwd alic123 inseguro! ).

[Usuario nuevo: alice@FOO.INTERNAL]

A continuación, creamos una cuenta de servicio core-data-svc en la unidad organizativa de GCP Data Lake y generamos una tabla de claves para la autenticación.

[Nueva cuenta para core-data-svc en GCP Data Lake OU]
[Nuevo objeto para core-data-svc]

Cree la tabla de claves para esta cuenta core-data-svc no humana. Abra powershell (haga clic con el botón derecho y ejecútelo como administrador ) y ejecute lo siguiente:

 $ KEYTAB_SECRET = "keytab-core-data-svc"
 # generación de keytab
ktpass / out "C: \ Users \ jhambleton \ core-data-svc.keytab" / mapuser core-data-svc / princ core-data-svc@FOO.INTERNAL + rndpass / ptype KRB5_NT_PRINCIPAL / target FOO.INTERNAL / kvno 0 / cripto AES256-SHA1
 # exportar keytab al administrador secreto
Las versiones de gcloud secrets agregan $ {KEYTAB_SECRET} --data-file = "C: \ Users \ jhambleton \ core-data-svc.keytab"
 # eliminar secreto
rm "C: \ Users \ jhambleton \ core-data-svc.keytab"

Verificar la autenticación Kerberos con Active Directory

Inicie sesión, autentíquese como Alice y ejecute los comandos de Hadoop en analytics-cluster.

 $ gcloud compute ssh alice @ analytics-cluster-m --tunnel-through-iap
$ kinit alice@FOO.INTERNAL # ¡Recuerda inseguro pwd alic123!
Contraseña para alice@FOO.INTERNAL:
$ klist
$ hadoop fs -ls / usuario /

Prueba de cuenta de servicio de aplicación core-data-svc@FOO.INTERNAL

Los pasos siguientes se ejecutan utilizando la tabla de teclas y luego destruyen la tabla de teclas local por razones de seguridad. Luego, ejecuta el comando hadoop (o puede iniciar un trabajo de chispa) en el clúster de análisis. El comando solo se puede ejecutar con una identidad de Google con autorización para la instancia del clúster.

Ejecutar desde la terminal local o el shell en la nube ( no se requiere ssh ):

 # propiedades
exportar KEYTAB_SECRET = keytab-core-data-svc
exportar AD_SVC_ACCNT = core-data-svc
export DOMAIN = FOO.INTERNAL
 ## ## ## ##
## comandos que se ejecutarán en un clúster remoto
 # cmd 1 - obtener keytab del administrador secreto
export cmd_get_secret = "gcloud secrets versiones acceden a la última --secret $ {KEYTAB_SECRET} --format = 'get (payload.data)' | tr '_-' '/ +' | base64 -d> ./${AD_SVC_ACCNT}. keytab "
 # cmd 2 - kinit
exportar cmd_kinit = "kinit -kt ./${AD_SVC_ACCNT}.keytab $ {AD_SVC_ACCNT} @ $ {DOMAIN}; rm ./${AD_SVC_ACCNT}.keytab"
 # cmd 3 - ejecutar hadoop cmd o spark-submit
exportar cmd_hadoop = "hadoop fs -ls / user /"
 ## ## ## ##
# ejecutar cmd - ejecutar el comando hadoop / spark-submit con autenticación de kerberos
gcloud compute ssh core-data-svc @ analytics-cluster-m \
--command = "$ {cmd_get_secret}; $ {cmd_kinit}; $ {cmd_hadoop};" - túnel a través de iap

Solución de problemas

En esta sección capturamos algunos comandos útiles que son útiles para depurar si es necesario.

Comando para probar la regla predeterminada del nombre de usuario (reglas hadoop.security.auth_to_local)

 $ hadoop org.apache.hadoop.security.HadoopKerberosName alice@FOO.INTERNAL
Nombre: alice@FOO.INTERNAL a alice

Modo de depuración para Hadoop y Kerberos Handshake

 $ HADOOP_OPTS = "- Dsun.security.krb5.debug = true" hadoop fs -ls /
...
>>> KrbKdcReq enviar: kdc = directorio-activo-2016.us-central1-acad-kerberos.UDP interno: 88, tiempo de espera = 30000, número de reintentos = 3, # bytes = 1378
>>> KDCCommunication: kdc = directorio-activo-2016.us-central1-acad-kerberos.UDP interno: 88, tiempo de espera = 30000, intento = 1, # bytes = 1378
>>> KrbKdcReq enviar: #bytes leídos = 1377
>>> KdcAccessibility: elimine el directorio activo-2016.us-central1-acad-kerberos.internal
>>> EType: sun.security.krb5.internal.crypto.Aes256CtsHmacSha1EType
>>> Servicio de credenciales TGSCredsSingle:
...

Habilite el registrador Hadoop de nivel de seguimiento y el registro de depuración JAAS

 $ HADOOP_ROOT_LOGGER = TRACE, consola HADOOP_JAAS_DEBUG = true hdfs dfs -ls /
...
21/02/05 12:32:54 DEBUG security.UserGroupInformation: confirmación de inicio de sesión de hadoop
21/02/05 12:32:54 DEBUG security.UserGroupInformation: usando el usuario kerberos: alice@FOO.INTERNAL
21/02/05 12:32:54 DEBUG security.UserGroupInformation: Usando el usuario: "alice@FOO.INTERNAL" con el nombre alice@FOO.INTERNAL
...

Seguimiento de nivel de Kerberos

 $ env KRB5_TRACE = / dev / stdout kinit alice@FOO.INTERNAL
[14178] 1612528239.343161: Obtención de las credenciales iniciales para alice@FOO.INTERNAL
[14178] 1612528239.343163: Enviando solicitud no autenticada
[14178] 1612528239.343164: Enviando solicitud (192 bytes) a FOO.INTERNAL
[14178] 1612528239.343165: Resolviendo el nombre de host directorio-activo-2016.us-central1-acad-kerberos.internal
[14178] 1612528239.343166: Envío de una solicitud UDP inicial a dgram 10.128.0.55:88
...

Resumen

En esta sesión, analizamos la configuración de Active Directory Domain Services y Domain Controller como proveedor de identidad para la autenticación con un clúster Kerberizado de Dataproc. Si bien esta configuración fue una implementación simple con un solo clúster de Dataproc, se puede expandir para incorporar arquitecturas de Data Lake complejas en Google Cloud.

Referencias adicionales

Por Wilson Liu y Jordan Hambleton


La configuración de Active Directory con Kerberized Dataproc Cluster se publicó originalmente en Google Cloud - Community on Medium, donde las personas continúan la conversación destacando y respondiendo a esta historia.