Automatizzare la gestione dei certificati TLS per il gateway di ingresso di Cloud Service Mesh utilizzando Certificate Authority Service

Questo tutorial mostra agli operatori della piattaforma come utilizzare l'emittente di Certificate Authority Service per lo strumento cert-manager per automatizzare la gestione dei certificati TLS per il gateway di ingresso Cloud Service Mesh. I certificati consentono al gateway di ingresso di terminare il traffico HTTPS e di altro tipo TLS e mTLS proveniente da client nel tuo Virtual Private Cloud (VPC), ma al di fuori del mesh di servizi. Il tutorial presuppone una conoscenza di base di Kubernetes e dei certificati TLS.

Introduzione

Cloud Service Mesh esegue il provisioning dei certificati TLS per ogni workload nella rete mesh di servizi. Questi certificati consentono la comunicazione tra i workload nella rete mesh di servizi con crittografia e TLS (mTLS) con autenticazione reciproca. Una delle CA supportate rilascia e firma i certificati.

Tuttavia, Cloud Service Mesh non esegue il provisioning automatico dei certificati nel gateway di ingresso per il traffico che entra nel mesh di servizi. Una soluzione comune è utilizzare lo strumento open source cert-manager per automatizzare la gestione dei certificati del gateway di ingresso.

Lo strumento cert-manager richiede i certificati a un emittente, che rappresenta un'autorità di certificazione (CA). Certificate Authority Service (CA Service) è un servizio Google Cloud che ti consente di creare la tua CA privata. Lo strumento cert-manager può richiedere certificati da CA Service utilizzando l'emittente esterno open source per CA Service.

Un'autorità di certificazione privata può emettere certificati TLS che autenticano e criptano il traffico all'interno di una rete interna. I gateway di ingresso di Cloud Service Mesh vengono spesso configurati per consentire il traffico in entrata dai client all'interno della VPC, ma al di fuori del mesh di servizi. Per il traffico di rete interno, puoi utilizzare una CA privata nel servizio CA per emettere certificati per il gateway di ingresso.

Questo tutorial mostra come configurare lo strumento cert-manager e l'emittente CA Service per automatizzare il provisioning e il rinnovo dei certificati TLS per il gateway di ingresso. Lo strumento cert-manager esegue il provisioning dei certificati come risorse Kubernetes Secret di tipo TLS. Quando lo strumento cert-manager rinnova un certificato, aggiorna la risorsa Secret con un nuovo certificato. Il gateway di ingresso esegue il proxy Envoy e supporta il servizio di rilevamento dei secret (SDS) di Envoy. SDS consente al gateway di ingresso di iniziare a utilizzare un nuovo certificato senza richiedere all'amministratore di riavviare o ricaricare il processo.

I proxy sidecar che fanno parte del mesh possono ottenere certificati TLS dall'autorità di certificazione CA Service o Cloud Service Mesh. In questo tutorial, utilizzi il servizio CA sia per i certificati del proxy sidecar sia per quelli del gateway di ingresso. In questo modo puoi utilizzare una CA principale per tutti i certificati TLS.

Il seguente diagramma mostra le risorse di cui esegui il provisioning in questo tutorial. Esegui il provisioning di un bilanciatore del carico di rete passthrough interno per la porta di accesso. Il bilanciatore del carico di rete passthrough interno non è un proxy, quindi non termina le connessioni TCP né esegue handshake TLS. Inoltra invece le connessioni ai pod del deployment istio-ingressgateway.

Il secret hello-example-com-credential contiene un certificato e una chiave privata. Il gateway hello configura i pod del deployment istio-ingressgateway per utilizzare questo certificato e questa chiave privata per eseguire handshake TLS per le richieste con l'hostname hello.example.com.

gestione mtls con il servizio CA

I pod del deployment google-cas-issuer nel namespace cert-manager richiedi i certificati dalla CA che crei nel servizio CA. Creerai un'associazione di criteri di Identity and Access Management che consenta ai pod ca-service-isser di rubare l'identità di un account di servizio Google utilizzando la federazione delle identità per i carichi di lavoro per GKE. Puoi grante a questo account di servizio Google l'autorizzazione per richiedere certificati dalla tua CA nel servizio CA creando un'associazione di criteri IAM nel tuo pool di CA.

Obiettivi

Costi

Questo tutorial utilizza i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud potrebbero essere idonei per una prova gratuita.

Al termine di questo tutorial, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, vedi Pulizia.

