Utilizzo di Workload Identity con AWS

Questo argomento descrive come abilitare l'identità del carico di lavoro per i workload GKE su AWS per controllarne l'accesso alle risorse AWS.

Per informazioni sull'utilizzo di Workload Identity con gli account Google Cloud Identity and Access Management (IAM) per controllare l'accesso alle risorse Google Cloud, consulta Utilizzare Workload Identity con Google Cloud.

Panoramica

Workload Identity utilizza le autorizzazioni AWS IAM per controllare l'accesso alle risorse cloud. Con Workload Identity, puoi assegnare diversi ruoli IAM a ogni carico di lavoro. Questo controllo granulare delle autorizzazioni ti consente di seguire il principio del privilegio minimo. Senza l'identità del carico di lavoro, devi assegnare i ruoli IAM di AWS al tuo GKE sui nodi AWS, concedendo a tutti i workload sul nodo le stesse autorizzazioni del nodo stesso.

Per attivare Workload Identity per il cluster, completa i seguenti passaggi, raggruppati in base ai ruoli amministrativi che li eseguono.

Amministratore del cluster

  1. Crea un bucket Cloud Storage per archiviare i dati di rilevamento OIDC.
  2. Crea un ruolo Identity and Access Management per leggere da quel bucket.
  3. Crea un cluster utente con Workload Identity abilitato.
  4. Crea un webhook sul tuo cluster che applichi le credenziali di Workload Identity ai pod al momento della creazione. Se non vuoi utilizzare l'webhook, puoi impostare manualmente le variabili di ambiente nei pods.
  5. Configura il provider AWS OIDC.
  6. Crea ruoli e criteri IAM AWS.
Amministratore o sviluppatore del cluster
  1. Crea account di servizio Kubernetes e associavi i criteri AWS.
Sviluppatore
  1. Applica le credenziali ai tuoi pod.

Prerequisiti

Per completare i passaggi descritti in questo documento, devi disporre della seguente configurazione:

  • Un servizio di gestione GKE su AWS.
  • Cluster utente che eseguono una versione di Kubernetes superiore a 1.17.9.

  • Le seguenti autorizzazioni e strumenti.

Autorizzazioni

Per creare un cluster con l'identità del carico di lavoro abilitata, devi disporre delle seguenti autorizzazioni:

Google Cloud

  • Crea un bucket Cloud Storage leggibile pubblicamente con accesso uniforme a livello di bucket abilitato.
  • Concedi al servizio management-sa@PROJECT_NAME.iam.gserviceaccount.com le autorizzazioni di lettura/scrittura per il bucket.

AWS

  • Crea un provider OIDC AWS
  • Creazione di ruoli IAM AWS

Strumenti

Ti consigliamo di installare lo strumento jq sulla tua macchina locale.

Creazione del bucket di rilevamento OIDC

Questa sezione è rivolta agli amministratori di cluster.

Il cluster di utenti deve archiviare i dati di rilevamento OIDC in un bucket Cloud Storage accessibile pubblicamente. Il bucket include la configurazione della scoperta OIDC e le chiavi pubbliche. AWS utilizza i contenuti per autenticare le richieste provenienti dai tuoi cluster di utenti.

Il bucket deve avere i seguenti attributi:

Se non hai un bucket con questi attributi, creane uno utilizzando i seguenti comandi gcloud storage:

BUCKET=BUCKET_NAME
gcloud storage buckets create gs://${BUCKET} --uniform-bucket-level-access
gcloud storage buckets add-iam-policy-binding gs://${BUCKET} \
    --member=allUsers --role=roles/storage.objectViewer

Sostituisci BUCKET_NAME con il nome del nuovo bucket.

Concedi le autorizzazioni all'account di servizio di gestione

L'account di servizio Identity and Access Management per il servizio di gestione GKE su AWS deve disporre delle autorizzazioni per leggere e scrivere oggetti in questo bucket.

  1. Concedi le autorizzazioni all'account di servizio di gestione utilizzando il seguente comando.

    MANAGEMENT_SA=management-sa@PROJECT_NAME.iam.gserviceaccount.com
    gcloud storage buckets add-iam-policy-binding gs://${BUCKET} \
        --member=serviceAccount:${MANAGEMENT_SA} \
        --role=roles/storage.admin
    

    Sostituisci PROJECT_NAME con il tuo Google Cloud progetto.

  2. Crea un nuovo ruolo IAM con autorizzazioni per gestire questo bucket. Per creare il ruolo, salva prima la definizione del ruolo in un file, poi crea il ruolo e associalo al tuo account di servizio di gestione.

    Per completare questi passaggi, esegui i seguenti comandi:

    cat << EOF >  anthos-oidc-role.yaml
    title: anthosAwsOidcStorageAdmin
    description: permissions to manage the OIDC buckets
    stage: GA
    includedPermissions:
    - storage.buckets.get
    EOF
    
    gcloud iam roles create anthosAwsOidcStorageAdmin --project=PROJECT_NAME \
      --file=anthos-oidc-role.yaml
    
    gcloud projects add-iam-policy-binding \
      PROJECT_NAME \
      --member=serviceAccount:${MANAGEMENT_SA} \
      --role=projects/PROJECT_NAME/roles/anthosAwsOidcStorageAdmin
    

    Sostituisci PROJECT_NAME con il tuo Google Cloud progetto.

    Google Cloud CLI conferma che l'associazione dei criteri è stata creata.

Creazione di un cluster utente

Questa sezione è rivolta agli amministratori di cluster.

