Usar claves de encriptado gestionadas por el cliente (CMEK)


En esta página se describe cómo usar claves de encriptado gestionadas por el cliente (CMEK) en Google Kubernetes Engine (GKE). Si necesitas controlar la gestión de tus claves, puedes usar Cloud Key Management Service y CMEK para proteger los discos persistentes conectados y los discos de arranque personalizados de tu clúster de GKE.

Información general

De forma predeterminada, Google Cloud cifra el contenido de los clientes en reposo y GKE gestiona el cifrado por ti sin que tengas que hacer nada.

Si quieres controlar y gestionar la rotación de las claves de cifrado por tu cuenta, puedes usar CMEK. Estas claves cifran las claves de cifrado de datos que cifran tus datos. Para obtener más información, consulta Gestión de claves.

También puedes cifrar secretos en tu clúster con claves que gestiones. Para obtener más información, consulta el artículo Encriptado de secretos en la capa de aplicación.

En GKE, las CMEK pueden proteger los datos de dos tipos de discos de almacenamiento: los discos de arranque de nodos y los discos conectados.

Discos de arranque de nodos
Los discos de arranque de los nodos forman parte de los grupos de nodos de tu clúster. Puedes crear un disco de arranque de nodo cifrado con CMEK al crear clústeres y grupos de nodos.
Discos conectados
Los discos conectados son volúmenes persistentes que usan los pods para el almacenamiento duradero. Los discos persistentes conectados cifrados con CMEK están disponibles en GKE como PersistentVolume aprovisionado dinámicamente.

Para obtener más información sobre los discos de almacenamiento, consulta Opciones de almacenamiento. Los discos del plano de control, que se usan en los planos de control de GKE, no se pueden proteger con CMEK.

Antes de empezar

  1. Para hacer los ejercicios de este tema, necesitas dos proyectos: Google Cloud

    • Proyecto de clave: aquí es donde se crea una clave de cifrado.

    • Proyecto de clúster: aquí es donde se crea un clúster que habilita CMEK.

  2. En tu proyecto de claves, comprueba que hayas habilitado la API Cloud KMS.

    Habilitar la API Cloud KMS

  3. En tu proyecto de claves, el usuario que crea el conjunto de claves y la clave necesita los siguientes permisos de gestión de identidades y accesos:

    • cloudkms.keyRings.getIamPolicy
    • cloudkms.keyRings.setIamPolicy

    Estos permisos se conceden al roles/cloudkms.admin rol de Gestión de Identidades y Accesos predefinido. Puedes consultar más información sobre cómo conceder permisos para gestionar claves en la documentación de Cloud KMS.

  4. En tu proyecto de clúster, comprueba que hayas habilitado la API de Cloud KMS.

    Habilitar la API Cloud KMS

  5. Asegúrate de que has instalado gcloud CLI.

  6. Actualiza gcloud a la versión más reciente:

    gcloud components update
    

Crear una clave de Cloud KMS

Para proteger el disco de arranque o el disco conectado de un nodo con una CMEK, necesitas un conjunto de claves y una clave de Cloud KMS.

Tu conjunto de claves y tu clave deben cumplir los siguientes requisitos:

  • Tu clave debe usar el cifrado simétrico.

  • Debes conceder permisos a la cuenta de servicio de GKE para usar la clave.

  • El conjunto de claves debe tener una ubicación que coincida con la de tu clúster de GKE:

    • Un clúster zonal debe usar un conjunto de claves de una ubicación de superconjunto. Por ejemplo, un clúster de la zona us-central1-a solo puede usar una clave de la región us-central1.

    • Un clúster regional debe usar un conjunto de claves de la misma ubicación. Por ejemplo, un clúster de la región asia-northeast1 debe protegerse con un conjunto de claves de la región asia-northeast1.

    • La región global de Cloud KMS no se puede usar con GKE.

Para obtener instrucciones sobre cómo crear un conjunto de claves y una clave, consulta Crear claves simétricas.

Concede permiso para usar la llave

