Limitare l'accesso per modificare e selezionare ComputeClasses

Puoi utilizzare ComputeClasses di Google Kubernetes Engine (GKE) per creare nodi che soddisfino vari requisiti dei carichi di lavoro. I pod possono utilizzare ComputeClasses per creare hardware. A seconda di ComputeClass, l'hardware potrebbe essere molto richiesto, a disponibilità limitata o relativamente costoso per la tua azienda. Questo tutorial mostra come utilizzare Kubernetes RBAC e ValidatingAdmissionPolicies per limitare la creazione, l'eliminazione, la modifica e la selezione di ComputeClass.

Queste limitazioni possono aiutarti a evitare situazioni come le seguenti:

  • I pod che non richiedono hardware specializzato come GPU o TPU selezionano ComputeClass che richiedono questo hardware.
  • Un'entità non autorizzata crea o modifica ComputeClasses per ottenere l'accesso all'hardware riservato ai carichi di lavoro critici.

Questo documento utilizza un esempio di ValidatingAdmissionPolicy che blocca i tipi comuni di uso improprio, come le tolleranze ComputeClass con caratteri jolly o la selezione di ComputeClass specifiche non consentite. Puoi modificare ValidatingAdmissionPolicy per soddisfare i requisiti specifici della tua organizzazione, ad esempio bloccare i workload di determinati team dall'utilizzo di ComputeClass.

Obiettivi

  • Utilizza un criterio ValidatingAdmissionPolicy per limitare le ComputeClass che i pod possono selezionare in ogni spazio dei nomi a un elenco approvato.
  • Utilizza controllo dell'accesso basato sui ruoli (RBAC) per limitare gli utenti che possono creare, modificare o eliminare ComputeClass nei tuoi cluster.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi utenti di Google Cloud potrebbero avere diritto a una prova senza costi.

Al termine delle attività descritte in questo documento, puoi evitare l'addebito di ulteriori costi eliminando le risorse che hai creato. Per saperne di più, consulta Esegui la pulizia.

Prima di iniziare

  1. Accedi al tuo account Google Cloud . Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti senza costi per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Installa Google Cloud CLI.

  3. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  4. Per inizializzare gcloud CLI, esegui questo comando:

    gcloud init
  5. Crea o seleziona un Google Cloud progetto.

    Ruoli richiesti per selezionare o creare un progetto

    • Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
    • Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto (roles/resourcemanager.projectCreator), che contiene l'autorizzazione resourcemanager.projects.create. Scopri come concedere i ruoli.
    • Creare un progetto Google Cloud :

      gcloud projects create PROJECT_ID

      Sostituisci PROJECT_ID con un nome per il progetto Google Cloud che stai creando.

    • Seleziona il progetto Google Cloud che hai creato:

      gcloud config set project PROJECT_ID

      Sostituisci PROJECT_ID con il nome del progetto Google Cloud .

  6. Se utilizzi un progetto esistente per questa guida, verifica di disporre delle autorizzazioni necessarie per completare la guida. Se hai creato un nuovo progetto, disponi già delle autorizzazioni necessarie.

  7. Verifica che la fatturazione sia attivata per il tuo progetto Google Cloud .

  8. Abilita l'API Kubernetes Engine:

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi disporre del ruolo IAM Amministratore utilizzo dei servizi (roles/serviceusage.serviceUsageAdmin), che include l'autorizzazione serviceusage.services.enable. Scopri come concedere i ruoli.

    gcloud services enable container.googleapis.com
  9. Installa Google Cloud CLI.

  10. Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.

  11. Per inizializzare gcloud CLI, esegui questo comando:

    gcloud init
  12. Crea o seleziona un Google Cloud progetto.

    Ruoli richiesti per selezionare o creare un progetto

    • Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
    • Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto (roles/resourcemanager.projectCreator), che contiene l'autorizzazione resourcemanager.projects.create. Scopri come concedere i ruoli.
    • Creare un progetto Google Cloud :

      gcloud projects create PROJECT_ID

      Sostituisci PROJECT_ID con un nome per il progetto Google Cloud che stai creando.

    • Seleziona il progetto Google Cloud che hai creato:

      gcloud config set project PROJECT_ID

      Sostituisci PROJECT_ID con il nome del progetto Google Cloud .

  13. Se utilizzi un progetto esistente per questa guida, verifica di disporre delle autorizzazioni necessarie per completare la guida. Se hai creato un nuovo progetto, disponi già delle autorizzazioni necessarie.

  14. Verifica che la fatturazione sia attivata per il tuo progetto Google Cloud .

  15. Abilita l'API Kubernetes Engine:

    Ruoli richiesti per abilitare le API

    Per abilitare le API, devi disporre del ruolo IAM Amministratore utilizzo dei servizi (roles/serviceusage.serviceUsageAdmin), che include l'autorizzazione serviceusage.services.enable. Scopri come concedere i ruoli.

    gcloud services enable container.googleapis.com
  16. Se utilizzi una shell locale, installa il componente kubectl:
    gcloud components install kubectl
  17. Assicurati di avere un cluster GKE che utilizzi la versione 1.30 o successive. Puoi anche creare un cluster Autopilot per questo tutorial.
  18. Configura il cluster per Google Gruppi per RBAC:
    1. Configura il gruppo gke-security-groups nel tuo dominio.
    2. Abilita Google Gruppi per RBAC nel cluster.

    Per maggiori informazioni, vedi Configurare Google Gruppi.

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per creare policy RBAC e oggetti Kubernetes nel cluster, chiedi all'amministratore di concederti il ruolo IAM Amministratore Kubernetes Engine (role/container.admin) nel progetto. Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Prepara l'ambiente