Creare un cluster utente con Workload Identity abilitato

Crea un cluster utente contenente i dettagli del bucket di discovery OIDC. Puoi impostare queste informazioni nel campo spec.controlPlane.workloadIdentity.oidcDiscoveryGCSBucket di AWSCluster.

In questo esempio, crei un cluster manualmente dalle CRD AWSCluster e AWSNodePool.

  1. Passa alla directory con la configurazione di GKE su AWS. Hai creato questa directory durante la installazione del servizio di gestione.

    cd anthos-aws

  2. Dalla directory anthos-aws, utilizza anthos-gke per cambiare contesto e passare al servizio di gestione.

    cd anthos-aws
    anthos-gke aws management get-credentials

  3. Apri un editor di testo e copia la seguente definizione di AWSCluster in un file chiamato custom-cluster.yaml.

    apiVersion: multicloud.cluster.gke.io/v1
    kind: AWSCluster
    metadata:
      name: CLUSTER_NAME
    spec:
      region: AWS_REGION
      networking:
        vpcID: VPC_ID
        podAddressCIDRBlocks: POD_ADDRESS_CIDR_BLOCKS
        serviceAddressCIDRBlocks: SERVICE_ADDRESS_CIDR_BLOCKS
        ServiceLoadBalancerSubnetIDs: SERVICE_LOAD_BALANCER_SUBNETS
      controlPlane:
        version:  CLUSTER_VERSION # Latest version is 1.25.5-gke.2100
        instanceType: AWS_INSTANCE_TYPE
        keyName: SSH_KEY_NAME
        subnetIDs:
        - CONTROL_PLANE_SUBNET_IDS
        securityGroupIDs:
        - CONTROL_PLANE_SECURITY_GROUPS
        iamInstanceProfile: CONTROL_PLANE_IAM_ROLE
        rootVolume:
          sizeGiB: ROOT_VOLUME_SIZE
          volumeType: ROOT_VOLUME_TYPE # Optional
          iops: ROOT_VOLUME_IOPS # Optional
          kmsKeyARN: ROOT_VOLUME_KEY # Optional
        etcd:
          mainVolume:
            sizeGiB: ETCD_VOLUME_SIZE
            volumeType: ETCD_VOLUME_TYPE # Optional
            iops: ETCD_VOLUME_IOPS # Optional
            kmsKeyARN: ETCD_VOLUME_KEY # Optional
        databaseEncryption:
          kmsKeyARN: ARN_OF_KMS_KEY
        hub: # Optional
          membershipName: ANTHOS_CONNECT_NAME
        cloudOperations: # Optional
          projectID: YOUR_PROJECT
          location: GCP_REGION
          enableLogging: ENABLE_LOGGING
          enableMonitoring: ENABLE_MONITORING
        workloadIdentity: # Optional
          oidcDiscoveryGCSBucket: WORKLOAD_IDENTITY_BUCKET
    

    Sostituisci quanto segue:

    • CLUSTER_NAME: il nome del tuo cluster.
    • AWS_REGION: la regione AWS in cui viene eseguito il cluster.

    • VPC_ID: l'ID della VPC in cui viene eseguito il cluster.

    • POD_ADDRESS_CIDR_BLOCKS: l'intervallo di indirizzi IPv4 utilizzati dai pod del cluster. Al momento è supportato un solo intervallo. L'intervallo non deve sovrapporsi ad alcuna subnet raggiungibile dalla tua rete. È possibile utilizzare lo stesso intervallo in più oggetti AWSCluster diversi. Ad esempio, 10.2.0.0/16.

    • SERVICE_ADDRESS_CIDR_BLOCKS: l'intervallo di indirizzi IPv4 utilizzati dai servizi del cluster. Al momento è supportato un solo intervallo. L'intervallo non deve sovrapporsi ad alcuna subnet raggiungibile dalla tua rete. È possibile utilizzare lo stesso intervallo in più oggetti AWSCluster. Ad esempio, 10.1.0.0/16.

    • SERVICE_LOAD_BALANCER_SUBNETS: gli ID subnet in cui GKE su AWS può creare bilanciatori del carico pubblici o privati.

    • CLUSTER_VERSION: una versione di Kubernetes supportata da GKE su AWS. La versione più recente è 1.25.5-gke.2100.

    • AWS_INSTANCE_TYPE: un tipo di istanza EC2 supportato.

    • SSH_KEY_NAME: una coppia di chiavi AWS EC2.

    • CONTROL_PLANE_SUBNET_IDS: gli ID subnet nelle AZ in cui vengono eseguite le istanze del piano di controllo.

    • CONTROL_PLANE_SECURITY_GROUPS: un securityGroupID creato durante l'installazione del servizio di gestione. Puoi personalizzarlo aggiungendo eventuali ID gruppo di sicurezza richiesti per la connessione al piano di controllo.

    • CONTROL_PLANE_IAM_PROFILE: nome del profilo dell'istanza AWS EC2 assegnato alle repliche del piano di controllo.

    • ROOT_VOLUME_SIZE: le dimensioni, in gibibyte (GiB), dei volumi radice del piano di controllo.

    • ROOT_VOLUME_TYPE con il tipo di volume EBS. Ad esempio: gp3.

    • ROOT_VOLUME_IOPS con la quantità di operazioni di I/O sottoposte a provisioning al secondo (IOPS) per il volume. Valido solo quando volumeType è GP3. Per ulteriori informazioni, consulta Volumi SSD per uso generico (gp3).

    • ROOT_VOLUME_KEY con il nome della risorsa Amazon della chiave AWS KMS che cripta i volumi principali delle istanze del piano di controllo.

    • ETCD_VOLUME_SIZE: la dimensione dei volumi utilizzati da etcd.

    • ETCD_VOLUME_TYPE con il tipo di volume EBS. Ad esempio: gp3.

    • ETCD_VOLUME_IOPS con la quantità di operazioni di I/O sottoposte a provisioning al secondo (IOPS) per il volume. Valido solo quando volumeType è gp3. Per ulteriori informazioni, consulta Volumi SSD per uso generico (gp3).

    • ETCD_VOLUME_KEY con l'Amazon Resource Name della chiave AWS KMS che cripta i volumi di dati etcd del piano di controllo.

    • ARN_OF_KMS_KEY: la chiave KMS AWS utilizzata per criptare i secret del cluster.

    • ANTHOS_CONNECT_NAME: il nome dell'abbonamento Connect utilizzato per registrare il cluster. Il nome dell'abbonamento deve essere univoco. Ad esempio, projects/YOUR_PROJECT/locations/global/memberships/CLUSTER_NAME, dove YOUR_PROJECT è il tuo Google Cloud progetto e CLUSTER_NAME è un nome univoco nel progetto. Questo campo è facoltativo.

    • YOUR_PROJECT: il tuo ID progetto.

    • GCP_REGION: la Google Cloud regione in cui vuoi archiviare i log. Scegli una regione vicina alla regione AWS. Per saperne di più, consulta Località globali - Regioni e zone ad esempio us-central1.

    • ENABLE_LOGGING: true o false, a seconda che Cloud Logging sia abilitato sui nodi del piano di controllo.

    • ENABLE_MONITORING: true o false, a seconda che Cloud Monitoring sia abilitato sui nodi del piano di controllo.

    • WORKLOAD_IDENTITY_BUCKET: il nome del bucket Cloud Storage contenente le informazioni di rilevamento della tua identità del carico di lavoro. Questo campo è facoltativo.

  4. Crea uno o più AWSNodePools per il tuo cluster. Apri un editor di testo e copia la seguente definizione di AWSCluster in un file chiamato custom-nodepools.yaml.

    apiVersion: multicloud.cluster.gke.io/v1
    kind: AWSNodePool
    metadata:
      name: NODE_POOL_NAME
    spec:
      clusterName: AWSCLUSTER_NAME
      version:  CLUSTER_VERSION # latest version is 1.25.5-gke.2100
      region: AWS_REGION
      subnetID: AWS_SUBNET_ID
      minNodeCount: MINIMUM_NODE_COUNT
      maxNodeCount: MAXIMUM_NODE_COUNT
      maxPodsPerNode: MAXIMUM_PODS_PER_NODE_COUNT
      instanceType: AWS_NODE_TYPE
      keyName: KMS_KEY_PAIR_NAME
      iamInstanceProfile: NODE_IAM_PROFILE
      proxySecretName: PROXY_SECRET_NAME
      rootVolume:
        sizeGiB: ROOT_VOLUME_SIZE
        volumeType: VOLUME_TYPE # Optional
        iops: IOPS # Optional
        kmsKeyARN: NODE_VOLUME_KEY # Optional 
    

    Sostituisci quanto segue:

    • NODE_POOL_NAME: un nome univoco per il pool di nodi AWS.
    • AWSCLUSTER_NAME: il nome del tuo AWSCluster. Ad esempio, staging-cluster.
    • CLUSTER_VERSION: una versione di GKE su AWS Kubernetes supportata.
    • AWS_REGION: la stessa regione AWS del tuo AWSCluster.
    • AWS_SUBNET_ID: una subnet AWS nella stessa regione del tuo AWSCluster.
    • MINIMUM_NODE_COUNT: il numero minimo di nodi nel pool di nodi. Per ulteriori informazioni, consulta Eseguire il ridimensionamento dei cluster di utenti.
    • MAXIMUM_NODE_COUNT: il numero massimo di nodi nel pool di nodi.
    • MAXIMUM_PODS_PER_NODE_COUNT: il numero massimo di pod che GKE su AWS può allocare a un nodo.
    • AWS_NODE_TYPE: un tipo di istanza AWS EC2.
    • KMS_KEY_PAIR_NAME: la coppia di chiavi AWS KMS assegnata a ogni worker del pool di nodi.
    • NODE_IAM_PROFILE: il nome del profilo dell'istanza AWS EC2 assegnato ai nodi del pool.
    • ROOT_VOLUME_SIZE: le dimensioni, in gibibyte (GiB), dei volumi radice del piano di controllo.
    • VOLUME_TYPE: il tipo di volume EBS AWS del nodo. Ad esempio: gp3.
    • IOPS: la quantità di operazioni di I/O al secondo (IOPS) messe a provisioning per i volumi. Valido solo quando volumeType è gp3.
    • NODE_VOLUME_KEY: l'ARN della chiave KMS AWS utilizzata per criptare il volume. Per saperne di più, consulta Utilizzare una CMK gestita dal cliente per criptare i volumi.
  5. Applica i manifest al servizio di gestione.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f custom-cluster.yaml
    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f custom-nodepools.yaml
    

