Configura la sicurezza del servizio con Envoy e le API di bilanciamento del carico (legacy)

Segui le istruzioni riportate in questa guida per configurare l'autenticazione e l'autorizzazione per i servizi di cui è stato eseguito il deployment con Cloud Service Mesh e i proxy Envoy utilizzando le API di bilanciamento del carico. Se utilizzi le API di routing dei servizi, leggi Configurare la sicurezza del servizio con Envoy.

Per informazioni complete, consulta Sicurezza del servizio Cloud Service Mesh con le API di bilanciamento del carico.

Questo documento si applica alle configurazioni che utilizzano le API di bilanciamento del carico. Si tratta di un documento precedente.

Requisiti

Prima di configurare la sicurezza del servizio per Cloud Service Mesh con Envoy, assicurati che la configurazione soddisfi i seguenti prerequisiti:

Prepararsi alla configurazione

Le sezioni seguenti descrivono le attività da completare prima di configurare il servizio di sicurezza Cloud Service Mesh. Queste attività sono:

  • Aggiornamento di Google Cloud CLI
  • Configurazione delle variabili
  • Abilitazione delle API richieste per il funzionamento di Cloud Service Mesh con Certificate Authority Service

Aggiornare lo strumento a riga di comando gcloud

Per aggiornare Google Cloud CLI, esegui quanto segue sulla tua macchina locale:

gcloud components update

Configura le variabili

Imposta le seguenti variabili in modo da poter copiare e incollare il codice con valori coerenti man mano che esamini l'esempio in questo documento. Utilizza i seguenti valori.

  • PROJECT_ID: sostituisci l'ID del tuo progetto.
  • CLUSTER_NAME: sostituisci il nome del cluster che vuoi utilizzare, ad esempio secure-td-cluster.
  • ZONE: sostituisci la zona in cui si trova il tuo cluster. Il tuo cluster si trova.
  • GKE_CLUSTER_URL: sostitutivo https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME
  • WORKLOAD_POOL: sostitutivo PROJECT_ID.svc.id.goog
  • K8S_NAMESPACE: sostituisci default.
  • DEMO_CLIENT_KSA: sostituisci il nome dell'account di servizio Kubernetes del cliente.
  • DEMO_SERVER_KSA: sostituisci il nome dell'account di servizio Kubernetes del tuo server.
  • PROJNUM: sostituisci il numero del progetto, che puoi determinare dalla console Google Cloud o con questo comando:

    gcloud projects describe PROJECT_ID --format="value(projectNumber)"
    
  • SA_GKE: sostitutivo service-PROJNUM@container-engine-robot.iam.gserviceaccount.com

  • CLUSTER_VERSION: sostituisci la versione più recente disponibile. Puoi trovarlo nelle note di rilascio del canale rapido. La versione minima richiesta è 1.21.4-gke.1801. Questa è la versione del cluster GKE da utilizzare in questo esempio.

Imposta i valori qui:

# Substitute your project ID
PROJECT_ID=PROJECT_ID

# GKE cluster name and zone for this example.
CLUSTER_NAME=CLUSTER_NAME
ZONE=ZONE

# GKE cluster URL derived from the above
GKE_CLUSTER_URL="https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME"

# Workload pool to be used with the GKE cluster
WORKLOAD_POOL="PROJECT_ID.svc.id.goog"

# Kubernetes namespace to run client and server demo.
K8S_NAMESPACE=K8S_NAMESPACE
DEMO_CLIENT_KSA=DEMO_CLIENT_KSA
DEMO_SERVER_KSA=DEMO_SERVER_KSA

# Compute other values
# Project number for your project
PROJNUM=PROJNUM

CLUSTER_VERSION=CLUSTER_VERSION
SA_GKE=service-PROJNUM@container-engine-robot.iam.gserviceaccount.com

Abilita le API

Utilizza il comando gcloud services enable per attivare tutte le API necessarie per configurare la sicurezza di Cloud Service Mesh con Certificate Authority Service.

gcloud services enable \
   container.googleapis.com \
   cloudresourcemanager.googleapis.com \
   compute.googleapis.com \
   trafficdirector.googleapis.com \
   networkservices.googleapis.com \
   networksecurity.googleapis.com \
   privateca.googleapis.com \
   gkehub.googleapis.com

Crea o aggiorna un cluster GKE

La sicurezza del servizio Cloud Service Mesh dipende dall'integrazione di CA Service con GKE. Il cluster GKE deve soddisfare i seguenti requisiti, oltre ai requisiti per la configurazione:

  • Utilizza una versione minima del cluster 1.21.4-gke.1801. Se hai bisogno di funzionalità che sono presenti in una versione successiva, puoi ottenere questa versione dal canale di rilascio rapido.
  • Il cluster GKE deve essere abilitato e configurato con i certificati mesh, come descritto in Creare autorità di certificazione per emettere certificati.
  1. Crea un nuovo cluster che utilizzi Workload Identity Federation for GKE. Se stai aggiornando un cluster esistente, vai al passaggio successivo. Il valore specificato per --tags deve corrispondere al nome passato al flag --target-tags per il comando firewall-rules create nella sezione Configurazione di Cloud Service Mesh con Cloud Load Balancing Cloud.

    # Create a GKE cluster with GKE managed mesh certificates.
    gcloud container clusters create CLUSTER_NAME \
      --release-channel=rapid \
      --scopes=cloud-platform \
      --image-type=cos_containerd \
      --machine-type=e2-standard-2 \
      --zone=ZONE \
      --workload-pool=PROJECT_ID.svc.id.goog \
      --enable-mesh-certificates \
      --cluster-version=CLUSTER_VERSION \
      --enable-ip-alias \
      --tags=allow-health-checks \
      --workload-metadata=GKE_METADATA
    

    La creazione del cluster potrebbe richiedere diversi minuti.

  2. Se utilizzi un cluster esistente, attiva la federazione delle identità per i carichi di lavoro per GKE e i certificati GKE Mesh. Assicurati che il cluster sia stato creato con il flag --enable-ip-alias, che non può essere utilizzato con il comando update.

    gcloud container clusters update CLUSTER_NAME \
      --enable-mesh-certificates
    
  3. Esegui il comando seguente per impostare il nuovo cluster come cluster predefinito per i comandi kubectl:

    gcloud container clusters get-credentials CLUSTER_NAME \
      --zone ZONE
    

Deployment in un ambiente multi-cluster