Debes asignar el rol de gestión de identidades y accesos Encargado del encriptado y desencriptado de la clave criptográfica Cloud KMS (roles/cloudkms.cryptoKeyEncrypterDecrypter) a la cuenta de servicio de Compute Engine en el proyecto de tu clúster. Si asignas este rol, los discos persistentes de GKE podrán acceder a tu clave de cifrado y usarla.

Para asignar el rol roles/cloudkms.cryptoKeyEncrypterDecrypter al agente de servicio de Compute Engine, selecciona una de las siguientes opciones:

gcloud

Ejecuta el siguiente comando:

gcloud kms keys add-iam-policy-binding KEY_NAME \
    --location LOCATION \
    --keyring RING_NAME \
    --member serviceAccount:service-PROJECT_NUMBER@compute-system.iam.gserviceaccount.com \
    --role roles/cloudkms.cryptoKeyEncrypterDecrypter \
    --project KEY_PROJECT_ID

Haz los cambios siguientes:

  • KEY_NAME: el nombre de tu clave.
  • LOCATION: la región en la que has creado el conjunto de claves.
  • RING_NAME: el nombre del conjunto de claves.
  • PROJECT_NUMBER: el número de proyecto de tu clúster.
  • KEY_PROJECT_ID: el ID de tu proyecto de clave.

Consola

  1. En la Google Cloud consola, ve a la página Gestión de claves.

    Ir a Gestión de claves

  2. Haga clic en el nombre del conjunto de claves que contiene la clave.

  3. Haga clic en el nombre de la clave que quiera modificar.

  4. Haz clic en la pestaña Permisos.

  5. Haz clic en Conceder acceso. Se abrirá el panel Dar acceso a la clave.

  6. En el campo Nuevos principales, introduce el nombre del agente de servicio de Compute Engine:

    service-PROJECT_NUMBER@compute-system.iam.gserviceaccount.com
    

    Sustituye PROJECT_NUMBER por el número de proyecto de tu clúster.

  7. En el menú Selecciona un rol, elige Encargado del encriptado y desencriptado de la clave criptográfica Cloud KMS.

  8. Haz clic en Guardar.

Usar discos de arranque de nodos protegidos con CMEK

En esta sección, crearás un clúster o un grupo de nodos con un disco de arranque protegido con CMEK.

No puedes habilitar el cifrado gestionado por el cliente para los discos de arranque de los nodos de un clúster que ya tengas, ya que no puedes cambiar el tipo de disco de arranque de un clúster o un grupo de nodos que ya tengas. Sin embargo, puedes crear un grupo de nodos para tu clúster con el cifrado gestionado por el cliente habilitado y eliminar el grupo de nodos anterior.

Tampoco puedes inhabilitar el cifrado gestionado por el cliente de los discos de arranque de los nodos en un clúster o un grupo de nodos que ya tengas. Sin embargo, puedes crear un grupo de nodos para tu clúster con el cifrado gestionado por el cliente inhabilitado y eliminar el grupo de nodos anterior.

Crear un clúster con un disco de arranque de nodo protegido con CMEK

Puedes crear un clúster con un disco de arranque de nodo protegido con CMEK mediante la CLI de gcloud o la Google Cloud consola.

En los clústeres estándar, solo se pueden cifrar con una clave CMEK los discos persistentes estándar (pd-standard) o los discos persistentes SSD (pd-ssd).

gcloud

Para crear un clúster cuyo disco de arranque esté cifrado con una clave CMEK, especifica un valor para el parámetro --boot-disk-kms-key en el comando de creación del clúster.

Crear un clúster estándar

Para crear un clúster estándar cuyo disco de arranque esté cifrado con una clave CMEK, usa el siguiente comando:

gcloud container clusters create CLUSTER_NAME \
    --cluster-version=latest \
    --location CONTROL_PLANE_LOCATION \
    --boot-disk-kms-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
    --project CLUSTER_PROJECT_ID \
    --disk-type DISK_TYPE

Crear un clúster de Autopilot

Para crear un clúster de Autopilot cuyo disco de arranque esté cifrado con una clave CMEK, usa el siguiente comando:

gcloud container clusters create-auto CLUSTER_NAME \
    --cluster-version=latest \
    --location CONTROL_PLANE_LOCATION \
    --boot-disk-kms-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
    --project CLUSTER_PROJECT_ID

