Crea recursos de Google Cloud que cumplen con las políticas

En este instructivo, se muestra cómo los administradores de la plataforma pueden usar las políticas del controlador de políticas de Anthos Config Management o del agente de política abierta de Gatekeeper para regular cómo crear recursos de Google Cloud con Config Connector

Se supone que tienes conocimientos básicos de Kubernetes o Google Kubernetes Engine (GKE). En el instructivo, defines una política que restringe las ubicaciones permitidas para los depósitos de Cloud Storage.

Descripción general

Realiza verificaciones del controlador de políticas, auditorías, y aplica el cumplimiento de tus recursos de clúster de Kubernetes con políticas relacionadas con las reglas empresariales, de seguridad o la normativa. El controlador de políticas se compila a partir del proyecto de código abierto Gatekeeper.

Config Connector crea y administra el ciclo de vida derecursos de Google Cloud, como los depósitos de Cloud Storage y las instancias de máquinas virtuales de Compute Engine. Para ello, los describe como Recursos personalizados de Kubernetes. Para crear un recurso de Google Cloud, debes crear un recurso de Kubernetes en un espacio de nombres que administra Config Connector. En el siguiente ejemplo, se muestra cómo describir un depósito de Cloud Storage con Config Connector:

apiVersion: storage.cnrm.cloud.google.com/v1beta1
kind: StorageBucket
metadata:
  name: my-bucket
spec:
  location: us-east1

Cuando administras tus recursos de Google Cloud con Config Connector, puedes aplicar las políticas de Policy Controller y las políticas de Gatekeeper a esos recursos a medida que los creas en tu clúster de GKE. Estas políticas te permiten evitar o informar acciones que creen o modifiquen recursos de formas que infrinjan tus políticas. Por ejemplo, puedes aplicar una política que restrinja las ubicaciones de los depósitos de Cloud Storage.

Este enfoque, basado en el modelo de recursos de Kubernetes (KRM), te permite usar un conjunto coherente de herramientas y flujos de trabajo para administrar tanto recursos de Kubernetes como de Google Cloud. En este instructivo, se demuestra cómo puedes hacer lo siguiente:

  • Definir políticas que rijan tus recursos de Google Cloud
  • Implementar controles que impidan que los desarrolladores y administradores creen recursos de Google Cloud que infrinjan tus políticas
  • Implementa controles que auditan tus recursos existentes de Google Cloud en relación con tus políticas, incluso si creaste esos recursos fuera de Config Connector.
  • Proporciona comentarios rápidos a los desarrolladores y administradores a medida que crean y actualizan las definiciones de recursos.
  • Validar las definiciones de recursos de Google Cloud según tus políticas antes de intentar aplicar las definiciones a un clúster de Kubernetes.

Objetivos

  • Crear un clúster de GKE que incluya el complemento de Config Connector
  • Instala el controlador de políticas o la puerta de enlace de OPA.
  • Crear una política de Gatekeeper para restringir las ubicaciones permitidas para depósitos de Cloud Storage
  • Verificar que la política de Gatekeeper impida la creación de depósitos de Cloud Storage en ubicaciones no permitidas
  • Evaluar el cumplimiento de políticas de la definición de depósito de Cloud Storage durante el desarrollo
  • Auditar los depósitos de Cloud Storage existentes para cumplir con las políticas

Costos

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

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

Antes de comenzar

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

    Ir al selector de proyecto

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

  3. En Cloud Console, activa Cloud Shell.

    Activar Cloud Shell

  4. En Cloud Shell, configura el proyecto de Google Cloud que deseas usar para este instructivo:

    gcloud config set project PROJECT_ID
    

    Reemplaza PROJECT_ID con el ID del proyecto de Cloud de tu proyecto. Cuando ejecutas este comando, Cloud Shell crea una variable de entorno exportada llamada GOOGLE_CLOUD_PROJECT que contiene el ID del proyecto. Si no usas Cloud Shell, puedes crear la variable de entorno con este comando:

    export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value core/project)
    
  5. Habilita la API de GKE:

    gcloud services enable container.googleapis.com
    
  6. Crea un directorio para almacenar los archivos creados en este instructivo:

    mkdir -p ~/cnrm-gatekeeper-tutorial
    
  7. Ve al directorio que creaste:

    cd ~/cnrm-gatekeeper-tutorial
    