Prima di iniziare

  1. Nella console Google Cloud, vai alla pagina di selezione del progetto, quindi seleziona o crea un progetto.

  2. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  3. Nella console Google Cloud, vai a Cloud Shell.

    Nella parte inferiore della console Google Cloud si apre una sessione Cloud Shell e viene visualizzato un prompt della riga di comando. Utilizza Cloud Shell per eseguire tutti i comandi di questo tutorial.

  4. Imposta il progetto della console Google Cloud che vuoi utilizzare per questo tutorial:

    gcloud config set core/project PROJECT_ID
    

    Sostituisci PROJECT_ID con l'ID del tuo progetto Cloud.

    Nella finestra di dialogo Autorizza Cloud Shell, fai clic su Autorizza. Se fai clic su Autorizza, consenti ai comandi gcloud eseguiti in Cloud Shell di utilizzare le tue credenziali utente per autenticarsi alle API Google.

  5. Abilita Resource Manager, GKE, GKE Hub, l'autorità di certificazione Cloud Service Mesh e le API di CA Service:

    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        gkehub.googleapis.com \
        meshca.googleapis.com \
        privateca.googleapis.com
    

Configura CA Service

In questa sezione, crei un'autorità di certificazione principale e due autorità di certificazione subordinate in CA Service. Una CA subordinata emette certificati per il gateway di ingresso e l'altra CA subordinata emette certificati per i proxy sidecar nel mesh.

Per semplicità, in questo tutorial utilizzerai lo stesso progetto per il cluster GKE e le CA principali e secondarie. Nel tuo ambiente, puoi utilizzare un progetto diverso per il cluster GKE e le CA.

  1. In Cloud Shell, crea un pool di CA da utilizzare per la CA radice:

    gcloud privateca pools create ROOT_CA_POOL \
        --location CA_LOCATION \
        --tier enterprise
    
    • ROOT_CA_POOL è il nome del pool di CA. Ad esempio, root-ca-pool-tutorial.
    • CA_LOCATION è la posizione del pool di CA. Ad esempio, us-central1.

    Puoi elencare le località del servizio CA disponibili utilizzando questo comando: gcloud privateca locations list

  2. Crea e attiva una CA radice:

    gcloud privateca roots create ROOT_CA \
        --auto-enable \
        --key-algorithm ec-p384-sha384 \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --subject "CN=Example Root CA, O=Example Organization" \
        --use-preset-profile root_unconstrained
    
    • ROOT_CA è il nome che vuoi utilizzare per la CA principale. Ad esempio, root-ca-tutorial.
  3. Crea un pool di CA da utilizzare per la CA subordinata che emette i certificati per il gateway di ingresso:

    gcloud privateca pools create SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --tier devops
    
    • SUBORDINATE_CA_POOL_GATEWAYS è il nome del pool di CA. Ad esempio, subordinate-ca-mtls-pool-gateways-tutorial.
  4. Crea e abilita la CA subordinata che emette i certificati per il gateway di ingresso:

    gcloud privateca subordinates create SUBORDINATE_CA_GATEWAYS \
        --auto-enable \
        --issuer-location CA_LOCATION \
        --issuer-pool ROOT_CA_POOL \
        --key-algorithm ec-p256-sha256 \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --subject "CN=Example Gateway mTLS CA, O=Example Organization" \
        --use-preset-profile subordinate_mtls_pathlen_0
    
    • SUBORDINATE_CA_GATEWAYS è il nome che vuoi utilizzare per la CA subordinata. Ad esempio, subordinate-ca-mtls-gateways-tutorial.
    • Il flag --use-preset-profile configura la CA subordinata in modo da utilizzare il profilo del certificato mTLS subordinato. Questo profilo consente alla CA subordinata di emettere sia i certificati TLS client sia quelli TLS del server per mTLS.

    Se vuoi che il gateway di ingresso utilizzi TLS semplice anziché mTLS, l'autorità di certificazione subordinata deve emettere solo certificati TLS del server. In questo caso, puoi utilizzare il profilo del certificato TLS del server secondario (subordinate_server_tls_pathlen_0).

  5. Crea un criterio di emissione dei certificati:

    cat << EOF > policy.yaml
    baselineValues:
      keyUsage:
        baseKeyUsage:
          digitalSignature: true
          keyEncipherment: true
        extendedKeyUsage:
          serverAuth: true
          clientAuth: true
      caOptions:
        isCa: false
    identityConstraints:
      allowSubjectPassthrough: false
      allowSubjectAltNamesPassthrough: true
      celExpression:
        expression: subject_alt_names.all(san, san.type == URI && san.value.startsWith("spiffe://PROJECT_ID.svc.id.goog/ns/") )
    EOF
    

    Questo criterio di emissione limita le CA a emettere solo certificati per i carichi di lavoro nel mesh.

  6. Crea un pool di CA da utilizzare per la CA subordinata che emette i certificati per i proxy sidecar nel mesh. Applica il criterio di emissione al pool di CA:

    gcloud privateca pools create SUBORDINATE_CA_POOL_SIDECARS \
     --issuance-policy policy.yaml \
     --location CA_LOCATION \
     --tier devops
    
    • SUBORDINATE_CA_POOL_SIDECARS è il nome del pool di CA. Ad esempio, subordinate-ca-mtls-pool-sidecars-tutorial.
  7. Crea e abilita la CA subordinata che emette i certificati ai proxy sidecar nel mesh:

    gcloud privateca subordinates create SUBORDINATE_CA_SIDECARS \
        --auto-enable \
        --issuer-location CA_LOCATION \
        --issuer-pool ROOT_CA_POOL \
        --key-algorithm ec-p256-sha256 \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --subject "CN=Example Sidecar mTLS CA, O=Example Organization" \
        --use-preset-profile subordinate_mtls_pathlen_0
    
    • SUBORDINATE_CA_GATEWAYS è il nome che vuoi utilizzare per la CA subordinata. Ad esempio, subordinate-ca-mtls-sidecars-tutorial.