Haz los cambios siguientes:

  • CLUSTER_NAME: el nombre del nuevo clúster.
  • CONTROL_PLANE_LOCATION: la ubicación de Compute Engine del plano de control de tu clúster. Indica una región para los clústeres regionales Estándar y Autopilot, o una zona para los clústeres zonales Estándar.
  • KEY_PROJECT_ID: el ID de tu proyecto de clave.
  • LOCATION: la ubicación del conjunto de claves.
  • RING_NAME: el nombre del conjunto de claves.
  • KEY_NAME: el nombre de tu clave.
  • CLUSTER_PROJECT_ID es el ID del proyecto del clúster.
  • DISK_TYPE: pd-standard (predeterminado) o pd-ssd.

Consola

Crear un clúster estándar

Para crear un clúster estándar cuyo disco de arranque esté cifrado con una clave CMEK, sigue estos pasos:

  1. En la Google Cloud consola, ve a la página Crear un clúster de Kubernetes.

    Ir a Crear un clúster de Kubernetes

  2. Configura el clúster a tu gusto.
  3. En el panel de navegación, ve a Grupos de nodos y haz clic en Nodos.
  4. En la lista desplegable Tipo de disco de arranque, selecciona Disco persistente estándar o Disco persistente SSD.
  5. Marca la casilla Habilitar el encriptado gestionado por el cliente para el disco de arranque y elige la clave de encriptado de Cloud KMS que has creado anteriormente.
  6. Haz clic en Crear.

Crear un clúster de Autopilot

Para crear un clúster de Autopilot cuyo disco de arranque esté cifrado con una clave CMEK, sigue estos pasos:

  1. En la Google Cloud consola, ve a la página Crear un clúster de Autopilot.

    Ir a Crear un clúster de Autopilot

  2. Configura el clúster a tu gusto.
  3. Despliega la sección Opciones avanzadas y busca las opciones de Seguridad.
  4. Marca la casilla Habilitar el encriptado gestionado por el cliente para el disco de arranque y elige la clave de encriptado de Cloud KMS que has creado anteriormente.
  5. Haz clic en Crear.

Crear un grupo de nodos con discos de arranque de nodos protegidos con CMEK

Para crear un grupo de nodos con CMEK habilitado en un clúster estándar, puedes usar la CLI de gcloud o la Google Cloud consola.

gcloud

Para crear un grupo de nodos con cifrado gestionado por el cliente para los discos de arranque de los nodos, especifica un valor para el parámetro --boot-disk-kms-key en el comando de creación.

gcloud container node-pools create NODE_POOL_NAME \
    --location CONTROL_PLANE_LOCATION \
    --disk-type DISK_TYPE \
    --boot-disk-kms-key projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME \
    --project CLUSTER_PROJECT_ID \
    --cluster CLUSTER_NAME

Haz los cambios siguientes:

  • NODE_POOL_NAME: el nombre que elijas para tu grupo de nodos.
  • CONTROL_PLANE_LOCATION: la ubicación de Compute Engine del plano de control de tu clúster. Proporciona una región para los clústeres regionales o una zona para los clústeres zonales.
  • DISK_TYPE: pd-standard (predeterminado) o pd-ssd.
  • KEY_PROJECT_ID:el ID de tu proyecto de clave.
  • LOCATION: la ubicación del conjunto de claves.
  • RING_NAME: el nombre del conjunto de claves.
  • KEY_NAME: el nombre de tu clave.
  • CLUSTER_PROJECT_ID: el ID de proyecto del clúster.
  • CLUSTER_NAME: el nombre del clúster estándar que has creado en el paso anterior.

Consola

  1. Ve a la página Google Kubernetes Engine en la Google Cloud consola.

    Ir a Google Kubernetes Engine

  2. En la lista de clústeres, haga clic en el nombre del clúster que quiera modificar.

  3. Haz clic en Añadir grupo de nodos.

  4. En el panel de navegación, haga clic en Nodos.

  5. En la sección Configuración de la máquina, comprueba que Tipo de disco de arranque sea Disco persistente estándar o Disco persistente SSD.

  6. Marca la casilla Habilitar el encriptado del disco de arranque gestionado por el cliente y selecciona la clave de encriptado de Cloud KMS que has creado.

  7. Haz clic en Crear.