Crea un file kubeconfig

Durante l'avvio del cluster utente, puoi creare un contesto kubeconfig per il nuovo cluster utente. Utilizzi il contesto per autenticarti in un cluster di utenti o di gestione.

  1. Utilizza anthos-gke aws clusters get-credentials per generare un kubeconfig per il tuo cluster di utenti in ~/.kube/config.

    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    

    Sostituisci CLUSTER_NAME con il nome del cluster. Ad esempio, cluster-0.

  2. Utilizza kubectl per autenticarti nel nuovo cluster di utenti.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl cluster-info
    

    Se il cluster è pronto, l'output include gli URL dei componenti Kubernetes al suo interno.

Visualizzazione dello stato del cluster

Il servizio di gestione esegue il provisioning delle risorse AWS quando applichi un AWSCluster o un AWSNodePool.

  1. Dalla directory anthos-aws, utilizza anthos-gke per cambiare contesto e passare al servizio di gestione.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Per elencare i cluster, utilizza kubectl get AWSClusters.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get AWSClusters
    

    L'output include il nome, lo stato, la versione, l'età e l'endpoint di ogni cluster.

    Ad esempio, il seguente output include un solo AWSCluster denominato cluster-0:

    NAME        STATE          AGE     VERSION         ENDPOINT
    cluster-0   Provisioning   2m41s   1.25.5-gke.2100   gke-xyz.elb.us-east-1.amazonaws.com
    