Per preparare il cluster per le attività di creazione e verifica di questo tutorial, segui questi passaggi:

  1. Connettiti al cluster:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

    Sostituisci quanto segue:

    • CLUSTER_NAME: il nome del tuo cluster.
    • CONTROL_PLANE_LOCATION: la regione o zona del control plane del cluster, ad esempio us-central1 o us-central1-a.
  2. Crea uno spazio dei nomi da utilizzare per questo tutorial. Puoi anche utilizzare qualsiasi spazio dei nomi esistente nel cluster.

    kubectl create namespace computeclass-vap-tutorial
    
  3. Crea una policy RBAC che conceda l'accesso per gestire ValidatingAdmissionPolicies e ValidatingAdmissionPolicyBindings:

    1. Salva il seguente manifest come validatingadmissionpolicy-editor.yaml:

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: validatingadmissionpolicy-editor
      rules:
      - apiGroups: ["admissionregistration.k8s.io"]
        resources: ["validatingadmissionpolicies","validatingadmissionpolicybindings"]
        verbs: ["get", "list", "create", "update", "patch", "delete"]
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: edit-validatingadmissionpolicies
      subjects:
      - kind: User
        name: USER_ACCOUNT
        apiGroup: rbac.authorization.k8s.io
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: validatingadmissionpolicy-editor
      

      Sostituisci USER_ACCOUNT con l'indirizzo email del tuo account utente.

    2. Crea la policy RBAC:

      kubectl apply -f validatingadmissionpolicy-editor.yaml
      
  4. Crea un ComputeClass nel cluster. Se il cluster ha già una ComputeClass, salta questo passaggio.

    1. Salva il seguente manifest come access-computeclass.yaml:

      apiVersion: cloud.google.com/v1
      kind: ComputeClass
      metadata:
        name: access-restriction-class
      spec:
        priorities:
        - machineFamily: e2
        nodePoolAutoCreation:
          enabled: true
        whenUnsatisfiable: ScaleUpAnyway
      
    2. Crea ComputeClass:

      kubectl apply -f access-computeclass.yaml
      

Crea un ValidatingAdmissionPolicy