Crea un cluster Google Kubernetes Engine

  1. In Cloud Shell, crea un cluster GKE:

    gcloud container clusters create CLUSTER_NAME \
        --enable-ip-alias \
        --num-nodes 4 \
        --release-channel regular \
        --scopes cloud-platform \
        --workload-pool PROJECT_ID.svc.id.goog \
        --zone ZONE
    

    Sostituisci CLUSTER_NAME con il nome che vuoi utilizzare per il cluster. Ad esempio, asm-ingress-cert-manager-ca-service.

    Sostituisci ZONE con la zona che vuoi utilizzare per il cluster. Ad esempio, us-central1-f.

    Tieni presente quanto segue sul comando:

    • Il flag --release-channel seleziona il canale di rilascio GKE per il cluster.
    • Sia Cloud Service Mesh che l'emittente del servizio CA per lo strumento cert-manager richiedono di impostare l'ambito cloud-platform sui nodi del cluster.
    • L'argomento --workload-pool attiva Workload Identity Federation for GKE, che consente all'account di servizio Kubernetes del gestore del servizio CA di rubare l'identità di un account di servizio Google. Questa rappresentazione significa che i pod di emittenti del servizio CA possono accedere all'API del servizio CA senza scaricare un file di chiavi per l'account di servizio Google.
  2. Concedi le autorizzazioni di amministratore del cluster al tuo account utente:

    kubectl create clusterrolebinding cluster-admin-binding \
        --clusterrole cluster-admin \
        --user $(gcloud config get-value core/account)
    

    Per creare le regole del controllo controllo dell'accesso basato su ruoli (RBAC) per Cloud Service Mesh e installare lo strumento cert-manager, devi disporre delle autorizzazioni fornite dal cluster-admin ClusterRole di Kubernetes.

Installa il piano di controllo di Anthos Service Mesh

In questo tutorial, installi Cloud Service Mesh gestito per un cluster GKE su Google Cloud, con tutte le risorse in un progetto. Nel tuo ambiente, puoi applicare la soluzione descritta in questo documento utilizzando Cloud Service Mesh gestito o un control plane all'interno del cluster.