Crea un clúster de GKE

  1. En Cloud Shell, crea un clúster de GKE con el complemento de Config Connector y Workload Identity:

    gcloud container clusters create CLUSTER_NAME \
      --addons ConfigConnector \
      --enable-ip-alias \
      --enable-stackdriver-kubernetes \
      --num-nodes 4 \
      --release-channel regular \
      --scopes cloud-platform \
      --workload-pool $GOOGLE_CLOUD_PROJECT.svc.id.goog \
      --zone ZONE
    

    Reemplaza lo siguiente:

    • CLUSTER_NAME: El nombre del clúster que deseas usar para este proyecto, por ejemplo, cnrm-gatekeeper-tutorial.
    • ZONE: Una zona de Compute Engine cerca de tu ubicación, por ejemplo, asia-southeast1-b.

    El complemento Config Connector instala definiciones de recursos personalizadas (CRD) para los recursos de Google Cloud en tu clúster de GKE.

  2. Si usas un clúster privado en tu entorno, agrega una regla de firewall que permita que el plano de control del clúster de GKE se conecte al controlador de políticas o al webhook de OPA Gatekeeper (opcional):

    gcloud compute firewall-rules create allow-cluster-control-plane-tcp-8443 \
      --allow tcp:8443 \
      --network default \
      --source-ranges CONTROL_PLANE_CIDR \
      --target-tags NODE_TAG
    

    Reemplaza lo siguiente:

    • CONTROL_PLANE_CIDR: El rango de IP para tu plano de control de clúster de GKE, por ejemplo, 172.16.0.16/28
    • NODE_TAG: La etiqueta que se aplica a todos los nodos de tu clúster de GKE.

    Esta regla de firewall opcional es obligatoria para que el controlador de políticas o el webhook de Gatekeeper funcionen cuando tu clúster usa nodos privados.

Configura Config Connector