Per limitare le ComputeClass che i pod possono selezionare, crea un criterio di controllo dell'ammissione e applicalo in uno spazio dei nomi specifico. Utilizzi la specifica ValidatingAdmissionPolicy per controllare in che modo i pod possono selezionare ComputeClass. I passaggi che seguono mostrano come creare e applicare questa policy:

  1. Salva il seguente manifest ValidatingAdmissionPolicy come restrict-computeclass-usage-vap.yaml:

    apiVersion: admissionregistration.k8s.io/v1
    kind: ValidatingAdmissionPolicy
    metadata:
      name: restrict-computeclass-usage
    spec:
      failurePolicy: Fail # If an internal error occurs, deny the request.
      variables:
      # Check whether the admission request is for a Deployment.
      - name: isDeployment
        expression: "object.kind == 'Deployment'"
      # Get the Pod specification from the admission request by reading the
      # spec.template.spec field for Deployments or the spec field for static Pods.
      - name: podSpec
        expression: "variables.isDeployment ? object.spec.template.spec : object.spec"
      # Check whether a node selector or an affinity rule that explicitly requests a
      # disallowed ComputeClass.
      - name: hasForbiddenNodeSelectorOrAffinity
        expression: >-
          (has(variables.podSpec.nodeSelector) &&
          variables.podSpec.nodeSelector['cloud.google.com/compute-class'] == 'COMPUTECLASS_NAME') ||
          (has(variables.podSpec.affinity) &&
          has(variables.podSpec.affinity.nodeAffinity) &&
          has(variables.podSpec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution) &&
          variables.podSpec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.exists(term, has(term.matchExpressions) &&
            term.matchExpressions.exists(
              exp, exp.key == 'cloud.google.com/compute-class' &&
              exp.operator == 'In' && exp.values.exists(v, v == 'COMPUTECLASS_NAME')
            )
          ))
    
      # Check whether the Pod has a toleration for the taint that corresponds to a
      # disallowed ComputeClass.
      - name: hasForbiddenComputeClassToleration
        expression: >-
          has(variables.podSpec.tolerations) &&
          variables.podSpec.tolerations.exists(t, 
            t.key == 'cloud.google.com/compute-class' &&
            (t.operator == 'Exists' || (t.operator == 'Equal' && t.value == 'COMPUTECLASS_NAME')) &&
            has(t.effect) && t.effect == 'NoSchedule')
    
      # Check whether the Pod has a toleration that could match any taint.
      - name: hasWildcardToleration
        expression: >-
          has(variables.podSpec.tolerations) &&
          variables.podSpec.tolerations.exists(t, 
            (t.operator == 'Exists' && !(has(t.key) && t.key != ''))
          )
    
      # Trigger the ValidatingAdmissionPolicy when Pods or Deployments are created or
      # updated.
      matchConstraints:
        resourceRules:
        - apiGroups: [""]
          apiVersions: ["v1"]
          operations: ["CREATE", "UPDATE"]
          resources: ["pods"]
        - apiGroups: ["apps"]
          apiVersions: ["v1"]
          operations: ["CREATE", "UPDATE"]
          resources: ["deployments"]
    
      # Validate whether any of the expressions in the variables section evaluate to
      # true.
      validations:
        - expression: >-
            !(variables.hasForbiddenNodeSelectorOrAffinity ||
              variables.hasForbiddenComputeClassToleration ||
              variables.hasWildcardToleration)
          message: >-
            Pods and Deployments in this namespace cannot request ComputeClass
            COMPUTECLASS_NAME or use wildcard
            tolerations.
    

    Sostituisci COMPUTECLASS_NAME con il nome di una ComputeClass che vuoi impedire ai pod di selezionare.

    Questo ValidatingAdmissionPolicy ha le seguenti proprietà:

    • Trigger per pod statici o pod nei deployment.
    • Trova i podcast che eseguono una delle seguenti operazioni:

      • Utilizza un selettore di nodi o una regola di affinità dei nodi per selezionare in modo esplicito una ComputeClass non consentita specifica.
      • Utilizza una tolleranza che corrisponda a un taint del nodo per una ComputeClass specifica non consentita.
      • Utilizza una tolleranza che corrisponda a tutte le incompatibilità dei nodi nel cluster.

    Questo ValidatingAdmissionPolicy è un esempio. Puoi utilizzare le espressioni per attivare la policy in base alle tue condizioni, ad esempio impedendo ai pod con etichette specifiche di selezionare determinate ComputeClass.

  2. Crea ValidatingAdmissionPolicy:

    kubectl apply -f restrict-computeclass-usage-vap.yaml
    
  3. Salva il seguente ValidatingAdmissionPolicyBinding come restrict-computeclass-usage-binding.yaml:

    apiVersion: admissionregistration.k8s.io/v1
    kind: ValidatingAdmissionPolicyBinding
    metadata:
      name: restrict-computeclass-usage-binding
    spec:
      policyName: restrict-computeclass-usage
      validationActions: ["Deny","Audit"]
      matchResources:
        namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: computeclass-vap-tutorial # Replace with the name of any namespace in the cluster.
    

    Questo ValidatingAdmissionPolicyBinding applica ValidatingAdmissionPolicy del passaggio precedente nello spazio dei nomi computeclass-vap-tutorial. I valori nel campo validationActions rifiutano i pod o i deployment che violano ValidatingAdmissionPolicy e aggiungono una voce al log di controllo di Kubernetes.

  4. Crea ValidatingAdmissionPolicyBinding:

    kubectl apply -f restrict-computeclass-usage-binding.yaml
    