Usar instancias de Filestore o discos persistentes protegidos con CMEK

La siguiente información explica cómo cifrar instancias de Filestore o discos persistentes recién creados. Puedes habilitar CMEK en un clúster nuevo o ya creado, con una clave de Cloud KMS nueva o ya creada.

Estas instrucciones deben completarse una vez por cada clúster de GKE:

Crea un StorageClass que haga referencia a la clave de Cloud KMS

  1. Copia el contenido que aparece abajo en un archivo YAML llamado cmek-sc.yaml. Esta configuración permite el aprovisionamiento dinámico de volúmenes cifrados.

    Instancias de Filestore

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: csi-filestore-cmek
    provisioner: filestore.csi.storage.gke.io
    allowVolumeExpansion: true
    parameters:
      tier: enterprise
      instance-encryption-kms-key: projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME
    
    • El campo instance-encryption-kms-key debe ser el identificador de recurso completo de la clave que se usará para cifrar las nuevas instancias de Filestore.
    • Los valores de instance-encryption-kms-key distinguen entre mayúsculas y minúsculas (por ejemplo, keyRings y cryptoKeys). Si se aprovisiona un nuevo volumen con valores incorrectos, se producirá un error invalidResourceUsage.
    • No puede añadir el parámetro instance-encryption-kms-key a un objeto StorageClass ya creado. Sin embargo, puedes eliminar el objeto StorageClass y volver a crearlo con el mismo nombre, pero con un conjunto de parámetros diferente.

    Discos persistentes

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: csi-gce-pd-cmek
    provisioner: pd.csi.storage.gke.io
    volumeBindingMode: "WaitForFirstConsumer"
    allowVolumeExpansion: true
    parameters:
      type: pd-standard
      disk-encryption-kms-key: projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME
    
    • El campo disk-encryption-kms-key debe ser el identificador de recurso completo de la clave que se usará para cifrar los discos nuevos.
    • Los valores de disk-encryption-kms-key distinguen entre mayúsculas y minúsculas (por ejemplo, keyRings y cryptoKeys). Si se aprovisiona un nuevo volumen con valores incorrectos, se producirá un error invalidResourceUsage.
    • No puedes añadir el parámetro disk-encryption-kms-key a un objeto StorageClass ya creado. Sin embargo, puedes eliminar el objeto StorageClass y volver a crearlo con el mismo nombre, pero con un conjunto de parámetros diferente. Asegúrate de que el aprovisionador de la clase ya creada sea pd.csi.storage.gke.io.

    Puedes establecer StorageClass como predeterminado.

  2. Despliega el StorageClass en tu clúster de GKE con kubectl:

    kubectl apply -f cmek-sc.yaml
    
  3. Verifica que tu StorageClass haya usado el controlador de CSI de Filestore o Persistent Disk de Compute Engine e incluya el ID de tu clave:

    Instancias de Filestore

    kubectl describe storageclass csi-filestore-cmek
    

    En el resultado del comando, comprueba lo siguiente:

    • El provisionador se define como filestore.csi.storage.gke.io.
    • El ID de tu clave sigue el formato instance-encryption-kms-key.
    Name:                  csi-filestore-cmek
    IsDefaultClass:        No
    Annotations:           None
    Provisioner:           filestore.csi.storage.gke.io
    Parameters:            instance-encryption-kms-key=projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME,type=pd-standard
    AllowVolumeExpansion:  true
    MountOptions:          none
    ReclaimPolicy:         Delete
    VolumeBindingMode:     WaitForFirstConsumer
    Events:                none
    

    Discos persistentes

    kubectl describe storageclass csi-gce-pd-cmek
    

    En el resultado del comando, comprueba lo siguiente:

    • El proveedor se define como pd.csi.storage.gke.io.
    • El ID de tu clave es disk-encryption-kms-key.
    Name:                  csi-gce-pd-cmek
    IsDefaultClass:        No
    Annotations:           None
    Provisioner:           pd.csi.storage.gke.io
    Parameters:            disk-encryption-kms-key=projects/KEY_PROJECT_ID/locations/LOCATION/keyRings/RING_NAME/cryptoKeys/KEY_NAME,type=pd-standard
    AllowVolumeExpansion:  unset
    MountOptions:          none
    ReclaimPolicy:         Delete
    VolumeBindingMode:     WaitForFirstConsumer
    Events:                none
    