Se esegui il deployment in un ambiente multi-cluster, segui la procedura generale descritta in questa sezione. Queste istruzioni presuppongono che i pod client siano in esecuzione in un cluster e i pod server nell'altro cluster.

  1. Crea o aggiorna i cluster seguendo le istruzioni riportate nella sezione precedente.

  2. Acquisisci gli intervalli di indirizzi IP dei pod per ogni cluster utilizzando il seguente comando:

    gcloud compute firewall-rules list \
      --filter="name~gke-{CLUSTER_NAME}-[0-9a-z]*-all" \
      --format="value(sourceRanges)"
    

    Ad esempio, per i cluster denominati cluster-a e cluster-b, i comandi restituiranno risultati come i seguenti:

    cluster-a, pod CIDR: 10.4.0.0/14, node network tag: gke-cluster-a-9cd18751-node
    cluster-b, pod CIDR: 10.8.0.0/14, node network tag: gke-cluster-b-acd14479-node
    
  3. Crea regole firewall VPC che consentano ai cluster di comunicare tra loro. Ad esempio, il seguente comando crea una regola firewall che consente agli indirizzi IP del pod cluster-a di comunicare con i nodi cluster-b:

    gcloud compute firewall-rules create per-cluster-a-pods \
      --allow="tcp,udp,icmp,esp,ah,sctp" \
      --target-tags="gke-cluster-b-acd14479-node"
    

    Il seguente comando crea una regola firewall che consente agli indirizzi IP del pod cluster-b di comunicare con i nodi cluster-a:

    gcloud compute firewall-rules create per-cluster-b-pods \
      --allow="tcp,udp,icmp,esp,ah,sctp" \
      --target-tags="gke-cluster-a-9cd18751-node"
    

Registra i cluster in un parco risorse

Registra il cluster che hai creato o aggiornato in Creazione di un cluster GKE con un parco risorse. La registrazione del cluster semplifica la configurazione dei cluster in più progetti.

Tieni presente che il completamento di ciascun passaggio può richiedere fino a dieci minuti.

  1. Registra il cluster nel parco risorse:

    gcloud container fleet memberships register CLUSTER_NAME \
      --gke-cluster=ZONE/CLUSTER_NAME \
      --enable-workload-identity --install-connect-agent \
      --manifest-output-file=MANIFEST-FILE_NAME
    

    Sostituisci le variabili in questo modo:

    • CLUSTER_NAME: il nome del cluster.
    • ZONE: la zona del tuo cluster.
    • MANIFEST-FILE_NAME: il percorso in cui questi comandi generano il manifest per la registrazione.

    Se la procedura di registrazione va a buon fine, viene visualizzato un messaggio simile al seguente:

    Finished registering the cluster CLUSTER_NAME with the fleet.
  2. Applica il file manifest generato al cluster:

    kubectl apply -f MANIFEST-FILE_NAME
    

    Quando la procedura di richiesta va a buon fine, vengono visualizzati messaggi come i seguenti:

    namespace/gke-connect created
    serviceaccount/connect-agent-sa created
    podsecuritypolicy.policy/gkeconnect-psp created
    role.rbac.authorization.k8s.io/gkeconnect-psp:role created
    rolebinding.rbac.authorization.k8s.io/gkeconnect-psp:rolebinding created
    role.rbac.authorization.k8s.io/agent-updater created
    rolebinding.rbac.authorization.k8s.io/agent-updater created
    role.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created
    clusterrole.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created
    clusterrolebinding.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created
    clusterrolebinding.rbac.authorization.k8s.io/gke-connect-feature-authorizer-20210416-01-00 created
    rolebinding.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created
    role.rbac.authorization.k8s.io/gke-connect-namespace-getter created
    rolebinding.rbac.authorization.k8s.io/gke-connect-namespace-getter created
    secret/http-proxy created
    deployment.apps/gke-connect-agent-20210416-01-00 created
    service/gke-connect-monitoring created
    secret/creds-gcp create
    
  3. Recupera la risorsa appartenenza dal cluster:

    kubectl get memberships membership -o yaml
    

    L'output deve includere il pool di identità del workload assegnato dal parco risorse, dove PROJECT_ID è l'ID del progetto:

    workload_identity_pool: PROJECT_ID.svc.id.goog
    

    Ciò significa che il cluster è stato registrato correttamente.

Creare autorità di certificazione per emettere certificati

Per emettere certificati ai pod, crea un pool di CA Service e le seguenti autorità di certificazione (CA):

  • CA radice. Si tratta della radice di attendibilità per tutti i certificati mesh emessi. Puoi utilizzare una CA radice esistente, se ne hai una. Crea la CA radice nel livello enterprise, progettato per l'emissione di certificati di lunga durata e a basso volume.
  • CA subordinata. Questa CA emette certificati per i carichi di lavoro. Crea la CA subordinata nella regione in cui è dipiegato il cluster. Crea la CA subordinata nel livello devops, progettato per l'emissione di certificati di breve durata e ad alto volume.

La creazione di una CA subordinata è facoltativa, ma ti consigliamo vivamente di crearne una anziché utilizzare la CA radice per emettere i certificati del mesh GKE. Se decidi di utilizzare la CA radice per emettere i certificati mesh, assicurati che la modalità di emissione basata sulla configurazione predefinita rimanga consentita.

La CA secondaria può trovarsi in una regione diversa dal tuo cluster, ma ti consigliamo vivamente di crearla nella stessa regione del cluster per ottimizzare le prestazioni. Tuttavia, puoi creare le CA principali e secondarie in regioni diverse senza alcun impatto sul rendimento o sulla disponibilità.

Queste regioni sono supportate per il servizio CA:

Nome regione Descrizione della regione
asia-east1 Taiwan
asia-east2 Hong Kong
asia-northeast1 Tokyo
asia-northeast2 Osaka
asia-northeast3 Seul
asia-south1 Mumbai
asia-south2 Delhi
asia-southeast1 Singapore
asia-southeast2 Giacarta
australia-southeast1 Sydney
australia-southeast2 Melbourne
europe-central2 Varsavia
europe-north1 Finlandia
europe-southwest1 Madrid
europe-west1 Belgio
europe-west2 Londra
europe-west3 Francoforte
europe-west4 Paesi Bassi
europe-west6 Zurigo
europe-west8 Milano
europe-west9 Parigi
europe-west10 Berlino
europe-west12 Torino
me-central1 Doha
me-central2 Dammam
me-west1 Tel Aviv
northamerica-northeast1 Montréal
northamerica-northeast2 Toronto
southamerica-east1 San Paolo
southamerica-west1 Santiago
us-central1 Iowa
us-east1 Carolina del Sud
us-east4 Virginia del Nord
us-east5 Columbus
us-south1 Dallas
us-west1 Oregon
us-west2 Los Angeles
us-west3 Salt Lake City
us-west4 Las Vegas

L'elenco delle località supportate può essere controllato anche eseguendo il seguente comando:

gcloud privateca locations list
  1. Concedi il ruolo IAM roles/privateca.caManager alle persone che creano un pool di CA e una CA. Tieni presente che per MEMBER, il formato corretto è user:userid@example.com. Se questa persona è l'utente corrente, puoi ottenere l'ID utente corrente con il comando shell$(gcloud auth list --filter=status:ACTIVE --format="value(account)").

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=MEMBER \
      --role=roles/privateca.caManager
    
  2. Concedi il ruolo role/privateca.admin per il servizio CA alle persone che devono modificare i criteri IAM, dove MEMBER è una persona che ha bisogno di questo accesso, in particolare a tutte le persone che eseguono i passaggi che seguono per concedere i ruoli privateca.auditor e privateca.certificateManager:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=MEMBER \
      --role=roles/privateca.admin
    
  3. Crea il pool di servizi della CA radice.

    gcloud privateca pools create ROOT_CA_POOL_NAME \
      --location ROOT_CA_POOL_LOCATION \
      --tier enterprise
    
  4. Crea una CA radice.

    gcloud privateca roots create ROOT_CA_NAME --pool ROOT_CA_POOL_NAME \
      --subject "CN=ROOT_CA_NAME, O=ROOT_CA_ORGANIZATION" \
      --key-algorithm="ec-p256-sha256" \
      --max-chain-length=1 \
      --location ROOT_CA_POOL_LOCATION
    

    Per questa configurazione di dimostrazione, utilizza i seguenti valori per le variabili:

    • ROOT_CA_POOL_NAME=td_sec_pool
    • ROOT_CA_NAME=pkcs2-ca
    • ROOT_CA_POOL_LOCATION=us-east1
    • ROOT_CA_ORGANIZATION="TestCorpLLC"
  5. Crea il pool e la CA secondari. Assicurati che la modalità di emissione basata sulla configurazione predefinita rimanga consentita.

    gcloud privateca pools create SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --tier devops
    
    gcloud privateca subordinates create SUBORDINATE_CA_NAME \
      --pool SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --issuer-pool ROOT_CA_POOL_NAME \
      --issuer-location ROOT_CA_POOL_LOCATION \
      --subject "CN=SUBORDINATE_CA_NAME, O=SUBORDINATE_CA_ORGANIZATION" \
      --key-algorithm "ec-p256-sha256" \
      --use-preset-profile subordinate_mtls_pathlen_0
    

    Per questa configurazione di dimostrazione, utilizza i seguenti valori per le variabili:

    • SUBORDINATE_CA_POOL_NAME="td-ca-pool"
    • SUBORDINATE_CA_POOL_LOCATION=us-east1
    • SUBORDINATE_CA_NAME="td-ca"
    • SUBORDINATE_CA_ORGANIZATION="TestCorpLLC"
    • ROOT_CA_POOL_NAME=td_sec_pool
    • ROOT_CA_POOL_LOCATION=us-east1
  6. Concedi il ruolo IAM privateca.auditor per il pool CA principale per consentire l'accesso dall'account di servizio GKE:

    gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \
     --location ROOT_CA_POOL_LOCATION \
     --role roles/privateca.auditor \
     --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
    
  7. Concedi il ruolo IAM privateca.certificateManager per il pool CA secondario per consentire l'accesso dall'account di servizio GKE:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \
      --location SUBORDINATE_CA_POOL_LOCATION \
      --role roles/privateca.certificateManager \
      --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
    
  8. Salva la seguente configurazione YAML WorkloadCertificateConfig per indicare al tuo cluster come emettere i certificati del mesh:

    apiVersion: security.cloud.google.com/v1
    kind: WorkloadCertificateConfig
    metadata:
      name: default
    spec:
      # Required. The CA service that issues your certificates.
      certificateAuthorityConfig:
        certificateAuthorityServiceConfig:
          endpointURI: ISSUING_CA_POOL_URI
    
      # Required. The key algorithm to use. Choice of RSA or ECDSA.
      #
      # To maximize compatibility with various TLS stacks, your workloads
      # should use keys of the same family as your root and subordinate CAs.
      #
      # To use RSA, specify configuration such as:
      #   keyAlgorithm:
      #     rsa:
      #       modulusSize: 4096
      #
      # Currently, the only supported ECDSA curves are "P256" and "P384", and the only
      # supported RSA modulus sizes are 2048, 3072 and 4096.
      keyAlgorithm:
        rsa:
          modulusSize: 4096
    
      # Optional. Validity duration of issued certificates, in seconds.
      #
      # Defaults to 86400 (1 day) if not specified.
      validityDurationSeconds: 86400
    
      # Optional. Try to start rotating the certificate once this
      # percentage of validityDurationSeconds is remaining.
      #
      # Defaults to 50 if not specified.
      rotationWindowPercentage: 50
    
    

    Sostituisci quanto segue:

    • L'ID del progetto in cui viene eseguito il cluster:
      PROJECT_ID
    • L'URI completo dell'autorità di certificazione che emette i certificati mesh (ISSUING_CA_POOL_URI). Può essere la CA subordinata (opzione consigliata) o la CA principale. Il formato è:
      //privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
  9. Salva la seguente configurazione YAML TrustConfig per indicare al cluster come considerare attendibili i certificati emessi:

    apiVersion: security.cloud.google.com/v1
    kind: TrustConfig
    metadata:
      name: default
    spec:
      # You must include a trustStores entry for the trust domain that
      # your cluster is enrolled in.
      trustStores:
      - trustDomain: PROJECT_ID.svc.id.goog
        # Trust identities in this trustDomain if they appear in a certificate
        # that chains up to this root CA.
        trustAnchors:
        - certificateAuthorityServiceURI: ROOT_CA_POOL_URI
    

    Sostituisci quanto segue:

    • L'ID del progetto in cui viene eseguito il cluster:
      PROJECT_ID
    • L'URI completo del pool di CA radice (ROOT_CA_POOL_URI). Il formato è:
      //privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
  10. Applica le configurazioni al cluster:

    kubectl apply -f WorkloadCertificateConfig.yaml
    kubectl apply -f TrustConfig.yaml
    

Configurare Identity and Access Management

Per creare le risorse necessarie per la configurazione, devi disporre del ruolo compute.NetworkAdmin. Questo ruolo contiene tutte le autorizzazioni necessarie per creare, aggiornare, eliminare, elencare e utilizzare (ovvero fare riferimento a queste risorse in altre risorse) le risorse richieste. Se sei il proprietario-editor del progetto, hai automaticamente questo ruolo.

Tieni presente che networksecurity.googleapis.com.clientTlsPolicies.use e networksecurity.googleapis.com.serverTlsPolicies.use non vengono applicati quando fai riferimento a queste risorse nel servizio di backend e nelle risorse proxy HTTPS di destinazione.

Se queste autorizzazioni vengono applicate in futuro e utilizzi il ruolo compute.NetworkAdmin, non noterai alcun problema quando verrà applicato questo controllo.