El proyecto de Google Cloud en el que instalas Config Connector se conoce como el proyecto host. Los proyectos en los que utilizas Config Connector para administrar recursos se conocen como proyectos administrados. En este instructivo, debes usar Config Connector para crear recursos de Google Cloud en el mismo proyecto que tu clúster de GKE, de modo que el proyecto host y el proyecto administrado sean el mismo proyecto.

  1. En Cloud Shell, crea una cuenta de servicio de Google para Config Connector:

    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name "Config Connector Gatekeeper tutorial"
    

    Reemplaza SERVICE_ACCOUNT_NAME con el nombre que deseas usar para esta cuenta de servicio, por ejemplo, cnrm-gatekeeper-tutorial. Config Connector usa esta cuenta de servicio de Google para crear recursos en tu proyecto administrado.

  2. Otorga la función Administrador de almacenamiento a la cuenta de servicio de Google:

    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
      --member "serviceAccount:SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
      --role roles/storage.admin
    

    En este instructivo, usarás la función Administrador de almacenamiento porque usas Config Connector para crear depósitos de Cloud Storage. En tu propio entorno, otorga las funciones necesarias para administrar los recursos de Google Cloud que deseas crear para Config Connector. Para obtener más información sobre las funciones predefinidas, consulta Comprende las funciones en la documentación de IAM.

  3. Crea un espacio de nombres de Kubernetes para los recursos de Config Connector que creas en este instructivo:

    kubectl create namespace NAMESPACE
    

    Reemplaza NAMESPACE por el espacio de nombres de Kubernetes con el que trabajarás en el instructivo, por ejemplo, tutorial.

  4. Anota el espacio de nombres a fin de especificar qué proyecto de Config Connector debe usar para crear recursos de Google Cloud (el proyecto administrado):

    kubectl annotate namespace NAMESPACE \
        cnrm.cloud.google.com/project-id=$GOOGLE_CLOUD_PROJECT
    
  5. Crea un recurso ConfigConnectorContext que habilite Config Connector para el espacio de nombres de Kubernetes y lo asocia con la cuenta de servicio de Google que creaste:

    cat << EOF | kubectl apply -f -
    apiVersion: core.cnrm.cloud.google.com/v1beta1
    kind: ConfigConnectorContext
    metadata:
      name: configconnectorcontext.core.cnrm.cloud.google.com
      namespace: NAMESPACE
    spec:
      googleServiceAccount: SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    EOF
    

    Cuando creas el recurso ConfigConnectorContext, Config Connector crea una cuenta de servicio de Kubernetes y StatefulSet en el espacio de nombres cnrm-system para administrar los recursos de Config Connector en tu espacio de nombres.

  6. Espera el pod controlador de Config Connector para tu espacio de nombres:

    kubectl wait --namespace cnrm-system --for=condition=Ready pod \
      -l cnrm.cloud.google.com/component=cnrm-controller-manager,cnrm.cloud.google.com/scoped-namespace=NAMESPACE
    

    Cuando el pod esté listo, aparecerá el símbolo del sistema de Cloud Shell. Si recibes el mensaje error: no matching resources found, espera un minuto y vuelve a intentarlo.

  7. Vincula tu cuenta de servicio de Config Connector de Kubernetes con tu cuenta de servicio de Google mediante la creación de una vinculación de política de IAM:

    gcloud iam service-accounts add-iam-policy-binding \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
      --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[cnrm-system/cnrm-controller-manager-NAMESPACE]" \
      --role roles/iam.workloadIdentityUser
    

    Esta vinculación permite que la cuenta de servicio cnrm-controller-manager-NAMESPACE de Kubernetes del espacio de nombres cnrm-system actúe como la cuenta de servicio de Google que creaste.

Instala la herramienta de políticas

Si tienes un clúster de Anthos administrado, sigue las instrucciones para instalar el Policy Controller; de lo contrario, instala la distribución de OPA Gatekeeper.

Policy Controller

Instala el Policy Controller según las instrucciones de instalación.

Usa un intervalo de auditoría de 60 segundos.

OPA Gatekeeper

  1. En Cloud Shell, define la versión de OPA Gatekeeper que deseas instalar:

    GATEKEEPER_VERSION=v3.5.1
    
  2. Instala OPA Gatekeeper:

    kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/$GATEKEEPER_VERSION/deploy/gatekeeper.yaml
    
  3. Verifica que OPA Gatekeeper esté instalado:

    kubectl rollout status deploy gatekeeper-controller-manager \
        -n gatekeeper-system
    

    Cuando se complete la instalación, el comando mostrará deployment "gatekeeper-controller-manager" successfully rolled out.

Crea un recurso de Google Cloud mediante Config Connector

  1. En Cloud Shell, crea un manifiesto de Config Connector que represente un depósito de Cloud Storage en la región us-central1:

    cat << EOF > tutorial-storagebucket-us-central1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-us-central1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: us-central1
    EOF
    
  2. Aplica el manifiesto para crear el depósito de Cloud Storage:

    kubectl apply -f tutorial-storagebucket-us-central1.yaml
    
  3. Verifica que Config Connector haya creado el depósito de Cloud Storage:

    gsutil ls | grep tutorial
    

    El resultado aparece de la siguiente manera después de que Config Connector crea el depósito de Cloud Storage:

    gs://tutorial-us-central1-GOOGLE_CLOUD_PROJECT/
    

    En el ejemplo anterior, GOOGLE_CLOUD_PROJECT es tu ID del proyecto de Cloud.

    Si no ves este resultado, espera un minuto y vuelve a realizar el paso.

Crea una política