Crear un volumen de almacenamiento cifrado en GKE

En esta sección, aprovisionarás dinámicamente volúmenes de almacenamiento de Kubernetes cifrados con tu nuevo StorageClass y tu clave de Cloud KMS.

  1. Copia el siguiente contenido en un archivo nuevo llamado pvc.yaml y asegúrate de que el valor de storageClassName coincida con el nombre de tu objeto StorageClass:

    Instancias de Filestore

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: podpvc
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: csi-filestore-cmek
      resources:
        requests:
          storage: 1Ti
    

    Discos persistentes

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: podpvc
    spec:
      accessModes:
        - ReadWriteOnce
      storageClassName: csi-gce-pd-cmek
      resources:
        requests:
          storage: 6Gi
    
  2. Aplica el PersistentVolumeClaim (PVC) en tu clúster de GKE:

    kubectl apply -f pvc.yaml
    
  3. Si tu StorageClass tiene el campo volumeBindingMode definido como WaitForFirstConsumer, debes crear un pod para usar el PVC antes de poder verificarlo. Copia el siguiente contenido en un archivo nuevo llamado pod.yaml y asegúrate de que el valor de claimName coincida con el nombre de tu objeto PersistentVolumeClaim:

    apiVersion: v1
    kind: Pod
    metadata:
      name: web-server
    spec:
      containers:
       - name: web-server
         image: nginx
         volumeMounts:
           - mountPath: /var/lib/www/html
             name: mypvc
      volumes:
       - name: mypvc
         persistentVolumeClaim:
           claimName: podpvc
           readOnly: false
    
  4. Aplica el pod en tu clúster de GKE:

    kubectl apply -f pod.yaml
    
  5. Obtén el estado de tu clúster PersistentVolumeClaim y verifica que el PVC se haya creado y enlazado a un PersistentVolume recién aprovisionado.

    Instancias de Filestore

    kubectl get pvc
    

    El resultado debería ser similar al siguiente:

    NAME      STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS     AGE
    podpvc    Bound     pvc-e36abf50-84f3-11e8-8538-42010a800002   1Ti        RWO            csi-filestore-cmek  9s
    

    Discos persistentes

    kubectl get pvc
    

    El resultado debería ser similar al siguiente:

    NAME      STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS     AGE
    podpvc    Bound     pvc-e36abf50-84f3-11e8-8538-42010a800002   6Gi       RWO            csi-gce-pd-cmek  9s
    

Ahora puedes usar tu disco persistente protegido con CMEK con tu clúster de GKE.

Quitar la protección de CMEK

Cuando encriptas un disco persistente con una clave de Cloud KMS, el encriptado es permanente. No puedes quitar la clave de cifrado de ese disco concreto, aunque elimines o inhabilites la clave de Cloud KMS. La única forma de cambiar la clave de cifrado o de eliminar la protección con CMEK de un disco persistente es crear un disco persistente a partir de una captura del disco. Para obtener más información, consulta Quitar una clave de cifrado de Cloud KMS de un disco persistente.

El cifrado con CMEK no se puede quitar de las instancias de Filestore.

Políticas de organización de GKE y CMEK

GKE admite políticas de la organización de CMEK (vista previa) que pueden requerir protección con CMEK y limitar las claves de Cloud KMS que puedes usar para la protección con CMEK.

Cuando container.googleapis.com está en la lista de servicios de la política Deny de la restricción constraints/gcp.restrictNonCmekServices, GKE rechaza la creación de los siguientes recursos si no habilitas la protección con CMEK:

  • Nuevos clústeres y grupos de nodos
  • Nuevas instancias de Filestore y discos persistentes

Cuando la restricción constraints/gcp.restrictNonCmekCryptoKeyProjects se configura en una política de organización, GKE solo crea recursos protegidos con CMEK que usan una clave de cifrado de un proyecto, una carpeta o una organización permitidos.

Siguientes pasos