Visualizzare gli eventi del cluster

Per visualizzare gli eventi Kubernetes recenti dal tuo cluster utente, utilizza kubectl get events.

  1. Dalla directory anthos-aws, utilizza anthos-gke per cambiare contesto e passare al servizio di gestione.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Esegui kubectl get events.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get events
    

L'output include informazioni, avvisi ed errori relativi al servizio di gestione.

Creazione del webhook dell'identità del workload

Questa sezione è rivolta agli amministratori di cluster.

Per fornire le credenziali di Workload Identity ai tuoi carichi di lavoro senza alcuna configurazione aggiuntiva, puoi facoltativamente creare un webhook nei tuoi cluster utente. Questo webhook intercetta le richieste di creazione dei pod e rende disponibili le seguenti informazioni IAM di AWS come variabili di ambiente per il pod:

  • AWS_ROLE_ARN: l'Amazon Resource Name (ARN) del ruolo IAM
  • aws-iam-token: il token scambiato per le credenziali AWS IAM
  • AWS_WEB_IDENTITY_TOKEN_FILE: il percorso in cui è archiviato il token

Con queste variabili, i tuoi workload possono chiamare lo strumento a riga di comando AWS o l'SDK può accedere alle risorse concesse al ruolo AWS.

La creazione dell'webhook è facoltativa. Se decidi di non creare l'webhook, devi impostare le variabili di ambiente elencate in precedenza nel pod. Per informazioni su come non utilizzare un webhook, consulta Applicare le credenziali senza il webhook.

Crea file YAML per il webhook

Per eseguire il deployment del webhook:

  1. Dalla directory anthos-aws, utilizza anthos-gke per cambiare contesto e passare al servizio di gestione.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Ottieni il nome del cluster utente con kubectl:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get awscluster
    

    kubectl elenca tutti i cluster di utenti. Scegli il cluster utente che hai creato con Workload Identity abilitato.

  3. Imposta il nome del cluster in una variabile di ambiente.

    CLUSTER_NAME=CLUSTER_NAME
    

    Sostituisci CLUSTER_NAME con il nome del cluster. Ad esempio, cluster-0.

  4. Imposta le variabili di ambiente per l'immagine del pod e lo spazio dei nomi dell'identità del carico di lavoro.

    IDENTITY_IMAGE=amazon/amazon-eks-pod-identity-webhook:ed8c41f
    
    WEBHOOK_NAMESPACE=workload-identity-webhook
    
  5. Genera il manifest YAML del webhook in un file denominato aws-webhook.yaml svolgendo i seguenti passaggi:

    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials ${CLUSTER_NAME}
    
    CLUSTER_CA=$(env HTTPS_PROXY=http://localhost:8118 \
      kubectl config view --raw -o json  | jq -r '.clusters[] | select(.name == "'$(kubectl config current-context)'") | .cluster."certificate-authority-data"')
    
    cat << EOF > aws-webhook.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    rules:
      - apiGroups: ['']
        resources: ['secrets']
        verbs: ['create']
      - apiGroups: ['']
        resources: ['secrets']
        verbs: ['get', 'update', 'patch']
        resourceNames:
          - pod-identity-webhook
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: pod-identity-webhook
    subjects:
      - kind: ServiceAccount
        name: pod-identity-webhook
        namespace: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: pod-identity-webhook
    rules:
      - apiGroups: ['']
        resources: ['serviceaccounts']
        verbs: ['get', 'watch',  'list']
      - apiGroups:  ['certificates.k8s.io']
        resources: ['certificatesigningrequests']
        verbs:  ['create', 'get', 'list', 'watch']
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: pod-identity-webhook
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: pod-identity-webhook
    subjects:
      - kind: ServiceAccount
        name: pod-identity-webhook
        namespace: ${WEBHOOK_NAMESPACE}
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: pod-identity-webhook
      template:
        metadata:
          labels:
            app: pod-identity-webhook
        spec:
          serviceAccountName: pod-identity-webhook
          containers:
            - name: pod-identity-webhook
              image: ${IDENTITY_IMAGE}
              imagePullPolicy: Always
              command:
                - /webhook
                - --in-cluster
                - --namespace=${WEBHOOK_NAMESPACE}
                - --service-name=pod-identity-webhook
                - --tls-secret=pod-identity-webhook
                - --annotation-prefix=eks.amazonaws.com
                - --token-audience=sts.amazonaws.com
                - --logtostderr
              volumeMounts:
                - name: webhook-certs
                  mountPath: /var/run/app/certs
                  readOnly: false
          volumes:
            - name: webhook-certs
              emptyDir: {}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
      annotations:
        prometheus.io/port: '443'
        prometheus.io/scheme: https
        prometheus.io/scrape: 'true'
    spec:
      ports:
        - port: 443
          targetPort: 443
      selector:
        app: pod-identity-webhook
    ---
    apiVersion: admissionregistration.k8s.io/v1
    kind: MutatingWebhookConfiguration
    metadata:
      name: pod-identity-webhook
      namespace: ${WEBHOOK_NAMESPACE}
    webhooks:
      - name: pod-identity-webhook.amazonaws.com
        failurePolicy: Ignore
        sideEffects: 'None'
        admissionReviewVersions: ['v1beta1']
        clientConfig:
          service:
            name: pod-identity-webhook
            namespace: ${WEBHOOK_NAMESPACE}
            path: /mutate
          caBundle: ${CLUSTER_CA}
        rules:
          - operations: ['CREATE']
            apiGroups: ['']
            apiVersions: ['v1']
            resources: ['pods']
    EOF
    

    I contenuti di aws-webhook.yaml sono pronti per essere applicati al tuo cluster.

