Comienza a usar Google Cloud CLI (GKE)


En este instructivo, se muestra cómo configurar y probar una política de autorización binaria que requiere certificaciones. Con este tipo de política, se protege tu cadena de suministro de software basada en contenedores mediante la verificación de que una imagen de contenedor tenga una certificación firmada antes de permitir la implementación de la imagen.

En el momento de la implementación, la autorización binaria usa certificadores para verificar las firmas digitales de las certificaciones. Los firmantes crean las certificaciones, por lo general, como parte de una canalización de integración continua (CI).

En este instructivo, el clúster de GKE, las certificaciones y los certificadores se encuentran en un solo proyecto. La configuración de un solo proyecto es muy útil para realizar pruebas o experimentar con el servicio. Para ver un ejemplo más real, consulta la configuración de varios proyectos.

En los siguientes pasos, se describen las tareas que debes realizar en la línea de comandos. Para seguir estos pasos mediante la consola de Google Cloud, consulta Comienza a usar la consola de Google Cloud.

Objetivos

En este instructivo, aprenderás a realizar lo siguiente:

  • Crear un clúster de Google Kubernetes Engine (GKE) con la autorización binaria habilitada
  • Crear un certificador que el ejecutor de la autorización binaria usará para verificar la firma de una certificación
  • Configurar una política que requiera una certificación
  • Crear un par de claves criptográficas para firmar certificaciones y poder verificarlas más tarde
  • Firmar un resumen de imagen de contenedor, lo que crea una firma
  • Crear una certificación mediante la firma
  • Probar la política mediante la implementación de una imagen de contenedor en GKE

Costos

En este documento, usarás 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 califiquen para obtener una prueba gratuita.

Antes de comenzar

  1. 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.
  2. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  4. Instala Google Cloud CLI.
  5. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

    gcloud init
  6. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  7. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  8. Instala Google Cloud CLI.
  9. Para inicializar la CLI de gcloud, ejecuta el siguiente comando:

    gcloud init
  10. Instala kubectl para interactuar con GKE.

Habilita la autorización binaria

Configura el proyecto predeterminado

El primer paso es configurar el proyecto predeterminado de Google Cloud que usa el comando de gcloud:

PROJECT_ID=PROJECT_ID
gcloud config set project ${PROJECT_ID}

En el ejemplo anterior, PROJECT_ID es el nombre del proyecto.

Habilita las API necesarias

Habilita las API para lo siguiente:

Container Registry

gcloud --project=${PROJECT_ID} \
    services enable\
    container.googleapis.com\
    containerregistry.googleapis.com\
    binaryauthorization.googleapis.com

Artifact Registry

gcloud --project=${PROJECT_ID} \
    services enable\
    container.googleapis.com\
    artifactregistry.googleapis.com\
    binaryauthorization.googleapis.com

Crea un clúster con la autorización binaria habilitada

Cree el clúster

Crea un clúster (de GKE) con la autorización binaria habilitada Este es el clúster en el que se recomienda que se ejecuten las imágenes de contenedor que implementaste. Cuando creas el clúster, debes pasar la marca --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE al comando gcloud container clusters create.

Sigue estos pasos para crear el clúster:

gcloud container clusters create \
    --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE \
    --zone us-central1-a \
    test-cluster

Aquí, crearás un clúster llamado test-cluster en la zona de GKE us-central1-a.

Configura kubectl

También debes actualizar el archivo local kubeconfig de tu instalación de kubectl. Esto proporciona las credenciales y la información del extremo necesarias para acceder al clúster en GKE.

Para actualizar el archivo kubeconfig local, sigue estos pasos:

gcloud container clusters get-credentials \
    --zone us-central1-a \
    test-cluster

Visualiza la política predeterminada

Una política en la autorización binaria es un conjunto de reglas que rige la implementación de imágenes de contenedor. Puedes tener una política por proyecto. De forma predeterminada, la política está configurada para permitir la implementación de todas las imágenes de contenedor.