Una política de Policy Controller y Gatekeeper consta de una plantilla de restricciones y una restricción. La plantilla de restricciones contiene la lógica de políticas. La restricción especifica dónde se aplica la política y los parámetros de entrada en la lógica de la política.

  1. En Cloud Shell, crea una plantilla de restricción que restrinja las ubicaciones de los depósitos de Cloud Storage:

    cat << EOF > tutorial-storagebucket-location-template.yaml
    apiVersion: templates.gatekeeper.sh/v1beta1
    kind: ConstraintTemplate
    metadata:
      name: gcpstoragelocationconstraintv1
    spec:
      crd:
        spec:
          names:
            kind: GCPStorageLocationConstraintV1
          validation:
            openAPIV3Schema:
              properties:
                locations:
                  type: array
                  items:
                    type: string
                exemptions:
                  type: array
                  items:
                    type: string
      targets:
      - target: admission.k8s.gatekeeper.sh
        rego: |
          package gcpstoragelocationconstraintv1
    
          allowedLocation(reviewLocation) {
              locations := input.parameters.locations
              satisfied := [ good | location = locations[_]
                                    good = lower(location) == lower(reviewLocation)]
              any(satisfied)
          }
    
          exempt(reviewName) {
              input.parameters.exemptions[_] == reviewName
          }
    
          violation[{"msg": msg}] {
              bucketName := input.review.object.metadata.name
              bucketLocation := input.review.object.spec.location
              not allowedLocation(bucketLocation)
              not exempt(bucketName)
              msg := sprintf("Cloud Storage bucket <%v> uses a disallowed location <%v>, allowed locations are %v", [bucketName, bucketLocation, input.parameters.locations])
          }
    
          violation[{"msg": msg}] {
              not input.parameters.locations
              bucketName := input.review.object.metadata.name
              msg := sprintf("No permitted locations provided in constraint for Cloud Storage bucket <%v>", [bucketName])
          }
    EOF
    
  2. Aplica la plantilla para crear el depósito de Cloud Storage:

    kubectl apply -f tutorial-storagebucket-location-template.yaml
    
  3. Crea una restricción que solo permita depósitos en las regiones de Singapur y Yakarta (asia-southeast1 y asia-southeast2). La restricción se aplica al espacio de nombres que indicaste antes. Exime al depósito de Cloud Storage predeterminado para Cloud Build.

    cat << EOF > tutorial-storagebucket-location-constraint.yaml
    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: GCPStorageLocationConstraintV1
    metadata:
      name: singapore-and-jakarta-only
    spec:
      enforcementAction: deny
      match:
        kinds:
        - apiGroups:
          - storage.cnrm.cloud.google.com
          kinds:
          - StorageBucket
        namespaces:
        - NAMESPACE
      parameters:
        locations:
        - asia-southeast1
        - asia-southeast2
        exemptions:
        - ${GOOGLE_CLOUD_PROJECT}_cloudbuild
    EOF
    
  4. Aplica la restricción para limitar las zonas en las que pueden existir los depósitos:

    kubectl apply -f tutorial-storagebucket-location-constraint.yaml
    