Applica l'webhook al tuo cluster utente

Per applicare l'webhook al cluster di utenti, svolgi i seguenti passaggi.

  1. Applica il file aws-webhook.yaml al tuo cluster utente.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f aws-webhook.yaml
    
  2. Quando applichi il manifest, il pod webhook genera richieste di firma del certificato (CSR) di Kubernetes. Approva tutte le richieste di system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook con kubectl certificate approve.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl certificate approve $(env HTTPS_PROXY=http://localhost:8118 \ &&\
      kubectl get csr -o \
        jsonpath="{.items[?(@.spec.username==\"system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook\")].metadata.name}")
    
  3. Verifica che non siano presenti CSR non approvate.

    Utilizza kubectl get csr per verificare che tutte le richieste di servizio del richiedente system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook siano approvate:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get csr
    

    Risposta:

    NAME        AGE   REQUESTOR                                            CONDITION
    csr-mxrt8   10s   system:serviceaccount:default:pod-identity-webhook   Approved,Issued
    

Configurazione del provider AWS OIDC

Questa sezione è rivolta agli amministratori di cluster.

Per creare un provider OIDC su AWS, AWS richiede un'autorità di certificazione (CA) intermedia o la impronta del certificato del server. Le credenziali di rilevamento OIDC sono archiviate su storage.googleapis.com, con un certificato firmato da un'autorità di certificazione intermedia denominata GTS CA 1C3. L'impronta SHA-1 della CA intermedia GTS CA 1C3 è 08745487E891C19E3078C1F2A07E452950EF36F6.

Per registrare il bucket di rilevamento OIDC come provider OIDC con AWS, svolgi i seguenti passaggi:

  1. Dalla directory anthos-aws, utilizza anthos-gke per cambiare contesto e passare al servizio di gestione.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Salva l'URL emittente OIDC, il percorso dell'host emittente e l'impronta di Cloud Storage nelle variabili di ambiente.

    ISSUER_URL=$(env HTTPS_PROXY=http://localhost:8118 \
      kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.workloadIdentityInfo.issuerURL}')
    ISSUER_HOSTPATH=${ISSUER_URL#"https://"}
    CA_THUMBPRINT=08745487E891C19E3078C1F2A07E452950EF36F6
    
  3. Utilizza lo strumento a riga di comando aws per creare un provider OIDC su AWS.

    aws iam create-open-id-connect-provider \
      --url ${ISSUER_URL} \
      --thumbprint-list ${CA_THUMBPRINT} \
      --client-id-list sts.amazonaws.com
    

Aggiorna la impronta

Se Google ruota la CA per storage.googleapis.com, esegui i seguenti comandi:

  1. Copia l'impronta del certificato aggiornato, 08745487E891C19E3078C1F2A07E452950EF36F6.

  2. Segui le istruzioni per il comando aws iam update-open-id-connect-provider-thumbprint. Utilizza storage.googleapis.com come nome host di destinazione e 08745487E891C19E3078C1F2A07E452950EF36F6 come impronta.

Creazione di ruoli e criteri AWS IAM

Questa sezione è rivolta agli amministratori di cluster.

Crea un ruolo AWS IAM da associare a un account di servizio Kubernetes. Il ruolo IAM dispone delle autorizzazioni per sts:AssumeRoleWithWebIdentity.

Per creare il ruolo, svolgi i seguenti passaggi:

  1. Trova o crea un criterio AWS IAM che conceda le autorizzazioni necessarie per i tuoi workload.

    Devi disporre del nome della risorsa Amazon (ARN) del criterio AWS IAM. Ad esempio, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.

  2. Imposta le variabili di ambiente con le informazioni di autenticazione.

    KSA_NAME=KUBERNETES_SERVICE_ACCOUNT
    WORKLOAD_NAMESPACE=WORKLOAD_IDENTITY_NAMESPACE
    
    AWS_ROLE_NAME=AWS_ROLE_NAME
    AWS_POLICY=EXISTING_AWS_POLICY
    

    Sostituisci quanto segue:

    • KUBERNETES_SERVICE_ACCOUNT: il nome del nuovo account di servizio Kubernetes
    • WORKLOAD_IDENTITY_NAMESPACE: il nome dello spazio dei nomi in cui vengono eseguiti i carichi di lavoro
    • AWS_ROLE_NAME: il nome di un nuovo ruolo AWS per i tuoi carichi di lavoro
    • EXISTING_AWS_POLICY: l'Amazon Resource Name (ARN) di un criterio IAM AWS esistente, ad esempio arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.
  3. Dalla directory anthos-aws, utilizza anthos-gke per cambiare contesto e passare al servizio di gestione.

    cd anthos-aws
    anthos-gke aws management get-credentials

  4. Crea un criterio AWS IAM che consenta al tuo cluster di utenti di assumere credenziali di sicurezza temporanee con il servizio token di sicurezza AWS:

    CLUSTER_ID=$(env HTTPS_PROXY=http://localhost:8118 \
      kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.clusterID}')
    
    # Get the ID Provider ARN
    PROVIDER_ARN=$(aws iam list-open-id-connect-providers  \
    | jq '.OpenIDConnectProviderList' \
    | jq ".[] | select(.Arn |  contains(\"${CLUSTER_ID}\"))"   \
    | jq  '.Arn' | tr -d '"')
    
    # Create AWS role and policy
    cat > irp-trust-policy.json << EOF
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "${PROVIDER_ARN}"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "${ISSUER_HOSTPATH}:sub": "system:serviceaccount:${WORKLOAD_NAMESPACE}:${KSA_NAME}"
            }
          }
        }
      ]
    }
    EOF
    
  5. Per creare un ruolo AWS IAM con questo criterio e associare il criterio esistente al ruolo, esegui i seguenti comandi:

    aws iam create-role \
      --role-name ${AWS_ROLE_NAME} \
      --assume-role-policy-document file://irp-trust-policy.json
    aws iam update-assume-role-policy \
      --role-name ${AWS_ROLE_NAME} \
      --policy-document file://irp-trust-policy.json
    aws iam attach-role-policy \
      --role-name ${AWS_ROLE_NAME} \
      --policy-arn ${AWS_POLICY}
    

    Lo strumento a riga di comando aws conferma che il criterio è associato al tuo ruolo.