Cloud Service Mesh offre una serie di opzioni di installazione per diversi scenari. Dopo aver completato questo tutorial, ti consigliamo di consultare le guide all'installazione per selezionare l'opzione più adatta al tuo ambiente.

  1. In Cloud Shell, scarica lo strumento di installazione asmcli:

    curl --location --output asmcli https://storage.googleapis.com/csm-artifacts/asm/asmcli_1.12
    
    chmod +x asmcli
    

    Utilizza asmcli per installare il control plane di Cloud Service Mesh.

  2. Installa il piano di controllo di Cloud Service Mesh:

    ./asmcli install \
        --ca gcp_cas \
        --ca_pool projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_SIDECARS \
        --channel regular \
        --cluster_location ZONE \
        --cluster_name CLUSTER_NAME \
        --enable_all \
        --enable_registration \
        --fleet_id PROJECT_ID \
        --managed \
        --output_dir asm-files \
        --project_id PROJECT_ID \
        --verbose
    

    L'installazione richiede diversi minuti. Al termine dell'installazione, viene visualizzato il seguente output:

    asmcli: Successfully installed ASM.`
    

Installa il gateway di ingresso

  1. In Cloud Shell, crea uno spazio dei nomi Kubernetes per il gateway di accesso:

    kubectl create namespace GATEWAY_NAMESPACE
    
    • GATEWAY_NAMESPACE è il nome dello spazio dei nomi che vuoi utilizzare per il gateway di ingresso. Ad esempio, istio-ingress.
  2. Prenota un indirizzo IP interno statico da utilizzare per il bilanciatore del carico di rete passthrough interno del gateway di ingresso:

    LOAD_BALANCER_IP=$(gcloud compute addresses create \
        asm-ingress-gateway-ilb \
        --region REGION \
        --subnet default \
        --format 'value(address)')
    
    • Sostituisci REGION con la regione contenente la o le zone utilizzate dai nodi del cluster GKE. Ad esempio, se il tuo cluster utilizza la zona us-central1-f, sostituisci REGION con us-central1.

    Questo comando riserva un indirizzo IP dalla subnet predefinita nella regione specificata.

  3. Crea un manifest dell'operatore per il gateway di ingresso:

    cat << EOF > ingressgateway-operator.yaml
    apiVersion: install.istio.io/v1alpha1
    kind: IstioOperator
    metadata:
      name: ingressgateway-operator
      annotations:
        config.kubernetes.io/local-config: "true"
    spec:
      profile: empty
      revision: asm-managed
      components:
        ingressGateways:
        - name: istio-ingressgateway
          namespace: GATEWAY_NAMESPACE
          enabled: true
          k8s:
            overlays:
            - apiVersion: apps/v1
              kind: Deployment
              name: istio-ingressgateway
              patches:
              - path: spec.template.metadata.annotations
                value:
                  inject.istio.io/templates: gateway
              - path: spec.template.metadata.labels.sidecar\.istio\.io/inject
                value: "true"
              - path: spec.template.spec.containers[name:istio-proxy]
                value:
                  name: istio-proxy
                  image: auto
            service:
              loadBalancerIP: $LOAD_BALANCER_IP
            serviceAnnotations:
              networking.gke.io/load-balancer-type: Internal
              networking.gke.io/internal-load-balancer-allow-global-access: "true"
    EOF
    

    Tieni presente quanto segue in merito al manifest dell'operatore:

  4. Crea il manifest di installazione del gateway in ingresso utilizzando il manifest dell'operatore e lo strumento istioctl che lo script asmcli ha scaricato durante l'installazione del piano di controllo:

    ./asm-files/istioctl manifest generate \
        --filename ingressgateway-operator.yaml \
        --output ingressgateway
    
  5. Installa il gateway di ingresso:

    kubectl apply --recursive --filename ingressgateway/
    

Installa lo strumento cert-manager

  1. In Cloud Shell, scarica e applica il manifest di installazione dello strumento cert-manager:

    CERT_MANAGER_VERSION=v1.5.4
    
    curl --location --output cert-manager.yaml "https://github.com/jetstack/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml"
    
    kubectl apply --filename cert-manager.yaml
    

    L'installazione dello strumento cert-manager richiede circa un minuto.

Installa il controller dell'emittente del servizio CA

Il controller dell'emittente del servizio CA consente allo strumento cert-manager di richiedere certificati utilizzando il servizio CA. Il controller utilizza il meccanismo di espansione dello strumento cert-manager issuer esterno.

  1. In Cloud Shell, crea un account di servizio Google:

    gcloud iam service-accounts create CAS_ISSUER_GSA \
        --display-name "CA Service issuer for cert-manager"
    
    • CAS_ISSUER_GSA è il nome dell'account di servizio Google. Ad esempio, cert-manager-ca-service-issuer.

    Il controller dell'emittente del servizio Certificate Authority utilizza questo account di servizio Google per autenticarsi alle API di Certificate Authority Service.

  2. Crea un'associazione dei criteri di Identity and Access Management che consenta all'account di servizio Google del controller di emittenti di Certificate Authority Service di richiedere i certificati dal pool di CA contenente la CA subordinata:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
  3. Scarica il manifest di installazione del controller di emittenti di Certificate Authority Service:

    CAS_ISSUER_VERSION=v0.5.3
    
    curl --location --output ca-service-issuer.yaml "https://github.com/jetstack/google-cas-issuer/releases/download/${CAS_ISSUER_VERSION}/google-cas-issuer-${CAS_ISSUER_VERSION}.yaml"
    
  4. Crea un'associazione di criteri IAM per consentire all'account di servizio Kubernetes ksa-google-cas-issuer nello spazio dei nomi cert-manager di rubare l'identità dell'account di servizio Google (GSA) utilizzando la federazione delle identità per i carichi di lavoro per GKE:

    gcloud iam service-accounts add-iam-policy-binding \
     CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \
        --role roles/iam.workloadIdentityUser
    

    I pod del controller dell'emittente del CA Service utilizzano l'account di servizio Kubernetes ksa-google-cas-issuer.

  5. Installa il controller di emittente del servizio CA nel cluster GKE:

    kubectl apply --filename ca-service-issuer.yaml
    
  6. Aggiungi l'annotazione iam.gke.io/gcp-service-account della federazione delle identità per i carichi di lavoro per GKE all'account di servizio Kubernetes utilizzato dai pod del controller del gestore del servizio CA:

    kubectl annotate serviceaccount ksa-google-cas-issuer --namespace cert-manager \
       "iam.gke.io/gcp-service-account=CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com"
    

    Questa annotazione informa GKE che l'account di servizio Kubernetes può rubare l'identità dell'account di servizio Google per accedere alle API di Google.

Crea un emittente di certificati

  1. In Cloud Shell, crea e applica un manifest GoogleCASIssuer:

    cat << EOF > gateway-cas-issuer.yaml
    apiVersion: cas-issuer.jetstack.io/v1beta1
    kind: GoogleCASIssuer
    metadata:
      name: gateway-cas-issuer
      namespace: GATEWAY_NAMESPACE
    spec:
      caPoolId: SUBORDINATE_CA_POOL_GATEWAYS
      location: CA_LOCATION
      project: PROJECT_ID
    EOF
    
    kubectl apply --filename gateway-cas-issuer.yaml
    

    L'emittente consente allo strumento cert-manager di eseguire il provisioning dei certificati dal pool di CA subordinato nel tuo spazio dei nomi del gateway di ingresso

Deployment di un'applicazione di esempio

In questa sezione verifichi che lo strumento cert-manager possa utilizzare il Nucleo di emissione di CA Service per ottenere certificati da CA Service. Per verificare, esegui il deployment di un'applicazione di esempio con la configurazione del routing delle richieste e un certificato per il gateway di ingresso.

  1. In Cloud Shell, crea uno spazio dei nomi per le risorse dell'applicazione di esempio:

    cat << EOF > sample-app-namespace.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: APP_NAMESPACE
      annotations:
        mesh.cloud.google.com/proxy: '{"managed":"true"}'
      labels:
        istio.io/rev: asm-managed
    EOF
    
    kubectl apply --filename sample-app-namespace.yaml
    
    • APP_NAMESPACE è il nome dello spazio dei nomi per l'applicazione di esempio. Ad esempio, sample-app.

    L'annotazione mesh.cloud.google.com/proxy attiva il piano dati gestito per lo spazio dei nomi.

    L'etichetta istio.io/rev: asm-managed seleziona il canale di rilascio regolare per il piano di dati gestito nello spazio dei nomi dell'applicazione di esempio. Modifica il valore di questa etichetta se utilizzi i canali di rilascio rapido o stabile.

  2. Crea una risorsa Deployment per l'applicazione di esempio:

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello
      namespace: APP_NAMESPACE
      labels:
        app: hello
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello
      template:
        metadata:
          labels:
            app: hello
        spec:
          containers:
          - image: gcr.io/google-samples/hello-app:1.0
            name: hello-app
            ports:
            - containerPort: 8080
    EOF
    
    kubectl apply --filename deployment.yaml
    
  3. Crea una risorsa Service per l'applicazione di esempio:

    cat << EOF > service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: SERVICE_NAME
      namespace: APP_NAMESPACE
    spec:
      ports:
      - name: http-hello
        port: 8080
      selector:
        app: hello
      type: ClusterIP
    EOF
    
    kubectl apply --filename service.yaml
    
    • SERVICE_NAME è il nome del servizio. Ad esempio, hello.
  4. Crea una risorsa del certificato per il nome di dominio hello.example.com utilizzando l'emittente del certificato:

    cat << EOF > certificate.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: hello-example-com-certificate
      namespace: GATEWAY_NAMESPACE
    spec:
      secretName: hello-example-com-credential
      commonName: hello.example.com
      dnsNames:
      - hello.example.com
      duration: 24h
      renewBefore: 8h
      issuerRef:
        group: cas-issuer.jetstack.io
        kind: GoogleCASIssuer
        name: gateway-cas-issuer
    EOF
    
    kubectl apply --filename certificate.yaml
    

    Lo spazio dei nomi del certificato deve corrispondere a quello del gateway di ingresso. In genere, solo gli amministratori della piattaforma possono modificare le risorse in questo uri, poiché le modifiche possono influire sull'intero mesh di servizi. Lo strumento cert-manager crea la risorsa Secret per il certificato TLS nello stesso uri. Ciò significa che gli amministratori delle applicazioni non devono avere accesso allo spazio dei nomi del gateway di ingresso.

    Puoi aggiungere altri nomi host nell'elenco dnsNames nel certificato. Questi nomi host sono inclusi nel certificato come Nomi alternativi dell'oggetto (SAN).

  5. Crea una risorsa Gateway per l'applicazione di esempio:

    cat << EOF > gateway.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: GATEWAY_NAME
      namespace: GATEWAY_NAMESPACE
    spec:
      selector:
        istio: ingressgateway
      servers:
      - hosts:
        - APP_NAMESPACE/hello.example.com
        port:
          name: https-hello
          number: 443
          protocol: HTTPS
        tls:
          credentialName: hello-example-com-credential
          mode: MUTUAL
    EOF
    
    kubectl apply --filename gateway.yaml
    
    • GATEWAY_NAME è il nome del gateway. Ad esempio, hello.
    • Il campo credentialName nel gateway corrisponde al campo secretName nel certificato. Lo strumento cert-manager crea un segreto Kubernetes con il certificato TLS del servizio CA. Questo certificato consente al gateway di ingresso di terminare il traffico TLS destinato a hello.example.com.

    Il file manifest del gateway specifica TLS RECIPROCO (mTLS). Se vuoi configurare il gateway per TLS normale, imposta la modalità TLS del gateway su SIMPLE.

  6. Crea una risorsa VirtualService per l'applicazione di esempio:

    cat << EOF > virtual-service.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: hello
      namespace: APP_NAMESPACE
    spec:
      hosts:
      - hello.example.com
      gateways:
      - GATEWAY_NAMESPACE/GATEWAY_NAME
      http:
      - route:
        - destination:
            host: SERVICE_NAME
            port:
              number: 8080
    EOF
    
    kubectl apply --filename virtual-service.yaml
    

    Gateway e VirtualService utilizzano spazi dei nomi diversi. Questo pattern comune limita le modifiche al routing basato sull'host nel gateway agli amministratori della piattaforma che dispongono delle autorizzazioni per modificare le risorse nello spazio dei nomi del gateway di ingresso.

    Gli amministratori dell'applicazione con autorizzazioni per modificare VirtualService nell'ambito dello spazio dei nomi dell'applicazione di esempio possono modificare il routing in base ad altri campi della richiesta, ad esempio il percorso dell'URL, senza coordinarsi con gli amministratori della piattaforma.

Se vuoi esplorare altre opzioni di configurazione, leggi la documentazione dell'API per le risorse Certificate, Gateway e VirtualService.

Puoi applicare criteri di autenticazione e autorizzazione al traffico che entra nel mesh di servizi tramite il gateway in entrata. A tale scopo, leggi la documentazione delle API Istio PeerAuthentication e AuthorizationPolicy.

Verificare la soluzione

In questa sezione verifichi di poter inviare richieste HTTPS utilizzando mTLS all'applicazione di esempio dall'esterno del mesh di servizi. Per la verifica, crea un'istanza VM Compute Engine, richiedi un certificato TLS client dal servizio CA e utilizza questo certificato per autenticare la richiesta all'applicazione di esempio.

Devi disporre dell'accesso SSH all'istanza VM. La rete predefinita include una regola firewall che consente l'accesso SSH. Se non disponi dell'accesso SSH, consulta la documentazione delle regole firewall per creare una regola firewall che consenta le connessioni TCP in entrata sulla porta 22.

  1. In Cloud Shell, crea un account di servizio Google:

    gcloud iam service-accounts create CLIENT_VM_GSA \
        --display-name "CA Service tutorial VM instance service account"
    
    • CLIENT_VM_GSA è il nome dell'account di servizio Google. Ad esempio, cas-tutorial-client.

    Assegna questo account di servizio Google all'istanza VM Compute Engine.

  2. Concedi il ruolo CA Service Certificate Requester al pool CA secondario dei gateway all'account di servizio Google:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    

    Questo ruolo fornisce le autorizzazioni per richiedere certificati dal pool di CA.

  3. Crea un'istanza VM Compute Engine nella stessa VPC del cluster GKE:

    gcloud compute instances create cas-tutorial-client \
        --scopes cloud-platform \
        --service-account CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --zone ZONE
    

    L'istanza VM richiede l'ambito cloud-platform per accedere all'API CA Service.

  4. Salva l'indirizzo IP del bilanciatore del carico di rete passthrough interno del gateway di ingresso in un file:

    kubectl get services istio-ingressgateway \
       --namespace GATEWAY_NAMESPACE \
       --output jsonpath='{.status.loadBalancer.ingress[0].ip}' > ilb-ip.txt
    
  5. Salva il certificato di chiave pubblica della CA principale in un file:

    gcloud privateca roots describe ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --format 'value(pemCaCertificates)' > root-ca-cert.pem
    
  6. Copia il certificato CA principale e il file contenente l'indirizzo IP del bilanciatore del carico di rete passthrough interno del gateway di ingresso nell'istanza VM:

    gcloud compute scp root-ca-cert.pem ilb-ip.txt cas-tutorial-client:~ \
       --zone ZONE
    
  7. Connettiti all'istanza VM tramite SSH:

    gcloud compute ssh cas-tutorial-client --zone ZONE
    

    Esegui il resto dei comandi in questa sezione dalla sessione SSH.

  8. Installa i pacchetti ca-certificates e coreutils e gli strumenti a riga di comando curl,openssl e jq:

    sudo apt-get update --yes
    
    sudo apt-get install --yes ca-certificates coreutils curl jq openssl
    
  9. Crea una coppia di chiavi per il certificato TLS del client:

    openssl genrsa -out private-key.pem 2048
    
    openssl rsa -in private-key.pem -pubout -out public-key.pem
    
  10. Esegui una query sul server metadati per ottenere l'indirizzo email dell'identità dell'account di servizio Google associato all'istanza VM:

    GSA_EMAIL=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email)
    
  11. Crea un file JSON da utilizzare come corpo della richiesta quando richiedi un certificato TLS client dall'API Certificate Authority Service:

    cat << EOF > request.json
    {
      "config": {
        "publicKey": {
          "format": "PEM",
          "key": "$(base64 --wrap 0 public-key.pem)"
        },
        "subjectConfig": {
          "subject": {
            "commonName": "$(hostname --short)",
            "organization": "Example Organization"
          },
          "subjectAltName": {
            "dnsNames": [
              "$(hostname --fqdn)"
            ],
            "emailAddresses": [
              "$GSA_EMAIL"
            ]
          }
        },
        "x509Config": {
          "caOptions": {
            "isCa": false
          },
          "keyUsage": {
            "baseKeyUsage": {
              "digitalSignature": true,
              "keyEncipherment": true
            },
            "extendedKeyUsage": {
              "clientAuth": true
            }
          }
        }
      },
      "lifetime": "86400s"
    }
    EOF
    

    Per scoprire di più sui campi nella sezione di configurazione, consulta il tipo CertificateConfig nella documentazione dell'API CA Service.

  12. Richiedi un token di accesso OAuth 2.0 dal server di metadati:

    TOKEN=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | jq --raw-output ".access_token")
    

    Questo token di accesso fornisce le autorizzazioni concesse all'account servizio Google associato all'istanza VM.

  13. Richiedi un certificato TLS client dall'API CA Service e memorizza il corpo della risposta in un file:

    curl --silent --request POST \
        --header "Authorization: Bearer $TOKEN" \
        --header "Content-Type: application/json" \
        --data @request.json \
        --output response.json \
        "https://privateca.googleapis.com/v1/projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_GATEWAYS/certificates"
    

    Il comando utilizza il token di accesso per autenticare la richiesta dell'API.

  14. Salva il certificato client e la catena di certificati in un file:

    jq --raw-output --join-output ".pemCertificate , .pemCertificateChain[]" response.json > client-cert-chain.pem
    
  15. Utilizza curl per inviare una richiesta HTTPS dall'istanza VM all'applicazione di esempio:

    curl --cert client-cert-chain.pem --key private-key.pem \
        --cacert root-ca-cert.pem \
        --resolve hello.example.com:443:$(cat ilb-ip.txt) \
        --silent https://hello.example.com | head -n1
    

    L'output è il seguente:

    Hello, world!
    

    Questa risposta mostra che curl ha inviato correttamente la richiesta HTTPS utilizzando mTLS. L'applicazione di esempio ha risposto con il messaggio visualizzato nell'output del terminale.

    Il comando curl esegue le seguenti operazioni:

    • I flag --cert e --key chiedono a curl di utilizzare il certificato TLS e la chiave privata del client per autenticare la richiesta. Il file del certificato client contiene la catena completa dei certificati, dal certificato client all'autorità di certificazione radice.

    • Il flag --cacert indica a curl di verificare che la CA radice creata in questo tutorial o una delle sue CA subordinate abbia emesso il certificato del server.

      Se ometti questo flag, curl tenta di verificare il certificato del server utilizzando il bundle CA predefinito del tuo sistema operativo, ad esempio il pacchetto ca-certificates su Debian. La verifica non va a buon fine perché il bundle CA predefinito non include la CA principale creata in questo tutorial.

    • Il flag --resolve indica a curl di utilizzare l'indirizzo IP del bilanciatore del carico di rete passthrough interno come destinazione per le richieste all'host hello.example.com sulla porta 443.

      Se ometti questo flag, curl tenta di utilizzare il DNS per risolvere il nome hosthello.example.com. La risoluzione DNS non va a buon fine perché non esiste un entry DNS per questo nome host.

      Nel tuo ambiente, ti consigliamo di creare un record DNS A che indichi l'indirizzo IP del bilanciatore di carico di rete passthrough interno ($LOAD_BALANCER_IP). Crea questo record utilizzando Cloud DNS, seguendo la documentazione sulla gestione dei record.

    • Il flag --silent elimina i report sull'avanzamento del download della risposta nell'output del terminale.

    • Il comando invia l'output di curl a head -n1. Il risultato è che il risultato nel terminale include solo la prima riga del corpo della risposta.

  16. Esci dalla sessione SSH:

    exit
    

In questa sezione hai richiesto un certificato TLS client direttamente dall'API CA Service. Se il client è il gateway di uscita di un altro mesh di servizi in un cluster Kubernetes separato, puoi utilizzare lo strumento cert-manager e l'emittente di Certificate Authority Service con la stessa CA radice per fornire i certificati client al gateway di uscita.

In altre situazioni, puoi utilizzare strumenti come Hashicorp Vault, Terraform o gcloud per richiedere certificati TLS client per i carichi di lavoro al di fuori della rete mesh di servizi. Per saperne di più, consulta la documentazione di CA Service per le soluzioni di esempio e la documentazione di gcloud per CA Service.

(Facoltativo) Aggiungi i certificati CA all'archivio attendibile

Questa sezione facoltativa mostra come aggiungere certificati CA all'archivio dei certificati CA attendibili per la distribuzione Debian di Linux. Queste istruzioni si applicano anche alle distribuzioni derivate da Debian, come Ubuntu.

Se aggiungi i certificati CA a questo archivio, non devi specificare la posizione dei certificati CA attendibili quando invii richieste HTTPS utilizzando curl, Python, Go e Ruby.

  1. Connettiti all'istanza VM tramite SSH:

    gcloud compute ssh cas-tutorial-client --zone ZONE
    

    Esegui il resto dei comandi in questa sezione dalla sessione SSH.

  2. Copia il certificato CA radice nella directory/usr/local/share/ca-certificates e assicurati che il file abbia l'estensione.crt:

    sudo cp root-ca-cert.pem /usr/local/share/ca-certificates/cas-rootca.crt
    
  3. Imposta i permessi dei file in modo che tutti gli utenti possano leggere il file del certificato CA principale:

    sudo chmod 644 /usr/local/share/ca-certificates/cas-rootca.crt
    
  4. Esegui lo script update-ca-certificates:

    sudo update-ca-certificates
    

    Questo script aggiunge il certificato all'insieme di certificati attendibili nella directory /etc/ssl/certs e al file /etc/ssl/certs/ca-certificates.crt.

    L'output è il seguente:

    Updating certificates in /etc/ssl/certs...
    1 added, 0 removed; done.
    Running hooks in /etc/ca-certificates/update.d...
    done.
    
  5. Utilizza curl per inviare una richiesta HTTPS dall'istanza VM all'applicazione di esempio:

    curl --cert client-cert-chain.pem --key private-key.pem \
       --resolve hello.example.com:443:$(cat ilb-ip.txt) \
       --silent https://hello.example.com | head -n1
    

    L'output è il seguente:

    Hello, world!
    

    Questa risposta mostra che curl ha inviato correttamente la richiesta HTTPS utilizzando mTLS e ha convalidato il certificato TLS del server dal gateway di ingresso utilizzando l'archivio dei certificati CA predefinito.

  6. Esci dalla sessione SSH:

    exit
    

Risoluzione dei problemi

Se il controller dell'emittente del servizio CA non crea il segreto del certificato TLS, visualizza i log del controller dell'emittente del servizio CA:

kubectl logs deployment/google-cas-issuer --namespace cert-manager

Se riscontri problemi con l'installazione di Cloud Service Mesh, esegui lo strumento asmcli per convalidare il progetto Cloud e il cluster GKE.

Se riscontri altri problemi con questo tutorial, ti consigliamo di consultare questi documenti:

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi continui per le risorse utilizzate in questo tutorial, puoi eliminare il progetto o le singole risorse.

Elimina il progetto

  1. In Cloud Shell, elimina il progetto:

    gcloud projects delete PROJECT_ID
    

Elimina le risorse

Se vuoi mantenere il progetto Google Cloud utilizzato in questo tutorial, elimina le singole risorse:

  1. In Cloud Shell, annulla la registrazione del cluster GKE da GKE Hub:

    gcloud container hub memberships unregister CLUSTER_NAME \
        --gke-cluster ZONE/CLUSTER_NAME
    
  2. Elimina il cluster GKE:

    gcloud container clusters delete CLUSTER_NAME \
        --zone ZONE --async --quiet
    
  3. Elimina le associazioni dei criteri IAM nel pool di CA secondario:

    gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
    gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
  4. Disattiva e pianifica l'eliminazione delle CA subordinate e della CA radice:

    gcloud privateca subordinates disable SUBORDINATE_CA_GATEWAYS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --quiet
    
    gcloud privateca subordinates delete SUBORDINATE_CA_GATEWAYS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --ignore-active-certificates \
        --quiet
    
    gcloud privateca subordinates disable SUBORDINATE_CA_SIDECARS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --quiet
    
    gcloud privateca subordinates delete SUBORDINATE_CA_SIDECARS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --ignore-active-certificates \
        --quiet
    
    gcloud privateca roots disable ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --quiet
    
    gcloud privateca roots delete ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --ignore-active-certificates \
        --quiet
    
  5. Elimina l'associazione della policy IAM per l'account di servizio Google del controller di emittenti di servizi CA:

    gcloud iam service-accounts remove-iam-policy-binding \
        CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \
        --role roles/iam.workloadIdentityUser
    
  6. Elimina gli account di servizio Google:

    gcloud iam service-accounts delete --quiet \
        CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com
    
    gcloud iam service-accounts delete --quiet \
        CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com
    
  7. Elimina l'indirizzo IP del bilanciatore del carico riservato:

    gcloud compute addresses delete asm-ingress-gateway-ilb \
        --region REGION --quiet
    
  8. Elimina l'istanza VM di Compute Engine:

    gcloud compute instances delete cas-tutorial-client \
        --zone ZONE --quiet
    

Passaggi successivi