Verifica la política

  1. Crea un manifiesto que represente un depósito de Cloud Storage en una ubicación no permitida (us-west1):

    cat << EOF > tutorial-storagebucket-us-west1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-us-west1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: us-west1
    EOF
    
  2. Aplica el manifiesto para crear el depósito de Cloud Storage:

    kubectl apply -f tutorial-storagebucket-us-west1.yaml
    

    El resultado es el siguiente:

    Error from server ([singapore-and-jakarta-only] Cloud Storage bucket
    <tutorial-us-west1-GOOGLE_CLOUD_PROJECT> uses a disallowed location
    <us-west1>, allowed locations are ["asia-southeast1",
    "asia-southeast2"]): error when creating
    "tutorial-storagebucket-us-west1.yaml": admission webhook
    "validation.gatekeeper.sh" denied the request: [singapore-and-jakarta-only]
    Cloud Storage bucket <tutorial-us-west1-GOOGLE_CLOUD_PROJECT> uses a
    disallowed location <us-west1>, allowed locations are
    ["asia-southeast1", "asia-southeast2"]
    
  3. (Opcional) Puedes ver un registro de la decisión que se rechaza en la solicitud de los Registros de auditoría de Cloud. Consulta los Registros de actividad del administrador del proyecto:

    gcloud logging read --limit=1 \
        "logName=\"projects/$GOOGLE_CLOUD_PROJECT/logs/cloudaudit.googleapis.com%2Factivity\""'
        resource.type="k8s_cluster"
        resource.labels.cluster_name="CLUSTER_NAME"
        resource.labels.location="ZONE"
        protoPayload.authenticationInfo.principalEmail!~"system:serviceaccount:cnrm-system:.*"
        protoPayload.methodName:"com.google.cloud.cnrm."
        protoPayload.status.code=7'
    

    El resultado se parece al siguiente:

    insertId: 3c6940bb-de14-4d18-ac4d-9a6becc70828
    labels:
      authorization.k8s.io/decision: allow
      authorization.k8s.io/reason: ''
      mutation.webhook.admission.k8s.io/round_0_index_0: '{"configuration":"mutating-webhook.cnrm.cloud.google.com","webhook":"container-annotation-handler.cnrm.cloud.google.com","mutated":true}'
      mutation.webhook.admission.k8s.io/round_0_index_1: '{"configuration":"mutating-webhook.cnrm.cloud.google.com","webhook":"management-conflict-annotation-defaulter.cnrm.cloud.google.com","mutated":true}'
    logName: projects/GOOGLE_CLOUD_PROJECT/logs/cloudaudit.googleapis.com%2Factivity
    operation:
      first: true
      id: 3c6940bb-de14-4d18-ac4d-9a6becc70828
      last: true
      producer: k8s.io
    protoPayload:
      '@type': type.googleapis.com/google.cloud.audit.AuditLog
      authenticationInfo:
        principalEmail: user@example.com
      authorizationInfo:
      - permission: com.google.cloud.cnrm.storage.v1beta1.storagebuckets.create
        resource: storage.cnrm.cloud.google.com/v1beta1/namespaces/NAMESPACE/storagebuckets/tutorial-us-west1-GOOGLE_CLOUD_PROJECT
      methodName: com.google.cloud.cnrm.storage.v1beta1.storagebuckets.create
      requestMetadata:
        callerIp: 203.0.113.1
        callerSuppliedUserAgent: kubectl/v1.21.1 (linux/amd64) kubernetes/5e58841
      resourceName: storage.cnrm.cloud.google.com/v1beta1/namespaces/NAMESPACE/storagebuckets/tutorial-us-west1-GOOGLE_CLOUD_PROJECT
      serviceName: k8s.io
      status:
        code: 7
        message: Forbidden
    receiveTimestamp: '2021-05-21T06:56:24.940264678Z'
    resource:
      labels:
        cluster_name: CLUSTER_NAME
        location: CLUSTER_ZONE
        project_id: GOOGLE_CLOUD_PROJECT
      type: k8s_cluster
    timestamp: '2021-05-21T06:56:09.060635Z'
    

    El campo methodName muestra la operación que se intentó, resourceName muestra el nombre completo del recurso de Config Connector y la sección status muestra que la solicitud no se realizó de forma correcta, con código de error 7 y mensaje Forbidden.

  4. Crea un manifiesto que represente un depósito de Cloud Storage en una ubicación permitida (asia-southeast1):

    cat << EOF > tutorial-storagebucket-asia-southeast1.yaml
    apiVersion: storage.cnrm.cloud.google.com/v1beta1
    kind: StorageBucket
    metadata:
      name: tutorial-asia-southeast1-$GOOGLE_CLOUD_PROJECT
      namespace: NAMESPACE
    spec:
      location: asia-southeast1
    EOF
    
  5. Aplica el manifiesto para crear el depósito de Cloud Storage:

    kubectl apply -f tutorial-storagebucket-asia-southeast1.yaml
    

    El resultado es el siguiente:

    storagebucket.storage.cnrm.cloud.google.com/tutorial-asia-southeast1-GOOGLE_CLOUD_PROJECT created
    

    En el ejemplo anterior, GOOGLE_CLOUD_PROJECT es tu ID del proyecto de Cloud.

  6. Verifica que Config Connector haya creado el depósito de Cloud Storage:

    gsutil ls | grep tutorial
    

    Después de que Config Connector cree el depósito de Cloud Storage, el resultado será el siguiente:

    gs://tutorial-asia-southeast1-GOOGLE_CLOUD_PROJECT/
    gs://tutorial-us-central1-GOOGLE_CLOUD_PROJECT/
    

    Si no ves este resultado, espera un minuto y vuelve a realizar este paso.