Creazione di account di servizio Kubernetes per i workload

Questa sezione è rivolta a sviluppatori o amministratori di cluster.

Per creare account di servizio Kubernetes associati al ruolo AWS IAM specificato in precedenza, svolgi i seguenti passaggi:

  1. Dalla directory anthos-aws, utilizza anthos-gke per cambiare contesto e passare al cluster di utenti.

    cd anthos-aws
    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    Sostituisci CLUSTER_NAME con il nome del cluster di utenti.

  2. Crea l'account di servizio Kubernetes eseguendo i seguenti comandi:

    S3_ROLE_ARN=$(aws iam get-role \
      --role-name AWS_ROLE_NAME \
      --query Role.Arn --output text)
    
    cat << EOF  > k8s-service-account.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ${KSA_NAME}
      namespace: WORKLOAD_IDENTITY_NAMESPACE
    EOF
    
    env HTTPS_PROXY=http://localhost:8118 \
    kubectl apply -f k8s-service-account.yaml
    
    env HTTPS_PROXY=http://localhost:8118 \
    kubectl annotate sa --namespace ${WORKLOAD_NAMESPACE} ${KSA_NAME} eks.amazonaws.com/role-arn=${S3_ROLE_ARN}
    

    Sostituisci quanto segue:

    • AWS_ROLE_NAME: il nome del ruolo AWS IAM da applicare ai carichi di lavoro
    • WORKLOAD_IDENTITY_NAMESPACE: il nome dello spazio dei nomi in cui vengono eseguiti i carichi di lavoro

Applicazione delle credenziali ai pod

Questa sezione è rivolta agli sviluppatori.

Questa sezione presuppone che tu abbia disegnato il webhook Workload Identity. Se non hai eseguito il deployment del webhook, vai a Applicare le credenziali senza il webhook.

Applica le credenziali con l'webhook

Questa sezione descrive come configurare i pod in modo che leggano le credenziali messe a disposizione dall'webhook.

Aggiungi il account di servizio al pod

Per utilizzare l'identità del carico di lavoro con un carico di lavoro, aggiungi l'account di servizio Kubernetes ai seguenti campi:

  • Per un deployment: spec.template.spec.serviceAccountName
  • Per un pod: spec.serviceAccount

Il seguente manifest del pod avvia un'immagine CentOS di base e contiene il campo spec.serviceAccount.

apiVersion: v1
kind: Pod
metadata:
  name: sample-centos-pod
  namespace: WORKLOAD_IDENTITY_NAMESPACE
spec:
  containers:
  - command:
    - /bin/bash
    - -ec
    - while :; do echo '.'; sleep 500 ; done
    image: amazon/aws-cli
    name: centos
  serviceAccount: KUBERNETES_SERVICE_ACCOUNT

Sostituisci quanto segue:

  • WORKLOAD_IDENTITY_NAMESPACE: il nome dello spazio dei nomi in cui vengono eseguiti i carichi di lavoro
  • KUBERNETES_SERVICE_ACCOUNT: il nome dell'account di servizio Kubernetes che hai creato in precedenza

Controlla se i pod hanno le variabili di ambiente impostate

Per verificare se i pod hanno le variabili di ambiente impostate, esegui il seguente comando per ottenere le informazioni del pod:

kubectl get pod --namespace WORKLOAD_IDENTITY_NAMESPACE POD_NAME -o yaml

