En este instructivo, también se muestra cómo puedes combinar kpt con otras soluciones de Google, como el Sincronizador de configuración y los planos de seguridad de GKE Enterprise. Si eres un desarrollador que trabaja con Kubernetes o un ingeniero de plataforma que administra una plataforma basada en Kubernetes, este instructivo te permite descubrir cómo puedes usar kpt en tus flujos de trabajo relacionados con Kubernetes. En este instructivo, se supone que estás familiarizado con Kubernetes y Google Cloud.
La configuración declarativa de la infraestructura de nube es una práctica bien establecida en la industria de TI. Proporciona una poderosa abstracción de los sistemas subyacentes. Esta abstracción evita que tengas que administrar los detalles de la configuración de bajo nivel y las dependencias. Por lo tanto, la configuración declarativa tiene una ventaja en comparación con los enfoques imperativos, como las operaciones realizadas en las interfaces de línea de comandos y gráficas.
El modelo de recursos de Kubernetes ha influido en la popularización de los enfoques de configuración declarativa. Debido a que la API de Kubernetes es completamente declarativa por naturaleza, solo le indica a Kubernetes lo que deseas, no cómo lograr lo que deseas. La API de Kubernetes te permite separar con claridad la configuración (ya sea deseada o real) de las operaciones en la configuración (agregar, quitar y modificar objetos). En otras palabras, en el modelo de recursos de Kubernetes, la configuración son los datos y no el código.
Esta separación entre la configuración y las operaciones tiene muchas ventajas: las personas y los sistemas automatizados pueden comprender y trabajar en la configuración, y el software que modifica la configuración se puede reutilizar con facilidad. Esta separación también te permite implementar con facilidad una metodología de GitOps (como se define en el instructivo de Entrega continua tipo GitOps con Cloud Build).
En este instructivo, explorarás esta separación de la declaración de configuración de las operaciones de configuración mediante kpt. En este instructivo, se destacan las siguientes características de kpt:
- Administración de paquetes: descarga y actualiza paquetes de configuración de Kubernetes.
- Funciones: ejecuta partes arbitrarias del código para modificar o validar los parámetros de configuración.
- Canalización de funciones: un conjunto de funciones que el autor del paquete incluyó en el paquete.
- Administración de recursos: aplica, actualiza y borra los recursos que corresponden a la configuración en un clúster de Kubernetes.
Objetivos
- Crear un clúster de Google Kubernetes Engine (GKE)
- Usa kpt para descargar un conjunto existente de opciones de configuración de Kubernetes.
- Usa las funciones de kpt para personalizar los parámetros de configuración.
- Aplica tu configuración al clúster de GKE.
- Usa kpt a fin de extraer algunos cambios ascendentes para la configuración.
- Usa kpt en una situación real para endurecer tu clúster de GKE.
Costos
En este documento, usarás los siguientes componentes facturables de Google Cloud:
- Google Kubernetes Engine
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Antes de comenzar
- Accede a tu cuenta de Google Cloud. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
-
En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
-
En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.
-
Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
-
En la consola de Google Cloud, activa Cloud Shell.
En la parte inferior de la consola de Google Cloud, se inicia una sesión de Cloud Shell en la que se muestra una ventana de línea de comandos. Cloud Shell es un entorno de shell con Google Cloud CLI ya instalada y con valores ya establecidos para el proyecto actual. La sesión puede tardar unos segundos en inicializarse.
Configura Cloud Shell para usar tu proyecto.
gcloud config set project PROJECT_ID
-
En Cloud Shell, habilita las API de Google Kubernetes Engine y Cloud Source Repositories:
gcloud services enable container.googleapis.com \ sourcerepo.googleapis.com
Cuando completes el instructivo puedes borrar los recursos que hayas creado para evitar que se te sigan facturando. Para obtener más información, consulta Realiza una limpieza.
Crea un clúster de GKE
En esta sección, crearás el clúster de GKE en el que implementarás las opciones de configuración más adelante en el instructivo.
En Cloud Shell, crea un clúster de GKE:
gcloud container clusters create kpt-tutorial \ --num-nodes=1 --machine-type=n1-standard-4 \ --zone=us-central1-a --enable-network-policy
Verifica que tienes acceso al clúster. El siguiente comando muestra información sobre los nodos que están en el clúster.
kubectl get nodes
Aplica un paquete de kpt
En esta sección, usarás kpt para descargar un conjunto de opciones de configuración, personalizarlas y aplicarlas al clúster que creaste en la sección anterior.
kpt
debe instalarse dentro de tu entorno de Cloud Shell. De lo contrario, instálalo con los siguientes comandos:
En Cloud Shell, instala kpt:
sudo apt update && sudo apt-get install google-cloud-sdk-kpt
Descarga un conjunto de parámetros de configuración de ejemplo Para obtener más información, consulta
kpt pkg get
kpt pkg get https://github.com/GoogleContainerTools/kpt.git/package-examples/wordpress@v0.9
Mediante el comando anterior, se descarga el paquete de muestra
wordpress
que está disponible en el repositorio de GitHub kpt, en la versión con la etiquetav0.9
.Examina el contenido del paquete:
kpt pkg tree
.kpt pkg tree wordpress
El resultado luce de la siguiente manera:
Package "wordpress" ├── [Kptfile] Kptfile wordpress ├── [service.yaml] Service wordpress ├── deployment │ ├── [deployment.yaml] Deployment wordpress │ └── [volume.yaml] PersistentVolumeClaim wp-pv-claim └── Package "mysql" ├── [Kptfile] Kptfile mysql ├── [deployment.yaml] PersistentVolumeClaim mysql-pv-claim ├── [deployment.yaml] Deployment wordpress-mysql └── [deployment.yaml] Service wordpress-mysql
El paquete contiene dos paquetes de nivel superior,
wordpress
y un subpaquetewordpress/mysql
, ambos contienen un archivo de metadatosKptfile
. Solo kpt consumeKptfile
y tiene datos sobre la fuente ascendente, la personalización y la validación del paquete.Actualiza la etiqueta del paquete
El autor del paquete agregó una canalización de renderización que suele usarse para transmitir las personalizaciones esperadas.
less wordpress/Kptfile
El contenido debería ser similar a este:
apiVersion: kpt.dev/v1 kind: Kptfile metadata: name: wordpress upstream: type: git git: repo: https://github.com/GoogleContainerTools/kpt directory: /package-examples/wordpress ref: v0.9 updateStrategy: resource-merge upstreamLock: type: git git: repo: https://github.com/GoogleContainerTools/kpt directory: /package-examples/wordpress ref: package-examples/wordpress/v0.9 commit: b9ea0bca019dafa9f9f91fd428385597c708518c info: emails: - kpt-team@google.com description: This is an example wordpress package with mysql subpackage. pipeline: mutators: - image: gcr.io/kpt-fn/set-labels:v0.1 configMap: app: wordpress validators: - image: gcr.io/kpt-fn/kubeval:v0.3
Puedes usar el editor que prefieras para cambiar los parámetros de la función set-label de
app: wordpress
aapp: my-wordpress
.Edita el
wordpress/mysql/deployment.yaml
de implementación de MySQL con tu editor de código favorito para cambiar la versión de MySQL. Además, para fortalecer aún más la seguridad, cambia la variableMYSQL_ROOT_PASSWORD
aMYSQL_PASSWORD
y agrega las siguientes variables:MYSQL_USER
MYSQL_RANDOM_ROOT_PASSWORD
MYSQL_DATABASE
Antes:
[...] containers: - name: mysql image: mysql:5.6 ports: - name: mysql protocol: TCP containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password [...]
Después:
[...] containers: - name: mysql image: mysql:8.0 ports: - name: mysql protocol: TCP containerPort: 3306 env: - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password - name: MYSQL_RANDOM_ROOT_PASSWORD value: '1' - name: MYSQL_USER value: wordpress - name: MYSQL_DATABASE value: wordpress [...]
Edita la implementación de WordPress
wordpress/deployment/deployment.yaml
con el editor de código favorito para cambiar la versión de WordPress y agregar una variableWORDPRESS_DB_USER
.Antes:
[...] containers: - name: wordpress image: wordpress:6.1-apache ports: - name: wordpress protocol: TCP containerPort: 80 env: - name: WORDPRESS_DB_HOST value: wordpress-mysql - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password [...]
Después:
[...] containers: - name: wordpress image: wordpress:4.8-apache ports: - name: wordpress protocol: TCP containerPort: 80 env: - name: WORDPRESS_DB_HOST value: wordpress-mysql - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password - name: WORDPRESS_DB_USER value: wordpress [...]
A diferencia de las herramientas que funcionan solo a través de parámetros, con kpt puedes editar archivos en el lugar mediante un editor y, luego, combinar las actualizaciones ascendentes. Puedes editar
deployment.yaml
directamente sin necesidad de crear un parche ni una función en la canalización.Anota la configuración con
sample-annotation: sample-value
.kpt fn eval wordpress --image gcr.io/kpt-fn/set-annotations:v0.1 \ -- sample-annotation=sample-value
El resultado debería ser similar a este:
[RUNNING] "gcr.io/kpt-fn/set-annotations:v0.1" [PASS] "gcr.io/kpt-fn/set-annotations:v0.1"
Para ver la anotación nueva, puedes examinar cualquier valor de configuración; si deseas ver uno simple, debes ver
wordpress/service.yaml
En este ejemplo, creamos una personalización mediante una función de una forma que el autor del paquete no planificó. kpt puede admitir la ejecución de funciones declarativas y, también, imperativas para permitir una amplia variedad de situaciones.
Si este paquete se desarrolla mediante la infraestructura como código, debemos ir a la fuente del paquete y editar el código allí.
Ejecuta la canalización y valida los cambios con kubeval a través de kpt.
kpt fn render wordpress
El autor del paquete incluyó un paso de validación en la canalización:
... validators: - image: gcr.io/kpt-fn/kubeval:v0.3
El resultado correcto de esta canalización de renderización es el siguiente:
Package "wordpress/mysql": [RUNNING] "gcr.io/kpt-fn/set-labels:v0.1" [PASS] "gcr.io/kpt-fn/set-labels:v0.1" in 1.3s Package "wordpress": [RUNNING] "gcr.io/kpt-fn/set-labels:v0.1" [PASS] "gcr.io/kpt-fn/set-labels:v0.1" in 1.3s [RUNNING] "gcr.io/kpt-fn/kubeval:v0.3" [PASS] "gcr.io/kpt-fn/kubeval:v0.3" in 3.7s Successfully executed 3 function(s) in 2 package(s).
Este paso es un ejemplo de los beneficios del modelo de recursos de Kubernetes: debido a que tus parámetros de configuración se representan en este modelo conocido, puedes usar las herramientas de Kubernetes existentes, como kubeval.
Examina las diferencias entre la versión local de las opciones de configuración y la configuración ascendente:
kpt pkg diff wordpress
Inicializa el paquete para la implementación:
kpt live init wordpress
Con el comando anterior, se compila un inventario de las opciones de configuración que están en el paquete. Entre otros aspectos, kpt usa el inventario para reducir la configuración cuando lo quitas del paquete. Para obtener más información, consulte
kpt live
.Crea un secreto que contenga la contraseña de MySQL:
kubectl create secret generic mysql-pass --from-literal=password=foobar
Aplica las configuraciones a tu clúster:
kpt live apply wordpress
El resultado luce de la siguiente manera:
installing inventory ResourceGroup CRD. inventory update started inventory update finished apply phase started service/wordpress apply successful service/wordpress-mysql apply successful deployment.apps/wordpress apply successful deployment.apps/wordpress-mysql apply successful persistentvolumeclaim/mysql-pv-claim apply successful persistentvolumeclaim/wp-pv-claim apply successful apply phase finished reconcile phase started service/wordpress reconcile successful service/wordpress-mysql reconcile successful deployment.apps/wordpress reconcile pending deployment.apps/wordpress-mysql reconcile pending persistentvolumeclaim/mysql-pv-claim reconcile pending persistentvolumeclaim/wp-pv-claim reconcile pending persistentvolumeclaim/wp-pv-claim reconcile successful persistentvolumeclaim/mysql-pv-claim reconcile successful deployment.apps/wordpress-mysql reconcile successful deployment.apps/wordpress reconcile successful reconcile phase finished inventory update started inventory update finished apply result: 6 attempted, 6 successful, 0 skipped, 0 failed reconcile result: 6 attempted, 6 successful, 0 skipped, 0 failed, 0 timed out
Espera unos minutos y verifica que todo se esté ejecutando como se espera:
kpt live status wordpress
El resultado luce de la siguiente manera:
inventory-88521939/deployment.apps/default/wordpress is Current: Deployment is available. Replicas: 1 inventory-88521939/persistentvolumeclaim/default/wp-pv-claim is Current: PVC is Bound inventory-88521939/service/default/wordpress-mysql is Current: Service is ready inventory-88521939/persistentvolumeclaim/default/mysql-pv-claim is Current: PVC is Bound inventory-88521939/deployment.apps/default/wordpress-mysql is Current: Deployment is available. Replicas: 1 inventory-88521939/service/default/wordpress is Current: Service is ready
Actualiza tu paquete local
En esta sección, actualizarás la versión local del paquete con algunos cambios del paquete ascendente.
Crea un repositorio de Git para la configuración y configura el correo electrónico y el nombre. Necesitas un repositorio de Git local para poder actualizar el paquete. Reemplaza
YOUR_EMAIL
por tu dirección de correo electrónico yYOUR_NAME
por tu nombre.cd wordpress/ git init -b main git config user.email "YOUR_EMAIL" git config user.name "YOUR_NAME"
Confirma tus opciones de configuración:
git add . git commit -m "First version of Wordpress package" cd ..
Actualiza tu paquete local. En este paso, debes extraer la versión
v0.10
del ascendente.kpt pkg update wordpress@v0.10
Observa que las actualizaciones ascendentes se aplican a tu paquete local:
cd wordpress/ git diff
En este caso, la actualización cambió el volumen de implementación de wordpress de 3Gi a 4Gi. También puedes ver tus propios cambios.
Confirma los cambios:
git commit -am "Update to package version v0.10"
Aplica la versión nueva del paquete:
kpt live apply .
Quita un recurso y un paquete
Dado que kpt realiza un seguimiento de los recursos que crea, puede reducir los recursos del clúster cuando borras recursos del paquete. También puede quitar por completo un paquete del clúster. En esta sección, quitas un recurso del paquete y, luego, lo quitas.
Quita el archivo
service.yaml
del paquete:git rm service.yaml git commit -m "Remove service"
Aplica el cambio y, luego, verifica que kpt haya reducido el servicio de wordpress:
kpt live apply . kubectl get svc
Quita el resto del paquete del clúster y, luego, verifica que no quede nada en el clúster:
kpt live destroy . kubectl get deployment
Usa kpt para endurecer tu GKE
El comando kpt live
no es la única forma de aplicar un paquete a un clúster de Kubernetes. En esta sección, se usa kpt con el
Sincronizador de configuración
en una situación básica, pero realista. La herramienta del Sincronizador de configuración te permite administrar tu configuración de manera centralizada, uniforme y declarativa para todos los clústeres de Kubernetes desde un repositorio de Git. GKE Enterprise (que usas en
este instructivo) incluye el
Sincronizador de configuración.
Los planos de seguridad de GKE Enterprise
te proporcionan un rango de opciones de configuración de seguridad empaquetadas previamente para tus
cargas de trabajo basadas en GKE Enterprise. En esta sección, debes usar el plano de restricción del tráfico (y su directorio en el repositorio de GitHub).
Usa kpt para descargar el paquete default-deny
. De forma predeterminada, el paquete usa las políticas de red de Kubernetes para denegar cualquier tráfico en el clúster de GKE (excepto la resolución de DNS). Luego, para aplicar los parámetros de configuración, confírmalos en el repositorio de Git del Sincronizador de configuración.
Instala Sincronizador de configuración
En esta sección, crearás el repositorio de Git que necesita Sincronización de configuración y, luego, instalarás Sincronización de configuración en tu clúster de GKE.
En Cloud Shell, usa Cloud Source Repositories a fin de crear un repositorio de Git para Sincronización de configuración:
cd ~ gcloud source repos create config-management
Genera un par de claves SSH para autenticarte en el repositorio de Git:
cd ~ ssh-keygen -t rsa -b 4096 -N '' \ -f cloud_source_repositories_key
Crea el Secret de Kubernetes que contiene la clave privada SSH para acceder al repositorio de Git:
kubectl create ns config-management-system && \ kubectl create secret generic git-creds \ --namespace=config-management-system \ --from-file=ssh=cloud_source_repositories_key
Muestra la clave pública y, luego, cópiala:
cat cloud_source_repositories_key.pub
Ir a Cloud Source Repositories
Página Administrar claves SSH.
En el cuadro de diálogo Registrar clave SSH que aparece, ingresa los siguientes valores:
- En el campo Nombre de clave, ingresa
config-management
. - En el campo Clave, pega la clave pública.
- Haz clic en Registrar.
- En el campo Nombre de clave, ingresa
Clona el repositorio de Git en Cloud Shell:
gcloud source repos clone config-management cd config-management git checkout -b main
Descarga la herramienta de línea de comandos de Sincronizador de configuración llamada
nomos
:nomos
debe instalarse dentro del entorno de Cloud Shell. De lo contrario, instálalo con los siguientes comandos:sudo apt update && sudo apt-get install google-cloud-sdk-nomos
Inicializa el repositorio de Sincronizador de configuración:
nomos init git add . git commit -m "Config Management directory structure" git push -u origin main
Implementa el operador de Sincronizador de configuración:
gsutil cp gs://config-management-release/released/latest/config-management-operator.yaml /tmp/config-management-operator.yaml kubectl apply -f /tmp/config-management-operator.yaml
Configura Sincronizador de configuración
Crea un recurso personalizado ConfigManagement para configurar Sincronizador de configuración:
PROJECT=$(gcloud config get-value project) EMAIL=$(gcloud config get-value account) cat <<EOF > /tmp/config-management.yaml apiVersion: configmanagement.gke.io/v1 kind: ConfigManagement metadata: name: config-management spec: clusterName: kpt-tutorial git: syncRepo: ssh://${EMAIL}@source.developers.google.com:2022/p/${PROJECT}/r/config-management syncBranch: main secretType: ssh EOF kubectl -n config-management-system \ apply -f /tmp/config-management.yaml
Para obtener más opciones de instalación, consulta la documentación del Sincronizador de configuración de instalación.
En Cloud Shell, verifica que Sincronizador de configuración funcione correctamente:
nomos status --contexts=$(kubectl config current-context)
Mediante este comando, se muestra el estado como
SYNCED
. La inicialización del Sincronizador de configuración puede tardar un tiempo. Si el estado no se actualiza, espera unos minutos y, luego, vuelve a ejecutar el comando.
Aplica el plano de seguridad de GKE Enterprise
En esta sección, usarás kpt para descargar el paquete default-deny
del plano de seguridad de GKE Enterprise que restringe el tráfico. Luego, usarás el Sincronizador de configuración para aplicar el paquete solo al espacio de nombres default
.
Descarga el paquete
default-deny
:cd ~ kpt pkg get https://github.com/GoogleCloudPlatform/anthos-security-blueprints.git/restricting-traffic/default-deny ./
Puedes explorar el contenido del paquete: el archivo
default-deny/Kptfile
contiene los metadatos del paquete y el archivodefault-deny/default-deny.yaml
contiene una NetworkPolicy de Kubernetes, que es la única configuración de este plano.Usa kpt para copiar el contenido del paquete en el repositorio de Sincronizador de configuración y, luego, agrega etiquetas para personalizarlo:
kpt fn source default-deny/ | \ kpt fn eval - --image=gcr.io/kpt-fn/set-annotations:v0.1 -- \ anthos-security-blueprint=restricting-traffic | \ kpt fn sink ~/config-management/namespaces/default/
Como se muestra en este ejemplo, puedes usar canalizaciones para encadenar comandos
kpt fn
. La cadena de comandoskpt fn
te permite leer los parámetros de configuración, modificarlos como desees y escribir el resultado. Puedes encadenar tantos comandoskpt fn
como desees.Crea el archivo
namespace.yaml
en el repositorio del Sincronizador de configuración:cat >> ~/config-management/namespaces/default/namespace.yaml <<EOF apiVersion: v1 kind: Namespace metadata: name: default EOF
El espacio de nombres
default
existe en el clúster de GKE, pero el Sincronizador de configuración no lo administra. Cuando creas el directorio y el archivo en este paso, haces que el Sincronizador de configuración administre el espacio de nombres. Para aplicar el paquete a varios espacios de nombres a la vez, puedes crear un espacio de nombres abstracto.Verifica que las NetworkPolicies de Kubernetes se hayan escrito en el repositorio del Sincronizador de configuración y que estén anotadas con
anthos-security-blueprint: restricting-traffic
:cat config-management/namespaces/default/default-deny.yaml
El resultado luce de la siguiente manera:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: # kpt-merge: /default-deny name: default-deny annotations: internal.kpt.dev/upstream-identifier: 'networking.k8s.io|NetworkPolicy|default|default-deny' anthos-security-blueprint: restricting-traffic spec: policyTypes: - Ingress - Egress podSelector: {} egress: - to: - namespaceSelector: matchLabels: k8s-namespace: kube-system podSelector: matchExpressions: - key: k8s-app operator: In values: ["kube-dns", "node-local-dns"] ports: - protocol: TCP port: 53 - protocol: UDP port: 53
Confirma y envía los cambios:
cd ~/config-management/ git add namespaces/default/ git commit -m "Default deny" git push
Verifica que se aplique la política nueva:
kubectl get networkpolicies
Si la política nueva no está presente, espera unos segundos y vuelve a ejecutar el comando. El Sincronizador de configuración actualiza los parámetros de configuración cada 15 segundos de forma predeterminada. Si necesitas solucionar problemas adicionales, ejecuta el siguiente comando para obtener información sobre los posibles errores del Sincronizador de configuración:
nomos status --contexts=$(kubectl config current-context)
Para probar la política nueva, obtén una shell en un Pod que se ejecuta dentro del espacio de nombres
default
:kubectl -n default run -i --tty --rm test \ --image=busybox --restart=Never -- sh
Intenta hacer ping a
8.8.8.8
y comprueba que no funciona como se espera:ping -c 3 -W 1 8.8.8.8
El resultado luce de la siguiente manera:
PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 3 packets transmitted, 0 packets received, 100% packet loss
Intenta consultar el servidor de API de Kubernetes y comprueba que no funciona, como se esperaba:
wget --timeout=3 https://${KUBERNETES_SERVICE_HOST}
El resultado luce de la siguiente manera:
Connecting to 10.3.240.1 (10.3.240.1:443) wget: download timed out
Sal del pod:
exit
Limpia
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.
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 recursos
Si deseas conservar el proyecto de Google Cloud que usaste en este instructivo, puedes borrar el repositorio de Git y el clúster de GKE. En Cloud Shell, ejecute los siguientes comandos:
gcloud source repos delete config-management --quiet
gcloud container clusters delete kpt-tutorial \
--async --quiet --zone=us-central1-a
¿Qué sigue?
- Obtén más información sobre el Sincronizador de configuración y sus componentes.
- Obtén más información sobre el Policy Controller para validar la configuración de implementación de tu aplicación.
- Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.