Auditoría de restricciones

El controlador de auditoría de Policy Controller y Gatekeeper evalúa de forma periódica los recursos según sus restricciones. El controlador detecta los incumplimientos de políticas de los recursos creados antes que la restricción y los recursos creados fuera de Config Connector.

  1. En Cloud Shell, observa los incumplimientos de todas las restricciones que usan la plantilla de restricción GCPStorageLocationConstraintV1:

    kubectl get gcpstoragelocationconstraintv1 -o json \
      | jq '.items[].status.violations'
    

    El resultado es el siguiente:

    [
      {
        "enforcementAction": "deny",
        "kind": "StorageBucket",
        "message": "Cloud Storage bucket <tutorial-us-central1-GOOGLE_CLOUD_PROJECT>
        uses a disallowed location <us-central1>, allowed locations are
        \"asia-southeast1\", \"asia-southeast2\"",
        "name": "tutorial-us-central1-GOOGLE_CLOUD_PROJECT",
        "namespace": "NAMESPACE"
      }
    ]
    

    Verás el depósito de Cloud Storage que creaste en us-central1 antes de crear la restricción.

Valida recursos durante el desarrollo

Durante el desarrollo y las compilaciones de integración continua, es útil validar los recursos según las restricciones antes de aplicar esos recursos a tu clúster de GKE. La validación proporciona comentarios rápidos y te permite descubrir problemas relacionados con los recursos y las restricciones de manera anticipada. En estos pasos, se muestra cómo validar recursos con kpt. La herramienta de línea de comandos kpt te permite administrar y aplicar los manifiestos de recursos de Kubernetes.

  1. En Cloud Shell, descarga kpt:

    mkdir -p ~/bin
    curl -L https://github.com/GoogleContainerTools/kpt/releases/download/v1.0.0-beta.1/kpt_linux_amd64 --output ~/bin/kpt
    chmod u+x ~/bin/kpt
    export PATH=${HOME}/bin:${PATH}
    
  2. Ejecuta la función de KRM gatekeeper con kpt:

    kpt fn eval . --image=gcr.io/kpt-fn/enforce-gatekeeper:v0.1 --truncate-output=false
    

    Una función de KRM es un programa que puede mutar o validar recursos de Kubernetes almacenados en el sistema de archivos local como archivos YAML. La función gatekeeper de KRM valida los recursos del bucket de Cloud Storage de Config Connector con la política de Gatekeeper. La función KRM gatekeeper se empaqueta como una imagen de contenedor disponible en Container Registry.

    La función informa que los archivos de manifiesto de los depósitos de Cloud Storage de las regiones us-central1 y us-west1 infringen la restricción.

    El resultado se parece al siguiente:

    [RUNNING] "gcr.io/kpt-fn/enforce-gatekeeper:v0.1"
    [FAIL] "gcr.io/kpt-fn/enforce-gatekeeper:v0.1"
      Results:
        [ERROR] Cloud Storage bucket <tutorial-us-central1-GOOGLE_CLOUD_PROJECT> uses a disallowed location <us-central1>, allowed locations are ["asia-southeast1", "asia-southeast2"] violatedConstraint: singapore-and-jakarta-only in object "storage.cnrm.cloud.google.com/v1beta1/StorageBucket/tutorial/tutorial-us-central1-GOOGLE_CLOUD_PROJECT" in file "tutorial-storagebucket-us-central1.yaml"
        [ERROR] Cloud Storage bucket <tutorial-us-west1-GOOGLE_CLOUD_PROJECT> uses a disallowed location <us-west1>, allowed locations are ["asia-southeast1", "asia-southeast2"] violatedConstraint: singapore-and-jakarta-only in object "storage.cnrm.cloud.google.com/v1beta1/StorageBucket/tutorial/tutorial-us-west1-GOOGLE_CLOUD_PROJECT" in file "tutorial-storagebucket-us-west1.yaml"
      Stderr:
        "Cloud Storage bucket <tutorial-us-central1-GOOGLE_CLOUD_PROJECT> uses a disallowed location <us-central1>, allowed locations are [\"asia-southeast1\", \"asia-southeast2\"]"
        "violatedConstraint: singapore-and-jakarta-only"
        ""
        "Cloud Storage bucket <tutorial-us-west1-GOOGLE_CLOUD_PROJECT> uses a disallowed location <us-west1>, allowed locations are [\"asia-southeast1\", \"asia-southeast2\"]"
        "violatedConstraint: singapore-and-jakarta-only"
      Exit code: 1
    