Configura i criteri RBAC

Oltre a utilizzare un ValidatingAdmissionPolicy per impedire ai workload di utilizzare determinate ComputeClass, utilizza RBAC per impedire alle entità non autorizzate di creare e modificare le ComputeClass nel tuo cluster. I passaggi seguenti mostrano come concedere l'accesso a ComputeClasses a un gruppo specifico di utenti utilizzando Google Gruppi per il controllo dell'accesso basato sui ruoli (RBAC):

  1. Crea un gruppo per gli editor di ComputeClass:

    1. Nella Console di amministrazione Google, vai alla pagina Gruppi.

      Vai a Gruppi

    2. Fai clic su Crea gruppo.

    3. Nella pagina Dettagli gruppo:

      1. Nel campo Nome gruppo, specifica computeclass-editors.
      2. Nel campo Email del gruppo, specifica computeclass-editors.
      3. Seleziona la casella di controllo Sicurezza.
      4. Fai clic su Avanti.
    4. Nella pagina Tipo di accesso, nella colonna Membri del gruppo, verifica che la casella di controllo Chi può visualizzare i membri sia selezionata.

    5. Fai clic su Crea gruppo.

    6. Nel menu di navigazione, fai clic su Directory > Gruppi.

    7. Passa il mouse sopra la riga gke-security-groups, quindi fai clic su Aggiungi membri.

    8. Nella finestra di dialogo Aggiungi membri a gke-security-groups, specifica computeclass-editors e seleziona il gruppo dai risultati.

    9. Fai clic su Aggiungi al gruppo.

  2. Aggiungi gli indirizzi email degli utenti autorizzati al gruppo computeclass-editors.

  3. Salva il seguente ClusterRole come computeclass-editor-clusterrole.yaml:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: computeclass-editor
    rules:
    -   apiGroups: ["cloud.google.com"]
      resources: ["computeclasses"]
      verbs: ["create","update"]
    
  4. Crea il ClusterRole:

    kubectl apply -f computeclass-editor-clusterrole.yaml
    
  5. Salva il seguente ClusterRoleBinding come computeclass-editor-role-binding.yaml:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: computeclass-editor-role-binding
    subjects:
    - kind: Group
      name: computeclass-editors@GROUP_DOMAIN
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: computeclass-editor
      apiGroup: rbac.authorization.k8s.io # Required for role references
    

    Sostituisci GROUP_DOMAIN con il nome di dominio del gruppo computeclass-editors.

  6. Crea ClusterRoleBinding:

    kubectl apply -f computeclass-editor-role-binding.yaml
    

Verificare le limitazioni

Le sezioni seguenti mostrano come verificare che le limitazioni configurate nelle sezioni precedenti funzionino come previsto. Se configuri le tue restrizioni nelle policy ValidatingAdmissionPolicies o RBAC, testale creando un carico di lavoro che viola queste policy.