Sostituisci quanto segue:

  • WORKLOAD_IDENTITY_NAMESPACE: il nome dello spazio dei nomi in cui vengono eseguiti i carichi di lavoro
  • POD_NAME: il nome del pod da controllare

L'output contiene i valori variabile di ambiente in spec.containers.command.env e il punto di montaggio per il token IAM AWS. Di seguito è riportato un esempio di manifest di pod.

apiVersion: v1
kind: Pod
metadata:
  ...
spec:
  containers:
  - command:
    - /bin/bash
    - -ec
    - while :; do echo '.'; sleep 500 ; done
    env:
    - name: AWS_ROLE_ARN
      value: arn:aws:iam::1234567890:role/my-example-workload-role-1
    - name: AWS_WEB_IDENTITY_TOKEN_FILE
      value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
    image: amazon/aws-cli
    imagePullPolicy: IfNotPresent
    name: centos
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: my-k8s-serviceaccount-token-d4nz4
      readOnly: true
    - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
      name: aws-iam-token
      readOnly: true
  serviceAccount: my-k8s-serviceaccount
  serviceAccountName: my-k8s-serviceaccount
  volumes:
  - name: aws-iam-token
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          audience: sts.amazonaws.com
          expirationSeconds: 86400
          path: token
  - name: my-k8s-serviceaccount-token-d4nz4
    secret:
      defaultMode: 420
      secretName: my-k8s-serviceaccount-token-d4nz4
   ...
status:
  ...

Applicare le credenziali senza il webhook

Se non esegui il deployment del webhook Workload Identity, devi eseguire le seguenti operazioni:

Crea un pod con le credenziali per l'identità del workload

Per creare un pod che includa le credenziali necessarie per l'identità del carico di lavoro:

  1. Copia il seguente manifest del pod in un file denominato sample-pod-no-webhook.yaml. La configurazione avvia un'immagine CentOS di base con le credenziali necessarie.

    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-centos-pod-no-webhook
      namespace: WORKLOAD_IDENTITY_NAMESPACE
    spec:
      containers:
      - command:
        - /bin/bash
        - -ec
        - while :; do echo '.'; sleep 500 ; done
        image: centos:7
        name: centos
        env:
        - name: AWS_ROLE_ARN
          value: IAM_ROLE_ARN
        - name: AWS_WEB_IDENTITY_TOKEN_FILE
          value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
        volumeMounts:
        - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
          name: aws-iam-token
          readOnly: true
      volumes:
      - name: aws-iam-token
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              audience: sts.amazonaws.com
              expirationSeconds: 86400
              path: token
      serviceAccount: KUBERNETES_SERVICE_ACCOUNT
    

    Sostituisci quanto segue:

    • WORKLOAD_IDENTITY_NAMESPACE: il nome dello spazio dei nomi in cui vengono eseguiti i carichi di lavoro.
    • IAM_ROLE_ARN: l'ARN del ruolo IAM concesso al pod. Ad esempio, arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess.
    • KUBERNETES_SERVICE_ACCOUNT: il nome dell'account di servizio Kubernetes che hai creato in precedenza.
  2. Applica il manifest del pod al cluster utilizzando kubectl:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f sample-pod-no-webhook.yaml
    

Controlla se i pod possono accedere alle risorse AWS

La procedura seguente descrive come verificare se il pod ha ricevuto le credenziali necessarie per il funzionamento dell'identità del carico di lavoro.

Per completare i passaggi, devi disporre di quanto segue:

  • bash accesso shell al contenitore; la maggior parte delle immagini di produzione non ha un shell disponibile. L'esempio seguente mostra come utilizzare il pod specificato nella sezione precedente per accedere ad AWS S3.

  • Il pod deve avere accesso in uscita a internet per scaricare l'interfaccia a riga di comando AWS.

Per verificare se il pod può accedere a un bucket S3, svolgi i seguenti passaggi:

  1. Utilizza kubectl exec per avviare una shell bash interattiva sul podsample-centos-pod-no-webhook:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl exec -it --namespace ${WORKLOAD_NAMESPACE} sample-centos-pod-no-webhook -- bash
    

    Il terminale apre la shell bash sul pod.

  2. Controlla le autorizzazioni e le credenziali AWS IAM utilizzando lo strumento aws:

    aws sts assume-role-with-web-identity \
     --role-arn ${AWS_ROLE_ARN} \
     --role-session-name mh9test \
     --web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token \
     --duration-seconds 1000
    

    Lo strumento aws stampa informazioni sulle credenziali simili alle seguenti:

    {
        "AssumedRoleUser": {
            "AssumedRoleId": "AROAR2ZZZLEXVSDCDJ37N:mh9test",
            "Arn": "arn:aws:sts::126285863215:assumed-role/my-example-workload-role-1/mh9test"
        },
        "Audience": "sts.amazonaws.com",
        "Provider": "arn:aws:iam::126285863215:oidc-provider/storage.googleapis.com/gke-issuer-cec6c353",
        "SubjectFromWebIdentityToken": "system:serviceaccount:default:my-s3-reader-ksa",
        "Credentials": {
            "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
            "SessionToken": "MY_TOKEN",
            "Expiration": "2020-08-14T22:46:36Z",
            "AccessKeyId": "AKIAIOSFODNN7EXAMPLE"
        }
    }
    

    Se viene visualizzato il seguente messaggio, verifica che il bucket sia accessibile pubblicamente: An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Couldn't retrieve verification key from your identity provider, please reference AssumeRoleWithWebIdentity documentation for requirements