La autorización binaria te permite importar y exportar un archivo de política en formato YAML. Este formato refleja la estructura de una política tal como el servicio la almacena. Cuando configuras una política mediante los comandos de gcloud, debes editar este archivo.

Para ver la política predeterminada, exporta el archivo de política en formato YAML:

gcloud container binauthz policy export

De forma predeterminada, el archivo tiene el siguiente contenido:

admissionWhitelistPatterns:
- namePattern: gcr.io/google_containers/*
- namePattern: gcr.io/google-containers/*
- namePattern: k8s.gcr.io/**
- namePattern: gke.gcr.io/**
- namePattern: gcr.io/stackdriver-agents/*
globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_ALLOW
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/${PROJECT_ID}/policy

La lista predeterminada contiene el registro de propiedad de la comunidad de código abierto k8s.gcr.io que se reemplaza por registry.k8s.io y se mantiene en la lista para retrocompatibilidad. El registro de reemplazo registry.k8s.io no está incluido en la lista predeterminada. Cuando migres de k8s.gcr.io, ve al registro que tienes sobre el control o agrega el registro de reemplazo registry.k8s.io a esta lista.

Aquí, la regla predeterminada se define en el nodo defaultAdmissionRule. evaluationMode especifica que la política permite todos los intentos de implementación de imágenes. En este instructivo, actualizas la regla predeterminada para exigir certificaciones.

Para obtener más información sobre la estructura de una política, consulta la Referencia sobre las políticas en formato YAML.

Crea un certificador

Un certificador es la autoridad de verificación que el ejecutor de la autorización binaria usa en el momento de la implementación para decidir si permite que GKE implemente la imagen de contenedor firmada correspondiente. El certificador contiene la clave pública y, por lo general, lo administra el personal de tu organización responsable de la seguridad de la cadena de suministro de software.

Para crear un certificador, debes hacer lo siguiente:

  • Crea una nota en Artifact Analysis para almacenar los metadatos de confianza que se usan en el proceso de autorización.
  • Crea el certificador en la autorización binaria y asocia la nota que creaste.

Para este instructivo, debes tener un certificador llamado test-attestor y una nota de Container Analysis llamada test-attestor-note. En una situación real, puedes tener cualquier cantidad de certificadores, cada uno representa a una parte que participa en el proceso de autorización de una imagen de contenedor.

Crea la nota de Artifact Analysis

  1. Establece las variables que almacenan el nombre del certificador y la nota de Artifact Analysis:

    ATTESTOR_NAME=test-attestor
    NOTE_ID=test-attestor-note
    

    Reemplaza lo siguiente:

    • test-attestor: Es el nombre del certificador que elijas.
    • attestor-note: Es el nombre de la nota del certificador que elijas.
  2. Crea un archivo JSON en /tmp/note_payload.json que describa la nota de Container Analysis:

    cat > /tmp/note_payload.json << EOM
    {
      "name": "projects/${PROJECT_ID}/notes/${NOTE_ID}",
      "attestation": {
        "hint": {
          "human_readable_name": "Attestor Note"
        }
      }
    }
    EOM
    
  3. Envía una solicitud HTTP a la API de REST de Artifact Analysis para crear la nota:

    curl -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
        --data-binary @/tmp/note_payload.json  \
        "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
    
  4. Verifica que se haya creado la nota:

    curl \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
    

Crea el certificador

Ahora, puedes crear el certificador:

  1. Crea el certificador en la autorización binaria:

    gcloud container binauthz attestors create ${ATTESTOR_NAME} \
    --attestation-authority-note=${NOTE_ID} \
    --attestation-authority-note-project=${PROJECT_ID}
    
  2. Verifica que se haya creado el certificador:

    gcloud container binauthz attestors list
    

El certificador que creaste aún no se puede usar sin un par de claves PKIX asociado, que puedes crear, a continuación.

Genera un par de claves

La autorización binaria usa claves criptográficas para verificar de forma segura la identidad de los firmantes. Esto garantiza que solo se puedan implementar imágenes de contenedor autorizadas. El par de claves contiene una clave privada y una pública. El firmante usa la clave privada a fin de firmar el resumen de la imagen de contenedor, lo que produce una firma que, luego, se almacena en una certificación. La clave pública se almacena en el certificador. En el momento de la implementación, el ejecutor de la autorización binaria usa la clave pública del certificador para verificar la firma en la certificación antes de permitir la implementación del contenedor.

En este instructivo, usarás el formato (PKIX) de infraestructura de claves públicas (X.509) para las claves criptográficas. En este instructivo, se usa el Algoritmo de firma digital de curva elíptica (ECDSA) que se recomienda para crear el par de claves PKIX. También puedes usar las claves de RSA o PGP para firmar.

Consulta Algoritmos y propósitos de clave para obtener más información sobre los algoritmos de firma.

Las claves que Cloud Key Management Service (Cloud KMS) genera y almacena son compatibles con PKIX. Consulta Crea certificadores mediante la CLI de gcloud para obtener más información sobre el uso de claves de PKIX y Cloud KMS.

PKIX (Cloud KMS)

Para crear el par de claves en Cloud KMS, haz lo siguiente:

  1. Configura las variables de entorno necesarias para crear el par de claves.

    KMS_KEY_PROJECT_ID=${PROJECT_ID}
    KMS_KEYRING_NAME=my-binauthz-keyring
    KMS_KEY_NAME=my-binauthz-kms-key-name
    KMS_KEY_LOCATION=global
    KMS_KEY_PURPOSE=asymmetric-signing
    KMS_KEY_ALGORITHM=ec-sign-p256-sha256
    KMS_PROTECTION_LEVEL=software
    KMS_KEY_VERSION=1
    
  2. Para crear el llavero de claves, ejecuta el siguiente comando:

    gcloud kms keyrings create ${KMS_KEYRING_NAME} \
      --location ${KMS_KEY_LOCATION}
    
  3. Para crear la clave, ejecuta el siguiente comando:

    gcloud kms keys create ${KMS_KEY_NAME} \
      --location ${KMS_KEY_LOCATION} \
      --keyring ${KMS_KEYRING_NAME}  \
      --purpose ${KMS_KEY_PURPOSE} \
      --default-algorithm ${KMS_KEY_ALGORITHM} \
      --protection-level ${KMS_PROTECTION_LEVEL}
    
  4. Para agregar la clave pública al certificador, ejecuta el siguiente comando:

    gcloud --project="${PROJECT_ID}" \
        container binauthz attestors public-keys add \
        --attestor="${ATTESTOR_NAME}" \
        --keyversion-project="${KMS_KEY_PROJECT_ID}" \
        --keyversion-location="${KMS_KEY_LOCATION}" \
        --keyversion-keyring="${KMS_KEYRING_NAME}" \
        --keyversion-key="${KMS_KEY_NAME}" \
        --keyversion="${KMS_KEY_VERSION}"
    
  5. Obtén el ID de la clave pública del certificador de la siguiente manera:

    Puedes ver tu ID de clave pública en cualquier momento con el comando: gcloud container binauthz attestors describe <var>ATTESTOR_NAME</var>.

    Para guardar tu ID de clave pública en una variable de entorno, ingresa el siguiente comando:

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
    --format='value(userOwnedGrafeasNote.publicKeys[0].id)' --project ${PROJECT_ID})
    

PKIX (clave local)

Para generar un par de claves de PKIX, sigue estos pasos:

  1. Crea la clave privada:

    PRIVATE_KEY_FILE="/tmp/ec_private.pem"
    openssl ecparam -genkey -name prime256v1 -noout -out ${PRIVATE_KEY_FILE}
    
  2. Extrae la clave pública de la clave privada:

    PUBLIC_KEY_FILE="/tmp/ec_public.pem"
    openssl ec -in ${PRIVATE_KEY_FILE} -pubout -out ${PUBLIC_KEY_FILE}
    
  3. Agrega la clave pública al certificador.

    Ahora, agrega la clave pública que exportaste al certificador a fin de que la autorización binaria pueda usarla para la verificación de identidad:

    gcloud --project="${PROJECT_ID}" \
        beta container binauthz attestors public-keys add \
        --attestor="${ATTESTOR_NAME}" \
        --pkix-public-key-file=${PUBLIC_KEY_FILE} \
        --pkix-public-key-algorithm=ecdsa-p256-sha256
    
  4. Guarda el ID de la clave pública.

    Para guardar el ID de la clave pública, puedes copiarlo del resultado de public-keys add anterior. Para ver el ID de la clave pública del certificador después de agregárselo, usa gcloud container binauthz attestors describe ${ATTESTOR_NAME}:

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
      --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
    

Configura la política

Ahora puedes configurar tu política. En este paso, exportarás el archivo YAML de la política a tu sistema local y modificarás la regla predeterminada para que necesite una certificación del certificador que definiste antes.

Para configurar la política, sigue estos pasos:

  1. Crea un archivo de política nuevo que permita imágenes del sistema mantenidas por Google, establece el evaluationMode en REQUIRE_ATTESTATION y agrega un nodo llamado requireAttestationsBy que hace referencia al certificador que creaste:

    cat > /tmp/policy.yaml << EOM
        globalPolicyEvaluationMode: ENABLE
        defaultAdmissionRule:
          evaluationMode: REQUIRE_ATTESTATION
          enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
          requireAttestationsBy:
            - projects/${PROJECT_ID}/attestors/${ATTESTOR_NAME}
        name: projects/${PROJECT_ID}/policy
    EOM
    
  2. Importa el archivo YAML de política a la autorización binaria:

    gcloud container binauthz policy import /tmp/policy.yaml
    

Para obtener más información sobre la configuración de una política, consulta Configura una política mediante la CLI de gcloud.

Prueba la política

Para probar la política que configuraste antes, intenta implementar una imagen de contenedor de muestra en el clúster. La política bloqueará la implementación porque no se realizó la certificación necesaria.

Para este instructivo, puedes usar imágenes de muestra de Container Registry y Artifact Registry. La imagen de Container Registry se encuentra en la ruta gcr.io/google-samples/hello-app:1.0. La imagen de Artifact Registry se encuentra en la ruta us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0. Ambas rutas de acceso contienen una imagen pública creada por Google que contiene una aplicación "Hello, World!" de muestra.

Primero, intenta implementar la imagen:

kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080

Ahora, verifica que la autorización binaria haya bloqueado la implementación:

kubectl get pods

El comando imprime el siguiente mensaje, que indica que la imagen no se implementó:

No resources found.

Puedes obtener más detalles sobre la implementación:

kubectl get event --template \
'{{range.items}}{{"\033[0;36m"}}{{.reason}}:{{"\033[0m"}}\{{.message}}{{"\n"}}{{end}}'

Verás una respuesta similar a la siguiente:

FailedCreate: Error creating: pods POD_NAME is forbidden: admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image IMAGE_NAME denied by Binary Authorization default admission rule. Image IMAGE_NAME denied by attestor ATTESTOR_NAME: No attestations found

En este resultado, se ilustra lo siguiente:

  • POD_NAME: Es el nombre del Pod.
  • IMAGE_NAME: Es el nombre de la imagen.
  • ATTESTOR_NAME: Es el nombre del certificador.

Asegúrate de borrar la implementación para poder continuar con el siguiente paso:

kubectl delete deployment hello-server

Crea una certificación

Una certificación es un documento digital creado por un firmante que certifica que GKE puede implementar la imagen de contenedor asociado. A veces, el proceso para crear una certificación se denomina “firmar una imagen”. Un firmante puede ser una persona o, con más frecuencia, un proceso automatizado que se ejecuta cuando se compila una imagen de contenedor. La firma se crea mediante la clave privada de un par de claves. En el momento de la implementación, el ejecutor de la autorización binaria usa la clave pública del certificador para verificar la firma de la certificación.

En este instructivo, tu certificación solo indica que autorizas la implementación de la imagen.

Para crear una certificación, sigue estos pasos:

  1. Configura las variables que almacenen la ruta de registro y el resumen de la imagen:

    Container Registry

    IMAGE_PATH="gcr.io/google-samples/hello-app"
    IMAGE_DIGEST="sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4"
    IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
    

    Artifact Registry

    IMAGE_PATH="us-docker.pkg.dev/google-samples/containers/gke/hello-app"
    IMAGE_DIGEST="sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567"
    IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
    
  2. Para crear la certificación, haz lo siguiente:

    PKIX (Cloud KMS)

    Para crear la certificación con la clave de Cloud KMS, ejecuta el siguiente comando:

    gcloud beta container binauthz attestations sign-and-create \
        --project="${PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="${ATTESTOR_NAME}" \
        --attestor-project="${PROJECT_ID}" \
        --keyversion-project="${KMS_KEY_PROJECT_ID}" \
        --keyversion-location="${KMS_KEY_LOCATION}" \
        --keyversion-keyring="${KMS_KEYRING_NAME}" \
        --keyversion-key="${KMS_KEY_NAME}" \
        --keyversion="${KMS_KEY_VERSION}"
    

    PKIX (clave local)

    Para crear la certificación con la clave local, haz lo siguiente:

    1. Genera la carga útil de la certificación:

      gcloud container binauthz create-signature-payload \
      --artifact-url=${IMAGE_TO_ATTEST} > /tmp/generated_payload.json
      

      El archivo JSON de carga útil tiene el siguiente contenido:

      {
      "critical": {
        "identity": {
          "docker-reference": "gcr.io/google-samples/hello-app"
        },
        "image": {
          "docker-manifest-digest": "sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea
      882eb722c3be4"
        },
        "type": "Google cloud binauthz container signature"
      }
      }
      
    2. Para firmar la carga útil con tu clave privada de PKIX y generar un archivo de firma, ejecuta el siguiente comando:

      openssl dgst -sha256 -sign ${PRIVATE_KEY_FILE} /tmp/generated_payload.json > /tmp/ec_signature
      

      El archivo de firma es la versión firmada del archivo JSON de carga útil que creaste antes en esta guía.

    3. Crea y valida la certificación:

      gcloud container binauthz attestations create \
        --project="${PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="projects/${PROJECT_ID}/attestors/${ATTESTOR_NAME}" \
        --signature-file=/tmp/ec_signature \
        --public-key-id="${PUBLIC_KEY_ID}" \
        --validate
      

      Reemplaza PUBLIC_KEY_ID por el ID de clave pública que encontraste en Genera un par de claves de PKIX.

      La marca validate comprueba que el certificador que configuraste en la política pueda verificar la certificación.

  3. Verifica que se haya creado la certificación:

    gcloud container binauthz attestations list \
        --attestor=$ATTESTOR_NAME --attestor-project=$PROJECT_ID
    

Para obtener más información sobre cómo crear certificaciones, consulta Crea certificaciones.

Vuelve a probar la política

Prueba la política otra vez mediante la implementación de una imagen de contenedor de muestra en el clúster. Esta vez, debes implementar la imagen mediante el resumen en lugar de una etiqueta, como 1.0 o latest, ya que la autorización binaria usará el resumen y la ruta de la imagen para buscar certificaciones. Aquí, la autorización binaria permite implementar la imagen, ya que se realizó la certificación necesaria.

Para implementar la imagen, sigue estos pasos:

kubectl run hello-server --image ${IMAGE_TO_ATTEST} --port 8080

Para verificar que se implementó la imagen, sigue estos pasos:

kubectl get pods

El comando imprime un mensaje similar al siguiente, que indica que la implementación se realizó de forma correcta:

NAME                            READY     STATUS    RESTARTS   AGE
hello-server-579859fb5b-h2k8s   1/1       Running   0          1m

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 clúster que creaste en GKE:

gcloud container clusters delete \
    --zone=us-central1-a \
    test-cluster

¿Qué sigue?