Valida recursos creados fuera de Config Connector

Puedes validar los recursos de Google Cloud que se crearon fuera del Config Connector mediante la exportación de los recursos. Después de exportar los recursos, utiliza cualquiera de las siguientes opciones para evaluar tus políticas de Policy Controller con los recursos exportados:

  • Valida los recursos con la función gatekeeper de KRM.

  • Importa los recursos a Config Connector.

Para exportar los recursos, usa Cloud Asset Inventory.

  1. En Cloud Shell, habilita la API de Cloud Asset:

    gcloud services enable cloudasset.googleapis.com
    
  2. Borra los archivos de manifiesto de recursos de Kubernetes para los depósitos de Cloud Storage en us-central1 y us-west1:

    rm tutorial-storagebucket-us-*.yaml
    
  3. Exporta todos los recursos de Cloud Storage en tu proyecto actual y almacena el resultado en un archivo llamado export.yaml:

    gcloud beta resource-config bulk-export \
      --project $GOOGLE_CLOUD_PROJECT \
      --resource-format krm \
      --resource-types StorageBucket > export.yaml
    

    El resultado se parece al siguiente:

    Exporting resource configurations to stdout...
    
    Export complete.
    
  4. Crea una canalización de kpt mediante la encadenamiento de funciones de KRM. Esta canalización valida los recursos en el directorio actual en función de la política de ubicación de bucket de Cloud Storage:

    kpt fn source . \
      | kpt fn eval - --image gcr.io/kpt-fn/set-namespace:v0.1 -- namespace=NAMESPACE \
      | kpt fn eval - --image gcr.io/kpt-fn/enforce-gatekeeper:v0.1 --truncate-output=false
    

    Los recursos exportados no tienen un valor para el atributo de metadatos namespace. Esta canalización usa una función de KRM llamada set-namespace para establecer el valor namespace de todos los recursos.

    El resultado muestra las infracciones de los recursos que exportaste:

    [RUNNING] "gcr.io/kpt-fn/set-namespace:v0.1"
    [PASS] "gcr.io/kpt-fn/set-namespace:v0.1"
    [RUNNING] "gcr.io/kpt-fn/enforce-gatekeeper:v0.1"
    [FAIL] "gcr.io/kpt-fn/enforce-gatekeeper:v0.1"
      Results:
        [ERROR] Cloud Storage bucket <tutorial-us-central1-GOOGLE_CLOUD_PROJECT> uses a disallowed location <us-central1>, allowed locations are ["asia-southeast1", "asia-southeast2"] violatedConstraint: singapore-and-jakarta-only in object "storage.cnrm.cloud.google.com/v1beta1/StorageBucket/tutorial/tutorial-us-central1-GOOGLE_CLOUD_PROJECT" in file "export.yaml"
      Stderr:
        "Cloud Storage bucket <tutorial-us-central1-GOOGLE_CLOUD_PROJECT> uses a disallowed location <us-central1>, allowed locations are [\"asia-southeast1\", \"asia-southeast2\"]"
        "violatedConstraint: singapore-and-jakarta-only"
      Exit code: 1
    

    Si tu proyecto de Cloud contiene depósitos de Cloud Storage que creaste antes de trabajar en este instructivo y su ubicación infringe la restricción, los depósitos creados anteriormente aparecerán en el resultado.