Se utilizzi ruoli personalizzati e questo controllo viene applicato in futuro, devi assicurarti di includere la rispettiva autorizzazione .use. In caso contrario, in futuro potresti scoprire che il tuo ruolo personalizzato non dispone delle autorizzazioni necessarie per fare riferimento a clientTlsPolicy o serverTlsPolicy rispettivamente dal servizio di backend o dal proxy HTTPS di destinazione.

Le istruzioni riportate di seguito consentono all'account di servizio predefinito di accedere all'API Cloud Service Mesh Security e di creare gli account di servizio Kubernetes.

  1. Configura IAM per consentire all'account di servizio predefinito di accedere all'API di sicurezza Cloud Service Mesh.

    GSA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \
       --filter='displayName:Compute Engine default service account')
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member serviceAccount:${GSA_EMAIL} \
      --role roles/trafficdirector.client
    
  2. Configura gli account di servizio Kubernetes. I deployment client e server nelle sezioni seguenti utilizzano i Kname degli account di servizio client e server Kubernetes.

    kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_SERVER_KSA
    kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_CLIENT_KSA
    
  3. Consenti agli account di servizio Kubernetes di rubare l'identità dell'account di servizio Compute Engine predefinito creando un'associazione dei criteri IAM tra i due. Questa associazione consente all'account di servizio Kubernetes di agire come account di servizio Compute Engine predefinito.

    gcloud iam service-accounts add-iam-policy-binding  \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_SERVER_KSA]" ${GSA_EMAIL}
    
    gcloud iam service-accounts add-iam-policy-binding  \
      --role roles/iam.workloadIdentityUser  \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_CLIENT_KSA]" ${GSA_EMAIL}
    
  4. Aggiungi annotazioni agli account di servizio Kubernetes per associarli all'account di servizio Compute Engine predefinito.

    kubectl annotate --namespace K8S_NAMESPACE \
      serviceaccount DEMO_SERVER_KSA \
      iam.gke.io/gcp-service-account=${GSA_EMAIL}
    
    kubectl annotate --namespace K8S_NAMESPACE \
      serviceaccount DEMO_CLIENT_KSA \
      iam.gke.io/gcp-service-account=${GSA_EMAIL}
    

Configurare Cloud Service Mesh

Segui le istruzioni riportate di seguito per installare l'iniettore sidecar, configurare un servizio di test e completare altre attività di implementazione.

Installa l'iniettore sidecar Envoy nel cluster

Segui le istruzioni riportate in entrambe le sezioni seguenti della configurazione di Cloud Service Mesh per i pod GKE con l'iniezione automatica di Envoy per eseguire il deployment e attivare l'iniezione di sidecar Envoy nel cluster:

Assicurati di completare entrambe le serie di istruzioni prima di configurare un servizio di test.

Configurare un servizio di test

Dopo aver installato l'iniettore sidecar Envoy, segui queste istruzioni per configurare un servizio di test per la distribuzione.

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/service_sample.yaml | sed -e s/DEMO_SERVER_KSA_PLACEHOLDER/DEMO_SERVER_KSA/g > service_sample.yaml

kubectl apply -f service_sample.yaml

Il file service_sample.yaml contiene il podspec per l'applicazione del server demo. Esistono alcune annotazioni specifiche per la sicurezza di Cloud Service Mesh.

Metadati del proxy Cloud Service Mesh

Il file podspec specifica l'annotazione proxyMetadata:

spec:
...
      annotations:
        cloud.google.com/proxyMetadata: '{"app": "payments"}'
...

Quando il pod viene inizializzato, il proxy sidecar recupera questa annotazione e la trasmette a Cloud Service Mesh. Cloud Service Mesh può quindi utilizzare queste informazioni per inviare nuovamente la configurazione filtrata:

  • Più avanti in questa guida, tieni presente che il criterio endpoint specifica un'associazione di endpoint.
  • Il corrispettivo endpoint specifica che solo i client che presentano un'etichetta con nome app e valore payments ricevono la configurazione filtrata.

Utilizzare certificati e chiavi mesh firmati dal servizio CA

Il file podspec specifica l'annotazione enableManagedCerts:

spec:
...
      annotations:
        ...
        cloud.google.com/enableManagedCerts: "true"
...

Quando il pod viene inizializzato, le chiavi e i certificati firmati del servizio CA vengono montati automaticamente sul file system del proxy sidecar locale.

Configurazione della porta di intercettazione del traffico in entrata

Il file podspec specifica l'annotazione includeInboundPorts:

spec:
...
      annotations:
        ...
        cloud.google.com/includeInboundPorts: "8000"
...

Questa è la porta su cui l'applicazione server è in ascolto per le connessioni. Quando il pod viene inizializzato, il proxy sidecar recupera questa annotazione e la trasmette a Cloud Service Mesh. Cloud Service Mesh può quindi utilizzare queste informazioni per inviare nuovamente la configurazione filtrata che intercetta tutto il traffico in entrata su questa porta e può applicare criteri di sicurezza.

La porta del controllo di integrità deve essere diversa dalla porta dell'applicazione. In caso contrario, alle connessioni in arrivo alla porta di controllo dell'integrità verranno applicati gli stessi criteri di sicurezza, il che potrebbe comportare il rifiuto delle connessioni e il conseguente erroneo scambio del server per non integro.

Configurare i servizi GKE con i NEG

I servizi GKE devono essere esposti tramite gruppi di endpoint di rete (NEG) in modo da poterli configurare come backend di un servizio di backend Cloud Service Mesh. Il pacchetto service_sample.yaml fornito con questa guida alla configurazione utilizza il nome NEG service-test-neg nella seguente annotazione:

...
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "service-test-neg"}}}'
spec:
  ports:
  - port: 80
    name: service-test
    protocol: TCP
    targetPort: 8000

Non è necessario modificare il file service_sample.yaml.

Salvataggio del nome del NEG

Salva il nome del NEG nella variabile NEG_NAME:

NEG_NAME="service-test-neg"

Esegui il deployment di un'applicazione client in GKE

Esegui il seguente comando per avviare un client di dimostrazione con un proxy Envoy come sidecar, necessario per dimostrare le funzionalità di sicurezza.

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/client_sample.yaml | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > client_sample.yaml

kubectl apply -f client_sample.yaml

Il podspec del client include solo l'annotazione enableManagedCerts. Questo è necessario per montare i volumi necessari per i certificati e le chiavi del mesh gestito da GKE firmati dall'istanza del servizio CA.

Configura le risorse Google Cloud di Cloud Service Mesh

Segui i passaggi descritti in Configurare Cloud Service Mesh con Cloud Load Balancing Cloud. Assicurati di verificare che il traffico dal client di esempio venga indirizzato al servizio di esempio.