Verifica ValidatingAdmissionPolicy

  1. Salva uno dei seguenti manifest, ognuno dei quali viola una condizione diversa della ValidatingAdmissionPolicy:

    • Deployment che utilizza un selettore di nodi per selezionare una ComputeClass non consentita:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: disallowed-computeclass-deployment
        namespace: computeclass-vap-tutorial
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: forbidden-selector-app
        template:
          metadata:
            labels:
              app: forbidden-selector-app
          spec:
            containers:
            - name: my-app-container
              image: nginx:latest
            # The node selector triggers the policy.
            nodeSelector:
              cloud.google.com/compute-class: COMPUTECLASS_NAME
      
    • Deployment con una tolleranza per una ComputeClass non consentita:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: disallowed-computeclass-deployment-toleration
        namespace: computeclass-vap-tutorial
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: forbidden-selector-app
        template:
          metadata:
            labels:
              app: forbidden-selector-app
          spec:
            containers:
            - name: my-app-container
              image: nginx:latest
            tolerations:
            - key: cloud.google.com/compute-class
              operator: Equal
              value: COMPUTECLASS_NAME
              effect: NoSchedule
      
    • Deployment con una regola di affinità dei nodi per una ComputeClass non consentita:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: disallowed-computeclass-deployment-toleration
        namespace: computeclass-vap-tutorial
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: forbidden-selector-app
        template:
          metadata:
            labels:
              app: forbidden-selector-app
          spec:
            containers:
            - name: my-app-container
              image: nginx:latest
            affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms:
                  - matchExpressions:
                    - key: cloud.google.com/compute-class
                      operator: In
                      values:
                      - COMPUTECLASS_NAME
      
    • Pod con una tolleranza per qualsiasi taint del nodo nel cluster:

      apiVersion: v1
      kind: Pod
      metadata:
        name: disallowed-computeclass-deployment-toleration
        namespace: computeclass-vap-tutorial
      spec:
        containers:
        - name: my-app-container
          image: nginx:latest
        tolerations:
        - operator: Exists
          effect: NoSchedule
      
  2. Crea il workload di test:

    kubectl apply -f PATH_TO_WORKLOAD_MANIFEST
    

    L'output è simile al seguente:

    Error from server (BadRequest): admission webhook "validation-policy.kubernetes.io" denied the request: Pods and Deployments in this namespace cannot request ComputeClass COMPUTECLASS_NAME or use wildcard tolerations.
    

Verifica la configurazione RBAC

Per verificare la configurazione del controllo dell'accesso basato sui ruoli:

  1. Esegui l'autenticazione al cluster utilizzando le credenziali di un utente che sia membro del gruppo computeclass-editors.

  2. Verifica se l'utente può creare una ComputeClass:

    kubectl auth can-i create computeclasses.cloud.google.com \
        --as=MEMBER_USER
    

    Sostituisci MEMBER_USER con l'indirizzo email di un utente membro del gruppo.

    L'output è yes.

  3. Esegui l'autenticazione al cluster utilizzando le credenziali di un utente che non è membro del gruppo computeclass-editors.

  4. Verifica se l'utente può creare una ComputeClass:

    kubectl auth can-i create computeclasses.cloud.google.com \
        --as=NON_MEMBER_USER
    

    Sostituisci NON_MEMBER_USER con l'indirizzo email di un utente che non è membro del gruppo.

    L'output è no.

Se l'output del comando kubectl auth can-i è yes per un utente che non è membro del gruppo, verifica quanto segue:

  • Il gruppo computeclass-editors è membro del gruppo gke-security-groups.
  • L'indirizzo email del gruppo in ClusterRoleBinding è l'indirizzo email esatto del gruppo, ad esempio computeclass-editors@example.com.

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

Se esegui il deployment di ValidatingAdmissionPolicy e delle policy RBAC in questo tutorial in un cluster di produzione, GKE blocca i pod e le richieste API in entrata che violano le policy. Per mantenere attive queste norme, salta questa sezione. Le seguenti sezioni mostrano come eliminare il progetto o le singole risorse se hai seguito questo tutorial in un ambiente di apprendimento o di test.

Elimina il progetto

    Elimina un progetto Google Cloud :

    gcloud projects delete PROJECT_ID

Elimina singole risorse

  1. Elimina ComputeClass che hai creato:

    kubectl delete computeclass access-restriction-class
    
  2. Elimina ValidatingAdmissionPolicy e ValidatingAdmissionPolicyBinding:

    kubectl delete validatingadmissionpolicy restrict-computeclass-usage
    kubectl delete validatingadmissionpolicybinding restrict-computeclass-usage-binding
    
  3. Elimina ClusterRoles e ClusterRoleBindings:

    kubectl delete clusterroles \
        computeclass-editor validatingadmissionpolicy-editor
    kubectl delete clusterrolebindings \
        computeclass-editor-role-binding edit-validatingadmissionpolicies
    
  4. Elimina lo spazio dei nomi di esempio:

    kubectl delete namespace computeclass-vap-tutorial
    

Passaggi successivi