Felicitaciones. Configuraste con éxito una política que regula la ubicación permitida de los depósitos de Cloud Storage. El instructivo está completo. Ahora, puedes continuar agregando tus propias políticas para otros recursos de Google Cloud.

Soluciona problemas

Si Config Connector no crea los recursos esperados de Google Cloud, usa el siguiente comando en Cloud Shell para ver los registros del administrador de controladores de Config Connector:

kubectl logs --namespace cnrm-system --container manager \
  --selector cnrm.cloud.google.com/component=cnrm-controller-manager,cnrm.cloud.google.com/scoped-namespace=NAMESPACE

Si Policy Controller o el OPA Gatekeeper no aplican las políticas de forma correcta, usa el siguiente comando para ver los registros del administrador de controladores:

kubectl logs deployment/gatekeeper-controller-manager \
  --namespace gatekeeper-system

Si Policy Controller o Gatekeeper no informa las infracciones en el campo status de los objetos de restricción, consulta los registros del controlador de auditoría con este comando:

kubectl logs deployment/gatekeeper-audit --namespace gatekeeper-system

Si tienes otros problemas con este instructivo, te recomendamos que revises los siguientes documentos:

Realice una limpieza

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

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

    Ir a Administrar recursos

  2. Si el proyecto que deseas borrar está vinculado con una organización, expande la lista Organización en la columna Nombre.
  3. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  4. 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 Cloud que usaste en este instructivo, borra los recursos individuales.

  1. En Cloud Shell, borra la restricción de ubicación del depósito de Cloud Storage:

    kubectl delete -f tutorial-storagebucket-location-constraint.yaml
    
  2. Agrega la anotación cnrm.cloud.google.com/force-destroy con un valor de string de true a todos los recursos storagebucket en el espacio de nombres administrado por Config Connector:

    kubectl annotate storagebucket --all --namespace NAMESPACE \
      cnrm.cloud.google.com/force-destroy=true
    

    Esta anotación es una directiva que permite a Config Connector borrar un depósito de Cloud Storage cuando borras el recurso storagebucket correspondiente del clúster de GKE, incluso si el depósito contiene objetos.

  3. Borra los recursos de Config Connector que representan los depósitos de Cloud Storage:

    kubectl delete --namespace NAMESPACE storagebucket --all
    
  4. Borra el clúster de GKE:

    gcloud container clusters delete CLUSTER_NAME \
      --zone ZONE --async --quiet
    
  5. Borra la vinculación de políticas de Workload Identity en IAM:

    gcloud iam service-accounts remove-iam-policy-binding \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com \
      --member "serviceAccount:$GOOGLE_CLOUD_PROJECT.svc.id.goog[cnrm-system/cnrm-controller-manager-NAMESPACE]" \
      --role roles/iam.workloadIdentityUser
    
  6. Borra la vinculación de la función Administrador de Cloud Storage para la cuenta de servicio de Google:

    gcloud projects remove-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
      --member "serviceAccount:SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com" \
      --role roles/storage.admin
    
  7. Borra la cuenta de servicio de Google que creaste para Config Connector:

    gcloud iam service-accounts delete --quiet \
      SERVICE_ACCOUNT_NAME@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    

¿Qué sigue?