La configurazione di Cloud Service Mesh è completata e ora puoi configurare i criteri di autenticazione e autorizzazione.

Configurare la sicurezza tra servizi

Segui le istruzioni riportate nelle sezioni seguenti per configurare la sicurezza tra servizi.

Attiva mTLS nel mesh

Per configurare mTLS nel tuo mesh, devi proteggere il traffico in uscita verso il servizio di backend e il traffico in entrata verso l'endpoint.

Formato per i riferimenti alle norme

Tieni presente il seguente formato obbligatorio per fare riferimento a TLS server, TLS client e ai criteri di autorizzazione:

projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies|authorizationPolicies]/[server-tls-policy|client-mtls-policy|authz-policy]

Ad esempio:

projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy

Proteggi il traffico in uscita verso il servizio di backend

Per proteggere il traffico in uscita, crea innanzitutto un criterio TLS del client che svolga quanto segue:

  • Utilizza google_cloud_private_spiffe come plug-in per clientCertificate, che programma Envoy per utilizzare i certificati mesh gestiti da GKE come identità client.
  • Utilizza google_cloud_private_spiffe come plug-in per serverValidationCa che programma Envoy per utilizzare i certificati mesh gestiti da GKE per la convalida del server.

Successivamente, devi collegare il criterio TLS del client al servizio di backend. In questo modo:

  • Applica il criterio di autenticazione del criterio TLS del client alle connessioni in uscita agli endpoint del servizio di backend.
  • I SAN (Subject Alternative Names) chiedono al client di affermare l'identità esatta del server a cui si connette.
  1. Crea il criterio TLS del client in un file client-mtls-policy.yaml:

    name: "client-mtls-policy"
    clientCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    serverValidationCa:
    - certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    
  2. Importa il criterio TLS del client:

    gcloud network-security client-tls-policies import client-mtls-policy \
        --source=client-mtls-policy.yaml --location=global
    
  3. Collega il criterio TLS del client al servizio di backend. In questo modo viene applicata l'autenticazione mTLS su tutte le richieste in uscita dal client a questo servizio di backend.

    gcloud compute backend-services export td-gke-service \
        --global --destination=demo-backend-service.yaml
    

    Aggiungi le seguenti righe a demo-backend-service.yaml:

    securitySettings:
      clientTlsPolicy: projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
      subjectAltNames:
        - "spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA"
    
  4. Importa i valori:

    gcloud compute backend-services import td-gke-service \
        --global --source=demo-backend-service.yaml
    
  5. Se vuoi, esegui il seguente comando per verificare se la richiesta non va a buon fine. Si tratta di un errore previsto, perché il client si aspetta i certificati dall'endpoint, ma l'endpoint non è programmato con un criterio di sicurezza.

    # Get the name of the Podrunning Busybox.
    BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')
    
    # Command to execute that tests connectivity to the service service-test.
    TEST_CMD="wget -q -O - service-test; echo"
    
    # Execute the test command on the pod.
    kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
    

    Vedrai un output simile al seguente:

    wget: server returned error: HTTP/1.1 503 Service Unavailable
    

Proteggi il traffico in entrata verso l'endpoint

Per proteggere il traffico in entrata, crea innanzitutto un criterio TLS del server che svolga quanto segue:

  • Utilizza google_cloud_private_spiffe come plug-in per serverCertificate, che programma Envoy per utilizzare i certificati mesh gestiti da GKE come identità del server.
  • Utilizza google_cloud_private_spiffe come plug-in per clientValidationCa, che programma Envoy per utilizzare i certificati mesh gestiti da GKE per la convalida del client.
  1. Salva i valori dei criteri TLS del server in un file denominato server-mtls-policy.yaml.

    name: "server-mtls-policy"
    serverCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    mtlsPolicy:
      clientValidationCa:
      - certificateProviderInstance:
          pluginInstance: google_cloud_private_spiffe
    
  2. Crea il criterio TLS del server:

    gcloud network-security server-tls-policies import server-mtls-policy \
        --source=server-mtls-policy.yaml --location=global
    
  3. Crea un file denominato ep_mtls.yaml contenente l'analizzatore di endpoint e collega il criterio TLS del server.

    endpointMatcher:
      metadataLabelMatcher:
        metadataLabelMatchCriteria: MATCH_ALL
        metadataLabels:
        - labelName: app
          labelValue: payments
    name: "ep"
    serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy
    type: SIDECAR_PROXY
    
  4. Importa il corrispettivo dell'endpoint.

    gcloud network-services endpoint-policies import ep \
        --source=ep_mtls.yaml --location=global
    

Convalida la configurazione

Esegui questo comando curl. Se la richiesta viene completata correttamente, viene visualizzato x-forwarded-client-cert nell'output. L'intestazione viene stampata solo quando la connessione è mTLS.

# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

Viene visualizzato un output come il seguente:

GET /get HTTP/1.1
Host: service-test
content-length: 0
x-envoy-internal: true
accept: */*
x-forwarded-for: 10.48.0.6
x-envoy-expected-rq-timeout-ms: 15000
user-agent: curl/7.35.0
x-forwarded-proto: http
x-request-id: redacted
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA

Tieni presente che l'intestazione x-forwarded-client-cert viene inserita da Envoy lato server e contiene la propria identità (server) e l'identità del client di origine. Poiché vediamo sia le identità del client sia quelle del server, questo è un indicatore di una connessione mTLS.

Configurare l'accesso a livello di servizio con un criterio di autorizzazione

Queste istruzioni creano un criterio di autorizzazione che consente le richieste inviate dall'account DEMO_CLIENT_KSA in cui l'hostname è service-test, la porta è 8000 e il metodo HTTP è GET. Prima di creare i criteri di autorizzazione, leggi l'avviso in Limitare l'accesso utilizzando l'autorizzazione.

  1. Crea un criterio di autorizzazione creando un file denominato authz-policy.yaml.

    action: ALLOW
    name: authz-policy
    rules:
    - sources:
      - principals:
        - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
      destinations:
      - hosts:
        - service-test
        ports:
        - 8000
        methods:
        - GET
    
  2. Importa il criterio:

    gcloud network-security authorization-policies import authz-policy \
      --source=authz-policy.yaml \
      --location=global
    
  3. Aggiorna il criterio dell'endpoint in modo che faccia riferimento al nuovo criterio di autorizzazione aggiungendo quanto segue al file ep_mtls.yaml:

    authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
    

    Il criterio endpoint ora specifica che sia mTLS sia il criterio di autorizzazione devono essere applicati alle richieste in entrata ai pod i cui proxy sidecar Envoy presentano l'etichetta app:payments.

  4. Importa il criterio:

    gcloud network-services endpoint-policies import ep \
        --source=ep_mtls.yaml --location=global
    

Convalida la configurazione

Esegui i seguenti comandi per convalidare la configurazione.

# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
# This is a valid request and will be allowed.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

L'output previsto è simile al seguente:

GET /get HTTP/1.1
Host: service-test
content-length: 0
x-envoy-internal: true
accept: */*
x-forwarded-for: redacted
x-envoy-expected-rq-timeout-ms: 15000
user-agent: curl/7.35.0
x-forwarded-proto: http
x-request-id: redacted
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA

Esegui i seguenti comandi per verificare se il criterio di autorizzazione rifiuta correttamente le richieste non valide:

# Failure case
# Command to execute that tests connectivity to the service service-test.
# This is an invalid request and server will reject because the server
# authorization policy only allows GET requests.
TEST_CMD="wget -q -O - service-test --post-data='' ; echo"

# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

L'output previsto è simile al seguente:

<RBAC: access denied HTTP/1.1 403 Forbidden>

Configurare la sicurezza del gateway in entrata

Questa sezione presuppone che tu abbia completato la sezione sulla sicurezza tra servizi, inclusa la configurazione del cluster GKE con l'autoiniettore sidecar, la creazione di un'autorità di certificazione e la creazione di un criterio endpoint.

In questa sezione, esegui il deployment di un proxy Envoy come gateway di ingresso che termina le connessioni TLS e autorizza le richieste dei client interni di un cluster.

Terminazione TLS in un gateway in entrata (fai clic per ingrandire)
Terminazione di TLS in un gateway di ingresso (fai clic per ingrandire)

Per configurare un gateway di ingresso per terminare TLS:

  1. Esegui il deployment di un servizio Kubernetes raggiungibile utilizzando un indirizzo IP interno del cluster.
    1. Il deployment è costituito da un proxy Envoy autonomo esposto come servizio Kubernetes e connesso a Cloud Service Mesh.
  2. Crea un criterio TLS del server per terminare TLS.
  3. Crea un criterio di autorizzazione per autorizzare le richieste in entrata.

Esegui il deployment di un servizio di gateway in entrata in GKE

Esegui il seguente comando per eseguire il deployment del servizio gateway di ingresso su GKE:

wget -q -O -  https://storage.googleapis.com/traffic-director/security/ga/gateway_sample_xdsv3.yaml | sed -e s/PROJECT_NUMBER_PLACEHOLDER/PROJNUM/g | sed -e s/NETWORK_PLACEHOLDER/default/g | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > gateway_sample.yaml

kubectl apply -f gateway_sample.yaml

Il file gateway_sample.yaml è la specifica del gateway di ingresso. Le sezioni seguenti descrivono alcune aggiunte alle specifiche.

Disattivazione dell'iniezione di sidecar di Cloud Service Mesh

La specifica gateway_sample.yaml esegue il deployment di un proxy Envoy come unico contenitore. Nei passaggi precedenti, Envoy è stato inserito come sidecar in un contenitore dell'applicazione. Per evitare che più Envoy gestiscano le richieste, puoi disattivare l'iniezione di sidecar per questo servizio Kubernetes utilizzando la seguente istruzione:

sidecar.istio.io/inject: "false"

Monta il volume corretto

La specifica gateway_sample.yaml monta il volume gke-workload-certificates. Questo volume viene utilizzato anche per il deployment di sidecar, ma viene aggiunto automaticamente dall'iniettore sidecar quando vede l'annotazionecloud.google.com/enableManagedCerts: "true". Il volume gke-workload-certificates contiene i certificati e le chiavi SPIFFE gestiti da GKE firmati dall'istanza di servizio CA che hai configurato.

Impostare l'indirizzo IP interno del cluster

Configura il gateway in entrata con un servizio di tipo ClusterInternal. In questo modo viene creato un nome host DNS risolvibile internamente per mesh-gateway. Quando un client invia una richiesta a mesh-gateway:443, Kubernetes indirizza immediatamente la richiesta alla porta8080 del deployment di Envoy del gateway di ingresso.

Attivare TLS su un gateway in entrata

Segui queste istruzioni per abilitare TLS su un gateway di ingresso.

  1. Crea una risorsa criterio TLS del server per terminare le connessioni TLS, con i valori in un file denominato server-tls-policy.yaml:

    description: tls server policy
    name: server-tls-policy
    serverCertificate:
      certificateProviderInstance:
        pluginInstance: google_cloud_private_spiffe
    
  2. Importa il criterio TLS del server:

    gcloud network-security server-tls-policies import server-tls-policy \
        --source=server-tls-policy.yaml --location=global
    
  3. Crea una nuova mappa URL che indirizzi tutte le richieste al servizio di backend td-gke-service. Il gateway di ingresso gestisce le richieste in arrivo e le invia ai pod appartenenti al servizio di backend td-gke-service.

    gcloud compute url-maps create td-gke-ig-url-map \
       --default-service=td-gke-service
    
  4. Crea un nuovo proxy HTTPS di destinazione nel file td-gke-https-proxy.yaml e collega la mappa URL e il criterio TLS del server creati in precedenza. In questo modo, il gateway di ingresso del proxy Envoy viene configurato per terminare il traffico TLS in entrata.

    kind: compute#targetHttpsProxy
    name: td-gke-https-proxy
    proxyBind: true
    urlMap: https://www.googleapis.com/compute/beta/projects/PROJECT_ID/global/urlMaps/td-gke-ig-url-map
    serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
    
  5. Importa il criterio:

    gcloud compute target-https-proxies import td-gke-https-proxy \
       --global --source=td-gke-https-proxy.yaml
    
  6. Crea una nuova regola di forwarding e collega il proxy HTTPS di destinazione. In questo modo, il proxy Envoy viene configurato per ascoltare sulla porta 8080 e applicare i criteri di routing e sicurezza definiti in td-gke-https-proxy.

    gcloud compute forwarding-rules create td-gke-gateway-forwarding-rule --global \
      --load-balancing-scheme=INTERNAL_SELF_MANAGED --address=0.0.0.0 \
      --target-https-proxy=td-gke-https-proxy --ports 8080 \
      --network default
    
  7. Se vuoi, aggiorna il criterio di autorizzazione sui backend per consentire le richieste quando sono soddisfatte tutte le seguenti condizioni:

    • Richieste inviate da DEMO_CLIENT_KSA. Il deployment del gateway di ingresso utilizza l'account di servizio DEMO_CLIENT_KSA.
    • Richieste con host mesh-gateway o service-test
    • Porta: 8000

    Non è necessario eseguire questi comandi, a meno che non abbia configurato un criterio di autorizzazione per i tuoi backend. Se non è presente alcun criterio di autorizzazione nell'endpoint o se non contiene una corrispondenza dell'entità host o di origine nel criterio di autorizzazione, le richieste sono consentite senza questo passaggio. Aggiungi questi valori a authz-policy.yaml.

    action: ALLOW
    name: authz-policy
    rules:
    - sources:
      - principals:
        - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
      destinations:
      - hosts:
        - service-test
        - mesh-gateway
        ports:
        - 8000
        methods:
        - GET
    
  8. Importa il criterio:

    gcloud network-security authorization-policies import authz-policy \
      --source=authz-policy.yaml \
      --location=global
    