Eseguire l'upgrade del webhook

Se hai creato un cluster Kubernetes 1.18 o precedente con Workload Identity abilitato e la versione del webhook Workload Identity release-0.2.2-gke.0, devi eseguire l'upgrade del webhook prima di eseguire l'upgrade a Kubernetes 1.19.

Per eseguire l'upgrade del webhook:

  1. Verifica che l'webhook sia installato eseguendo i seguenti comandi:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get MutatingWebhookConfiguration
    

    Se nel cluster è stato implementato l'webhook, l'output include quanto segue:

    NAME                   WEBHOOKS   AGE
    pod-identity-webhook   1          11m
    

    Se il webhook non è dipiegato nel cluster, puoi saltare i passaggi riportati di seguito.

  2. Se hai salvato il file aws-webhook.yaml, puoi eliminare il manifest. Se non hai questo file a disposizione, puoi eliminare manualmente i componenti del webhook. Scegli tra i file o i componenti di seguito.

    File

    Se hai ancora il file aws-webhook.yaml, esegui il seguente comando per eliminare l'webhook:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl delete -f aws-webhook.yaml
    

    Componenti

    Per eliminare manualmente i componenti del webhook, esegui i seguenti comandi:

    env HTTPS_PROXY=http://localhost:8118 \
       kubectl delete namespace WEBHOOK_NAMESPACE
    env HTTPS_PROXY=http://localhost:8118 \
       kubectl delete clusterrole pod-identity-webhook
    env HTTPS_PROXY=http://localhost:8118 \
       kubectl delete clusterrolebinding pod-identity-webhook
    env HTTPS_PROXY=http://localhost:8118 \
       kubectl delete mutatingwebhookconfiguration pod-identity-webhook
    

    Sostituisci WEBHOOK_NAMESPACE con lo spazio dei nomi in cui hai installato il webhook di Workload Identity. Ad esempio, workload-identity-webhook.

  3. Controlla se ci sono richieste di firma del certificato (CSR) rimanenti eseguendo questo comando:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get csr |grep pod-identity-webhook
    

    Se l'output è vuoto, vai al passaggio successivo. Se sono presenti altri RP, il comando kubectl ne elenca quelli esistenti. Per rimuovere i CSR, esegui il seguente comando:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl delete csr $(kubectl get csr -o \
      jsonpath="{.items[?(@.spec.username==\"system:serviceaccount:WEBHOOK_NAMESPACE:pod-identity-webhook\")].metadata.name}")
    

    Sostituisci WEBHOOK_NAMESPACE con lo spazio dei nomi in cui hai installato il webhook di Workload Identity. Ad esempio, workload-identity-webhook.

  4. Segui i passaggi descritti in Creare l'webhook per eseguire il deployment della nuova versione dell'webhook.

    Dopo aver eseguito il deployment della nuova versione dell'webhook, devi riavviare i pod che lo utilizzano. Puoi riavviare i pod eseguendo l'upgrade di un cluster utente.

Pulizia

Questa sezione spiega come rimuovere le risorse create in precedenza in questo documento.

Ripulire l'account di servizio e il relativo ruolo IAM associato

Per eliminare l'account di servizio e il relativo ruolo IAM associato, svolgi i seguenti passaggi:

  1. Ripulisci l'account di servizio:

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl delete sa KUBERNETES_SERVICE_ACCOUNT --namespace WORKLOAD_IDENTITY_NAMESPACE
    

    Sostituisci quanto segue:

    • KUBERNETES_SERVICE_ACCOUNT: il nome del nuovo account di servizio Kubernetes
    • WORKLOAD_IDENTITY_NAMESPACE: il nome dello spazio dei nomi in cui vengono eseguiti i carichi di lavoro
  2. Ripulisci il ruolo IAM AWS. Scegli una delle seguenti opzioni:

    • Elimina il ruolo IAM AWS con la console AWS.

    • Elimina il ruolo con lo strumento a riga di comando AWS utilizzando i seguenti comandi:

      aws iam  detach-role-policy \
        --role-name=${AWS_ROLE_NAME} \
        --policy-arn=${AWS_POLICY}
      aws iam delete-role --role-name=${AWS_ROLE_NAME}
      

Eliminare il cluster utente

Per eliminare il cluster di utenti, segui la procedura descritta in Disinstallazione di GKE su AWS.

Ripulire il provider OIDC AWS

Dopo aver eliminato il cluster di utenti, annulla la registrazione ed elimina il provider OIDC su AWS utilizzando il seguente comando a riga di comando bash o la console AWS.

  1. Dalla directory anthos-aws, utilizza anthos-gke per cambiare contesto e passare al servizio di gestione.

    cd anthos-aws
    anthos-gke aws management get-credentials

  2. Elimina il ruolo con lo strumento a riga di comando AWS con i seguenti comandi:

    CLUSTER_ID=$(env HTTPS_PROXY=http://localhost:8118 \
      kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.clusterID}')
    
    PROVIDER_ARN=$(aws iam list-open-id-connect-providers  \
    | jq '.OpenIDConnectProviderList' \
    | jq ".[] | select(.Arn |  contains(\"${CLUSTER_ID}\"))"   \
    | jq  '.Arn' | tr -d '"')
    
    aws iam delete-open-id-connect-provider \
      --open-id-connect-provider-arn=${PROVIDER_ARN}
    

    Riceverai una conferma dell'eliminazione del provider AWS OIDC.

Passaggi successivi