Convalida il deployment del gateway in entrata

Utilizzi un nuovo contenitore denominato debug per inviare richieste al gateway di ingresso per convalidare il deployment.

Nella specifica seguente, l'annotazione "sidecar.istio.io/inject":"false" impedisce all'iniettore di sidecar di Cloud Service Mesh di iniettare automaticamente un proxy sidecar. Non è presente un sidecar per aiutare il contenitore debug nel routing delle richieste. Il contenitore deve connettersi al gateway di ingresso per il routing.

La specifica include il flag --no-check-certificate, che ignora la convalida del certificato del server. Il contenitore debug non dispone dei certificati di convalida dell'autorità di certificazione necessari per i certificati validi firmati dal servizio CA che vengono utilizzati dal gateway di ingresso per terminare TLS.

In un ambiente di produzione, ti consigliamo di scaricare il certificato di convalida del servizio CA e di montarlo o installarlo sul client. Dopo aver installato il certificato di convalida, rimuovi l'opzione --no-check-certificate del comando wget.

Esegui questo comando:

kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway; echo"

Viene visualizzato un output simile al seguente:

GET / HTTP/1.1
Host: 10.68.7.132
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
x-envoy-expected-rq-timeout-ms: 15000
x-envoy-internal: true
x-request-id: 5ae429e7-0e18-4bd9-bb79-4e4149cf8fef
x-forwarded-for: 10.64.0.53
x-forwarded-proto: https
content-length: 0
user-agent: Wget

Esegui il seguente comando di test negativo:

# Negative test
# Expect this to fail because gateway expects TLS.
kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - http://mesh-gateway:443/headers; echo"

Viene visualizzato un output simile al seguente:

wget: error getting response: Connection reset by peer

Esegui il seguente comando di test negativo:

# Negative test.
# AuthorizationPolicy applied on the endpoints expect a GET request. Otherwise
# the request is denied authorization.
kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway --post-data=''; echo"

Viene visualizzato un output simile al seguente:

HTTP/1.1 403 Forbidden
wget: server returned error: HTTP/1.1 403 Forbidden

Configurazione di un criterio di autorizzazione per il gateway in entrata

Il criterio di autorizzazione configurato qui consente al gateway in entrata di consentire le richieste nel mesh quando sono soddisfatte tutte le seguenti condizioni:

  • Host: mesh-gateway
  • Porta: 8080
  • path: *
  • Metodo HTTP GET
  1. Crea un criterio di autorizzazione nel file authz-gateway-policy.yaml:

    action: ALLOW
    name: authz-gateway-policy
    rules:
    - destinations:
      - hosts:
        - mesh-gateway
        ports:
        - 8080
        methods:
        - GET
    
  2. Importa i valori nel file:

    gcloud network-security authorization-policies import authz-gateway-policy \
       --source=authz-gateway-policy.yaml  --location=global
    
  3. Modifica il file td-gke-https-proxy.yaml aggiungendo quanto segue:

    authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-gateway-policy
    
  4. Importa di nuovo il file td-gke-https-proxy.yaml:

    gcloud compute target-https-proxies import td-gke-https-proxy \
       --global --source=td-gke-https-proxy.yaml
    

Convalida il deployment

Esegui il comando seguente per convalidare il deployment.

# On your localhost.
kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway; echo"

Viene visualizzato un output simile al seguente:

GET / HTTP/1.1
Host: 35.196.50.2
x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
x-envoy-expected-rq-timeout-ms: 15000
user-agent: curl/7.72.0
x-forwarded-proto: https
content-length: 0
x-envoy-internal: true
x-request-id: 98bec135-6df8-4082-8edc-b2c23609295a
accept: */*
x-forwarded-for: 10.142.0.7

Esegui il seguente comando di test negativo:

# Negative test. Expect failure because only POST method is allowed by \
# authz-gateway-policy
kubectl run -i --tty --rm debug --image=busybox --restart=Never  --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }'  -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway/ --post-data=''; echo"

Viene visualizzato un output simile al seguente:

wget: server returned error: HTTP/1.1 403 Forbidden

Elimina il deployment

Se vuoi, puoi eseguire questi comandi per eliminare il deployment creato con questa guida.

Per eliminare il cluster, esegui questo comando:

gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet

Per eliminare le risorse che hai creato, esegui questi comandi:

gcloud compute forwarding-rules delete td-gke-forwarding-rule --global --quiet
gcloud compute forwarding-rules delete td-gke-gateway-forwarding-rule --global \
    --quiet
gcloud compute target-http-proxies delete td-gke-proxy  --quiet
gcloud compute target-https-proxies delete td-gke-https-proxy  --quiet
gcloud compute url-maps delete td-gke-url-map  --quiet
gcloud compute url-maps delete td-gke-ig-url-map  --quiet
gcloud compute backend-services delete td-gke-service --global --quiet
cloud compute network-endpoint-groups delete service-test-neg --zone ZONE --quiet
gcloud compute firewall-rules delete fw-allow-health-checks --quiet
gcloud compute health-checks delete td-gke-health-check --quiet
gcloud network-services endpoint-policies delete ep \
    --location=global --quiet
gcloud network-security authorization-policies delete authz-gateway-policy \
   --location=global --quiet
gcloud network-security authorization-policies delete authz-policy \
    --location=global --quiet
gcloud network-security client-tls-policies delete client-mtls-policy \
    --location=global --quiet
gcloud network-security server-tls-policies delete server-tls-policy \
    --location=global --quiet
gcloud network-security server-tls-policies delete server-mtls-policy \
    --location=global --quiet

Limitazioni

La sicurezza del servizio Cloud Service Mesh è supportata solo con GKE. Non puoi eseguire il deployment della sicurezza del servizio con Compute Engine.

Risoluzione dei problemi

Questa sezione contiene informazioni su come risolvere i problemi riscontrati durante la configurazione del servizio di sicurezza.

Errori di connessione

Se la connessione non riesce con un errore upstream connect o disconnect/reset before headers, esamina i log di Envoy, dove potresti visualizzare uno dei seguenti messaggi di log:

gRPC config stream closed: 5, Requested entity was not found

gRPC config stream closed: 2, no credential token is found

Se vedi questi errori nel log di Envoy, è probabile che il token dell'account di servizio sia montato in modo errato o che utilizzi un audience diverso oppure entrambi.

Per ulteriori informazioni, consulta Messaggi di errore nei log di Envoy che indicano un problema di configurazione.

Pod non creati

Per risolvere il problema, consulta la sezione Risoluzione dei problemi relativi ai deployment automatici per i pod GKE.

Envoy non si autentica con Cloud Service Mesh

Quando Envoy (envoy-proxy) si connette a Cloud Service Mesh per recuperare la configurazione xDS, utilizza la federazione delle identità per i carichi di lavoro per GKE e l'account di servizio predefinito della VM Compute Engine (a meno che il bootstrap non sia stato modificato). Se l'autenticazione non va a buon fine, Envoy non entra nello stato di disponibilità.

Impossibile creare un cluster con --workload-identity-certificate-authority flag

Se vedi questo errore, assicurati di utilizzare la versione più recente di Google Cloud CLI:

gcloud components update

I pod rimangono in uno stato di attesa

Se i pod rimangono in uno stato in attesa durante la procedura di configurazione, aumenta le risorse di CPU e memoria per i pod nella specifica di deployment.

Impossibile creare il cluster con il flag --enable-mesh-certificates

Assicurati di utilizzare la versione più recente della gcloud CLI:

gcloud components update

Tieni presente che il flag --enable-mesh-certificates funziona solo con gcloud beta.

I pod non si avviano

L'avvio dei pod che utilizzano i certificati del mesh GKE potrebbe non riuscire se il provisioning dei certificati non va a buon fine. Ciò può accadere in situazioni come le seguenti:

  • WorkloadCertificateConfig o TrustConfig è configurato in modo errato o manca.
  • Le RP non vengono approvate.

Puoi verificare se il provisioning dei certificati non va a buon fine controllando gli eventi del pod.

  1. Controlla lo stato del tuo pod:

    kubectl get pod -n POD_NAMESPACE POD_NAME
    

    Sostituisci quanto segue:

    • POD_NAMESPACE: lo spazio dei nomi del pod.
    • POD_NAME: il nome del pod.
  2. Controlla gli eventi recenti del tuo pod:

    kubectl describe pod -n POD_NAMESPACE POD_NAME
    
  3. Se il provisioning dei certificati non va a buon fine, viene visualizzato un evento con Type=Warning, Reason=FailedMount, From=kubelet e un campo Message che inizia con MountVolume.SetUp failed for volume "gke-workload-certificates". Il campo Message contiene informazioni sulla risoluzione dei problemi.

    Events:
      Type     Reason       Age                From       Message
      ----     ------       ----               ----       -------
      Warning  FailedMount  13s (x7 over 46s)  kubelet    MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)
    
  4. Consulta i seguenti passaggi per la risoluzione dei problemi se i pod non si avviano a causa di oggetti configurati in modo errato o di CSR rifiutate.

WorkloadCertificateConfig o TrustConfig è configurato in modo errato

Assicurati di aver creato correttamente gli oggetti WorkloadCertificateConfig e TrustConfig. Puoi diagnosticare le configurazioni errate su uno di questi oggetti utilizzando kubectl.

  1. Recupera lo stato attuale.

    Per WorkloadCertificateConfig:

    kubectl get WorkloadCertificateConfig default -o yaml
    

    Per TrustConfig:

    kubectl get TrustConfig default -o yaml
    
  2. Controlla l'output dello stato. Un oggetto valido avrà una condizione con type: Ready e status: "True".

    status:
      conditions:
      - lastTransitionTime: "2021-03-04T22:24:11Z"
        message: WorkloadCertificateConfig is ready
        observedGeneration: 1
        reason: ConfigReady
        status: "True"
        type: Ready
    

    Per gli oggetti non validi viene visualizzato status: "False". I campireasone message contengono ulteriori dettagli sulla risoluzione dei problemi.

I CSR non sono approvati

Se si verifica un problema durante la procedura di approvazione del CSR, puoi controllare i dettagli dell'errore nelle condizioni type: Approved e type: Issued del CSR.

  1. Elenca i CSR pertinenti utilizzando kubectl:

    kubectl get csr \
      --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
    
  2. Scegli un CSR che sia Approved e non Issued oppure che non sia Approved.

  3. Visualizza i dettagli della CSR selezionata utilizzando kubectl:

    kubectl get csr CSR_NAME -o yaml
    

    Sostituisci CSR_NAME con il nome del CSR che hai scelto.

Un CSR valido ha una condizione con type: Approved e status: "True" e un certificato valido nel campo status.certificate:

status:
  certificate: <base64-encoded data>
  conditions:
  - lastTransitionTime: "2021-03-04T21:58:46Z"
    lastUpdateTime: "2021-03-04T21:58:46Z"
    message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
    reason: AutoApproved
    status: "True"
    type: Approved

Le informazioni per la risoluzione dei problemi relativi ai CSR non validi vengono visualizzate nei campi message e reason.

Le applicazioni non possono utilizzare le credenziali mTLS emesse

  1. Verifica che il certificato non sia scaduto:

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
    
  2. Verifica che il tipo di chiave utilizzato sia supportato dalla tua applicazione.

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
    
  3. Verifica che l'autorità di certificazione emittente utilizzi la stessa famiglia di chiavi della chiave del certificato.

    1. Visualizza lo stato dell'istanza del servizio CA (Anteprima):

      gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \
        --location ISSUING_CA_LOCATION
      

      Sostituisci quanto segue:

      • ISSUING_CA_TYPE: il tipo di CA emittente, che deve essere subordinates o roots.
      • ISSUING_CA_NAME: il nome della CA emittente.
      • ISSUING_CA_LOCATION: la regione della CA emittente.
    2. Verifica che keySpec.algorithm nell'output sia lo stesso algoritmo di chiave che hai definito nel WorkloadCertificateConfig manifest YAML. L'output è il seguente:

      config:
        ...
        subjectConfig:
          commonName: td-sub-ca
          subject:
            organization: TestOrgLLC
          subjectAltName: {}
      createTime: '2021-05-04T05:37:58.329293525Z'
      issuingOptions:
        includeCaCertUrl: true
      keySpec:
        algorithm: RSA_PKCS1_2048_SHA256
       ...
      

I certificati vengono rifiutati

  1. Verifica che l'applicazione peer utilizzi lo stesso bundle di attendibilità per verificare il certificato.
  2. Verifica che il certificato non sia scaduto:

    cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
    
  3. Verifica che il codice client, se non utilizza l'API di ricaricamento delle credenziali gRPC Go, aggiorni periodicamente le credenziali dal file system.

  4. Verifica che i tuoi carichi di lavoro si trovino nello stesso dominio attendibile della CA. I certificati del mesh GKE supportano la comunicazione tra i carichi di lavoro in un singolo dominio attendibile.