Questo tutorial mostra come utilizzare Cloud Service Mesh e altri controlli di Google Cloud per proteggere il traffico in uscita (in uscita) dai carichi di lavoro di cui è stato eseguito il deployment in un cluster Google Kubernetes Engine. Il tutorial è inteso come complemento delle best practice per l'utilizzo dei gateway in uscita di Cloud Service Mesh sui cluster GKE.
Il pubblico di destinazione di questo tutorial include rete, piattaforma e tecnici della sicurezza che amministrano i cluster di Google Kubernetes Engine utilizzati da uno o team di distribuzione del software. I controlli descritti qui sono particolarmente utili per le organizzazioni che devono dimostrare la conformità alle normative, ad esempio GDPR e PCI.
Obiettivi
- Configura l'infrastruttura per l'esecuzione di Cloud Service Mesh:
- Rete VPC personalizzata e subnet privata
- Cloud NAT per l'accesso a internet
- Cluster GKE privato con un pool di nodi aggiuntivo per i pod del gateway in uscita
- Regole firewall VPC in uscita restrittive; solo i nodi gateway possono raggiungere host esterni
- Accesso privato Google per connessione a Container Registry e API di Google
- Installa Cloud Service Mesh.
- Installa i proxy gateway in uscita in esecuzione su un pool di nodi dedicato.
- Configura le regole di routing multi-tenant per il traffico esterno tramite
gateway in uscita:
- Le applicazioni nello spazio dei nomi
team-x
possono connettersi aexample.com
- Le applicazioni nello spazio dei nomi
team-y
possono connettersi ahttpbin.org
- Le applicazioni nello spazio dei nomi
- Utilizza la risorsa
Sidecar
per limitare l'ambito del proxy sidecar configurazione in uscita per ogni spazio dei nomi. - Configura i criteri di autorizzazione per applicare le regole in uscita.
- Configura il gateway in uscita per eseguire l'upgrade delle richieste HTTP semplici a TLS (TLS origine).
- Configura il gateway in uscita per il traffico TLS passthrough.
- Configurare i criteri di rete di Kubernetes come controllo aggiuntivo del traffico in uscita.
- Configura l'accesso diretto alle API di Google utilizzando Accesso privato Google e Identity and Access Management (IAM) autorizzazioni aggiuntive.
Costi
In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:
- Compute Engine
- Google Kubernetes Engine (GKE)
- Container Registry
- Cloud Service Mesh
- Cloud Load Balancing
- Cloud NAT
- Networking
- Cloud Storage
Per generare una stima dei costi basata sull'utilizzo previsto,
utilizza il Calcolatore prezzi.
Al termine del tutorial, puoi evitare i costi continui eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la sezione Pulizia.
Prima di iniziare
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.
-
In the Google Cloud console, activate Cloud Shell.
Crea una directory di lavoro da utilizzare durante l'esecuzione del tutorial:
mkdir -p ~/WORKING_DIRECTORY cd ~/WORKING_DIRECTORY
Crea uno script shell per inizializzare il tuo ambiente per il tutorial. Sostituisci e modifica le variabili in base al tuo progetto e alle tue preferenze. Esegui questo script con il comando
source
per reinizializzare l'ambiente se la sessione shell scade:cat << 'EOF' > ./init-egress-tutorial.sh #! /usr/bin/env bash PROJECT_ID=YOUR_PROJECT_ID REGION=REGION ZONE=ZONE gcloud config set project ${PROJECT_ID} gcloud config set compute/region ${REGION} gcloud config set compute/zone ${ZONE} EOF
Attiva
compute.googleapis.com
:gcloud services enable compute.googleapis.com --project=YOUR_PROJECT_ID
Rendi eseguibile lo script ed eseguilo con il comando
source
per per inizializzare il tuo ambiente. SelezionaY
se ti viene richiesto di abilitarecompute.googleapis.com
:chmod +x ./init-egress-tutorial.sh source ./init-egress-tutorial.sh
Configurazione dell'infrastruttura
Crea una rete VPC e una subnet
Crea una nuova rete VPC:
gcloud compute networks create vpc-network \ --subnet-mode custom
Crea una subnet per l'esecuzione del cluster con un server secondario preassegnato di indirizzi IP per pod e servizi. Accesso privato Google corrente abilitata in modo che le applicazioni con solo indirizzi IP interni possano raggiungere API e servizi Google:
gcloud compute networks subnets create subnet-gke \ --network vpc-network \ --range 10.0.0.0/24 \ --secondary-range pods=10.1.0.0/16,services=10.2.0.0/20 \ --enable-private-ip-google-access
Configurazione di Cloud NAT
Cloud NAT consente la connessione a carichi di lavoro senza indirizzi IP esterni destinazioni su internet e ricevere risposte in entrata da destinazioni.
Crea un router Cloud:
gcloud compute routers create nat-router \ --network vpc-network
Aggiungi una configurazione NAT al router:
gcloud compute routers nats create nat-config \ --router nat-router \ --nat-all-subnet-ip-ranges \ --auto-allocate-nat-external-ips
Crea account di servizio per ogni pool di nodi GKE
Crea due account di servizio per l'utilizzo da parte dei due nodi GKE piscine. Un account di servizio separato è assegnato a ogni pool di nodi, e applicare regole firewall VPC a nodi specifici.
Crea un account di servizio che verrà utilizzato dai nodi nel pool di nodi predefinito:
gcloud iam service-accounts create sa-application-nodes \ --description="SA for application nodes" \ --display-name="sa-application-nodes"
Crea un account di servizio che verrà utilizzato dai nodi nel pool di nodi del gateway:
gcloud iam service-accounts create sa-gateway-nodes \ --description="SA for gateway nodes" \ --display-name="sa-gateway-nodes"
Concedi le autorizzazioni agli account di servizio
Aggiungi un insieme minimo di ruoli IAM all'applicazione e al gateway account di servizio. Questi ruoli sono obbligatori per il logging, il monitoraggio il pull di immagini container private da Container Registry.
project_roles=(
roles/logging.logWriter
roles/monitoring.metricWriter
roles/monitoring.viewer
roles/storage.objectViewer
)
for role in "${project_roles[@]}"
do
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:sa-application-nodes@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="$role"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:sa-gateway-nodes@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="$role"
done
crea le regole firewall
Nei passaggi seguenti, applicherai una regola firewall alla rete VPC in modo che per impostazione predefinita, tutto il traffico in uscita viene negato. È richiesta una connettività specifica per affinché il cluster funzioni e i nodi gateway possano raggiungere le destinazioni all'esterno del VPC. Un insieme minimo di regole firewall specifiche esegue l'override regola predefinita di negazione di tutto per consentire la connettività necessaria.
Creare una regola firewall predefinita (a bassa priorità) per negare tutto il traffico in uscita la rete VPC:
gcloud compute firewall-rules create global-deny-egress-all \ --action DENY \ --direction EGRESS \ --rules all \ --destination-ranges 0.0.0.0/0 \ --network vpc-network \ --priority 65535 \ --description "Default rule to deny all egress from the network."
Crea una regola per consentire solo i nodi con il servizio gateway per connetterti a internet:
gcloud compute firewall-rules create gateway-allow-egress-web \ --action ALLOW \ --direction EGRESS \ --rules tcp:80,tcp:443 \ --target-service-accounts sa-gateway-nodes@${PROJECT_ID}.iam.gserviceaccount.com \ --network vpc-network \ --priority 1000 \ --description "Allow the nodes running the egress gateways to connect to the web"
Consenti ai nodi di raggiungere il piano di controllo Kubernetes:
gcloud compute firewall-rules create allow-egress-to-api-server \ --action ALLOW \ --direction EGRESS \ --rules tcp:443,tcp:10250 \ --target-service-accounts sa-application-nodes@${PROJECT_ID}.iam.gserviceaccount.com,sa-gateway-nodes@${PROJECT_ID}.iam.gserviceaccount.com \ --destination-ranges 10.5.0.0/28 \ --network vpc-network \ --priority 1000 \ --description "Allow nodes to reach the Kubernetes API server."
(Facoltativo) Questa regola firewall non è necessaria se utilizzi Managed Cloud Service Mesh.
Cloud Service Mesh utilizza i webhook quando inserisci i proxy sidecar in carichi di lavoro con scale out impegnativi. Consenti al server API GKE di chiamare i webhook esposti dal piano di controllo del mesh di servizi in esecuzione sui nodi:
gcloud compute firewall-rules create allow-ingress-api-server-to-webhook \ --action ALLOW \ --direction INGRESS \ --rules tcp:15017 \ --target-service-accounts sa-application-nodes@${PROJECT_ID}.iam.gserviceaccount.com,sa-gateway-nodes@${PROJECT_ID}.iam.gserviceaccount.com \ --source-ranges 10.5.0.0/28 \ --network vpc-network \ --priority 1000 \ --description "Allow the API server to call the webhooks exposed by istiod discovery"
Consenti la connettività in uscita tra nodi e pod in esecuzione sul in un cluster Kubernetes. GKE crea automaticamente con la regola in entrata corrispondente. Nessuna regola richiesta per la connettività al servizio poiché la catena di routing iptables converte sempre gli indirizzi IP del servizio in gli indirizzi IP dei pod.
gcloud compute firewall-rules create allow-egress-nodes-and-pods \ --action ALLOW \ --direction EGRESS \ --rules all \ --target-service-accounts sa-application-nodes@${PROJECT_ID}.iam.gserviceaccount.com,sa-gateway-nodes@${PROJECT_ID}.iam.gserviceaccount.com \ --destination-ranges 10.0.0.0/24,10.1.0.0/16 \ --network vpc-network \ --priority 1000 \ --description "Allow egress to other Nodes and Pods"
Consenti l'accesso agli insiemi riservati di indirizzi IP utilizzati da Accesso privato Google per la gestione delle API di Google, Container Registry e altri servizi:
gcloud compute firewall-rules create allow-egress-gcp-apis \ --action ALLOW \ --direction EGRESS \ --rules tcp \ --target-service-accounts sa-application-nodes@${PROJECT_ID}.iam.gserviceaccount.com,sa-gateway-nodes@${PROJECT_ID}.iam.gserviceaccount.com \ --destination-ranges 199.36.153.8/30 \ --network vpc-network \ --priority 1000 \ --description "Allow access to the VIPs used by Google Cloud APIs (Private Google Access)"
Consenti al servizio di controllo di integrità di Google Cloud di accedere ai pod in esecuzione nel cluster. Vedi i controlli di integrità: per ulteriori informazioni.
gcloud compute firewall-rules create allow-ingress-gcp-health-checker \ --action ALLOW \ --direction INGRESS \ --rules tcp:80,tcp:443 \ --target-service-accounts sa-application-nodes@${PROJECT_ID}.iam.gserviceaccount.com,sa-gateway-nodes@${PROJECT_ID}.iam.gserviceaccount.com \ --source-ranges 35.191.0.0/16,130.211.0.0/22,209.85.152.0/22,209.85.204.0/22 \ --network vpc-network \ --priority 1000 \ --description "Allow workloads to respond to Google Cloud health checks"
Configurazione dell'accesso privato alle API Google Cloud
L'accesso privato Google abilita VM e pod che hanno solo IP interno per accedere alle API e ai servizi Google. Sebbene le API e i servizi Google vengono forniti da IP esterni, il traffico proveniente dai nodi non lascia mai quando si utilizza l'accesso privato Google.
Abilita l'API Cloud DNS:
gcloud services enable dns.googleapis.com
Crea una zona DNS privata e un record CNAME
e A
in modo che i nodi e
i carichi di lavoro possono connettersi alle API e ai servizi Google
Accesso privato Google e nome host private.googleapis.com
:
gcloud dns managed-zones create private-google-apis \
--description "Private DNS zone for Google APIs" \
--dns-name googleapis.com \
--visibility private \
--networks vpc-network
gcloud dns record-sets transaction start --zone private-google-apis
gcloud dns record-sets transaction add private.googleapis.com. \
--name "*.googleapis.com" \
--ttl 300 \
--type CNAME \
--zone private-google-apis
gcloud dns record-sets transaction add "199.36.153.8" \
"199.36.153.9" "199.36.153.10" "199.36.153.11" \
--name private.googleapis.com \
--ttl 300 \
--type A \
--zone private-google-apis
gcloud dns record-sets transaction execute --zone private-google-apis
Configurazione dell'accesso privato a Container Registry
Crea una zona DNS privata e un record CNAME
e un record A
in modo che i nodi possano
connettersi a Container Registry utilizzando l'accesso privato Google e
Nome host gcr.io
:
gcloud dns managed-zones create private-gcr-io \
--description "private zone for Container Registry" \
--dns-name gcr.io \
--visibility private \
--networks vpc-network
gcloud dns record-sets transaction start --zone private-gcr-io
gcloud dns record-sets transaction add gcr.io. \
--name "*.gcr.io" \
--ttl 300 \
--type CNAME \
--zone private-gcr-io
gcloud dns record-sets transaction add "199.36.153.8" "199.36.153.9" "199.36.153.10" "199.36.153.11" \
--name gcr.io \
--ttl 300 \
--type A \
--zone private-gcr-io
gcloud dns record-sets transaction execute --zone private-gcr-io
Crea un cluster GKE privato
Individua l'indirizzo IP esterno di Cloud Shell per puoi aggiungerlo all'elenco delle reti autorizzate ad accedere ai tuoi server API del cluster:
SHELL_IP=$(dig TXT -4 +short @ns1.google.com o-o.myaddr.l.google.com)
Dopo un periodo di inattività, l'indirizzo IP esterno del tuo La VM Cloud Shell può cambiare. In questo caso, devi aggiornare di reti autorizzate di un cluster. Aggiungi il seguente comando al tuo script di inizializzazione:
cat << 'EOF' >> ./init-egress-tutorial.sh SHELL_IP=$(dig TXT -4 +short @ns1.google.com o-o.myaddr.l.google.com) gcloud container clusters update cluster1 \ --enable-master-authorized-networks \ --master-authorized-networks ${SHELL_IP//\"}/32 EOF
Abilita l'API Google Kubernetes Engine:
gcloud services enable container.googleapis.com
Crea un cluster GKE privato:
gcloud container clusters create cluster1 \ --enable-ip-alias \ --enable-private-nodes \ --release-channel "regular" \ --enable-master-authorized-networks \ --master-authorized-networks ${SHELL_IP//\"}/32 \ --master-ipv4-cidr 10.5.0.0/28 \ --enable-dataplane-v2 \ --service-account "sa-application-nodes@${PROJECT_ID}.iam.gserviceaccount.com" \ --machine-type "e2-standard-4" \ --network "vpc-network" \ --subnetwork "subnet-gke" \ --cluster-secondary-range-name "pods" \ --services-secondary-range-name "services" \ --workload-pool "${PROJECT_ID}.svc.id.goog" \ --zone ${ZONE}
La creazione del cluster richiede alcuni minuti. Il cluster ha di nodi privati con indirizzi IP interni. I pod e i servizi sono assegnati IP dagli intervalli secondari denominati che hai definito durante la creazione del VPC una subnet.
Cloud Service Mesh con un piano di controllo nel cluster richiede il cluster per utilizzare un tipo di macchina con almeno 4 vCPU.
Google consiglia di sottoscrivere un abbonamento al cluster "regular" rilasciare per garantire che i nodi eseguano una versione Kubernetes supportate da Cloud Service Mesh.
Per ulteriori informazioni sui prerequisiti per l'esecuzione di Cloud Service Mesh con un piano di controllo nel cluster, consulta prerequisiti nel cluster.
Per ulteriori informazioni sui requisiti e sulle limitazioni per l'esecuzione Cloud Service Mesh per la gestione funzionalità supportate da Cloud Service Mesh gestito.
Federazione delle identità dei carichi di lavoro per GKE è siano abilitate sul cluster. Cloud Service Mesh richiede la federazione delle identità per i carichi di lavoro per GKE e è il metodo consigliato per accedere alle API di Google da GKE carichi di lavoro con scale out impegnativi.
Crea un pool di nodi denominato gateway. Questo pool di nodi è il punto in cui il traffico in uscita del gateway VPN ad alta disponibilità. L'incompatibilità di
dedicated=gateway:NoSchedule
viene aggiunto a ogni nodo nel pool di nodi del gateway.gcloud container node-pools create "gateway" \ --cluster "cluster1" \ --machine-type "e2-standard-4" \ --node-taints dedicated=gateway:NoSchedule \ --service-account "sa-gateway-nodes@${PROJECT_ID}.iam.gserviceaccount.com" \ --num-nodes "1"
Incompatibilità e tolleranze di Kubernetes per garantire che solo i pod gateway in uscita vengano eseguiti su nodi nel nodo gateway piscina.
Scarica le credenziali in modo da poterti connettere al cluster con kubectl:
gcloud container clusters get-credentials cluster1
Verifica che i nodi del gateway abbiano l'incompatibilità corretta:
kubectl get nodes -l cloud.google.com/gke-nodepool=gateway -o yaml \ -o=custom-columns='name:metadata.name,taints:spec.taints[?(@.key=="dedicated")]'
L'output è simile al seguente:
name taints gke-cluster1-gateway-9d65b410-cffs map[effect:NoSchedule key:dedicated value:gateway]
Installazione e configurazione di Cloud Service Mesh
Segui una delle guide all'installazione per Cloud Service Mesh:
Dopo aver installato Cloud Service Mesh, interrompi e torna a questo tutorial senza installare gateway in entrata o in uscita.
Installa un gateway in uscita
Crea uno spazio dei nomi Kubernetes per il gateway in uscita:
kubectl create namespace istio-egress
Quando esegui il deployment del gateway in uscita, la configurazione verrà inserite in base a un'etichetta applicata al deployment o allo spazio dei nomi. Se il tag predefinito è configurato, etichetti lo spazio dei nomi con le etichette di inserimento predefinite , altrimenti puoi utilizzare etichetta di revisione per il piano di controllo installato. L'etichetta di revisione aggiunta dipende anche dal fatto che tu abbia eseguito o meno il deployment Cloud Service Mesh gestito o installato piano di controllo nel cluster.
Seleziona la scheda seguente in base al tipo di installazione (gestita o nel cluster).
Gestito
Utilizza il seguente comando per individuare le revisioni disponibili del piano di controllo:
kubectl -n istio-system get controlplanerevision
L'output è simile al seguente:
NAME RECONCILED STALLED AGE asm-managed True False 112m
Prendi nota del valore nella colonna
NAME
per il piano di controllo che vuoi utilizzare. In genere il canale di rilascio di Cloud Service Mesh corrisponde al canale di rilascio del tuo cluster Google Kubernetes Engine.Nel cluster
Per i piani di controllo nel cluster, il servizio
istiod
e il deployment in genere hanno un'etichetta di revisione simile aistio.io/rev=
, doveidentifica la versione di Cloud Service Mesh. La revisione diventa parte del nome del servizio
istiod
, ad esempio:istiod-.istio-system
Utilizza questo comando per individuare l'etichetta di revisione su
istiod
per dal piano di controllo nel cluster:kubectl get deploy -n istio-system -l app=istiod \ -o=jsonpath='{.items[*].metadata.labels.istio\.io\/rev}''{"\n"}'
(Facoltativo) Etichetta lo spazio dei nomi in modo che la configurazione del gateway venga inserite automaticamente. È sufficiente etichettare lo spazio dei nomi e deployment continuo. Ai fini di questo tutorial, etichetti entrambi per evitare avvisi dello strumento
istioctl analyze
.kubectl label namespace istio-egress istio.io/rev=REVISION
Crea un manifest dell'operatore per il gateway in uscita:
cat << EOF > egressgateway-operator.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: name: egressgateway-operator annotations: config.kubernetes.io/local-config: "true" spec: profile: empty revision: REVISION components: egressGateways: - name: istio-egressgateway namespace: istio-egress enabled: true values: gateways: istio-egressgateway: injectionTemplate: gateway tolerations: - key: "dedicated" operator: "Equal" value: "gateway" nodeSelector: cloud.google.com/gke-nodepool: "gateway" EOF
Scarica lo strumento
istioctl
. È necessario utilizzare la versione 1.16.2-asm.2 o successiva anche se utilizzi Cloud Service Mesh 1.15 o versioni precedenti. Consulta: Download della versione istioctl corretta.Dopo aver estratto l'archivio scaricato, imposta una variabile di ambiente di conservazione il percorso dello strumento
istioctl
e aggiungilo allo script di inizializzazione:ISTIOCTL=$(find "$(pwd -P)" -name istioctl) echo "ISTIOCTL=\"${ISTIOCTL}\"" >> ./init-egress-tutorial.sh
Crea il manifest di installazione del gateway in uscita utilizzando l'operatore manifest e
istioctl
:${ISTIOCTL} manifest generate \ --filename egressgateway-operator.yaml \ --output egressgateway \ --cluster-specific
Installa il gateway in uscita:
kubectl apply --recursive --filename egressgateway/
Verifica che il gateway in uscita sia in esecuzione su nodi nel nodo
gateway
pool:kubectl get pods -n istio-egress -o wide
I pod del gateway in uscita hanno
affinity
per i nodi nel pool di nodigateway
e una tolleranza che ne consente l'esecuzione su nodi gateway incompatibili. Esamina l'affinità dei nodi e le tolleranze per i pod del gateway in uscita:kubectl -n istio-egress get pod -l istio=egressgateway \ -o=custom-columns='name:metadata.name,node-affinity:spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms,tolerations:spec.tolerations[?(@.key=="dedicated")]'
L'output è simile al seguente:
name node-affinity tolerations istio-egressgateway-754d9684d5-jjkdz [map[matchExpressions:[map[key:cloud.google.com/gke-nodepool operator:In values:[gateway]]]]] map[key:dedicated operator:Equal value:gateway]
Abilita logging degli accessi Envoy
I passaggi necessari per abilitare i log di accesso a Envoy dipendono da Cloud Service Mesh gestito o in-cluster:
Gestito
Segui le istruzioni per abilitare i log degli accessi nella versione gestita di Cloud Service Mesh.
Nel cluster
Segui le istruzioni per abilita i log degli accessi in Cloud Service Mesh nel cluster.
Preparazione della mesh e di un'applicazione di test
Assicurati che il protocollo TLS reciproco STRICT sia abilitato. Applica un valore predefinito Criterio
PeerAuthentication
per il mesh nello spazio dei nomiistio-system
:cat <<EOF | kubectl apply -f - apiVersion: "security.istio.io/v1beta1" kind: "PeerAuthentication" metadata: name: "default" namespace: "istio-system" spec: mtls: mode: STRICT EOF
Puoi eseguire l'override di questa configurazione creando
PeerAuthentication
in spazi dei nomi specifici.Crea spazi dei nomi da utilizzare per il deployment dei carichi di lavoro di test. Passaggi successivi in questo tutorial spiega come configurare diverse regole di routing in uscita per ogni spazio dei nomi.
kubectl create namespace team-x kubectl create namespace team-y
Etichetta gli spazi dei nomi in modo che possano essere selezionati dalla rete Kubernetes norme:
kubectl label namespace team-x team=x kubectl label namespace team-y team=y
Affinché Cloud Service Mesh possa inserire automaticamente i file collaterali proxy, devi Imposta l'etichetta di revisione del piano di controllo sugli spazi dei nomi dei carichi di lavoro:
kubectl label ns team-x istio.io/rev=REVISION kubectl label ns team-y istio.io/rev=REVISION
Crea un file YAML da utilizzare per effettuare deployment di test:
cat << 'EOF' > ./test.yaml apiVersion: v1 kind: ServiceAccount metadata: name: test --- apiVersion: v1 kind: Service metadata: name: test labels: app: test spec: ports: - port: 80 name: http selector: app: test --- apiVersion: apps/v1 kind: Deployment metadata: name: test spec: replicas: 1 selector: matchLabels: app: test template: metadata: labels: app: test spec: serviceAccountName: test containers: - name: test image: gcr.io/google.com/cloudsdktool/cloud-sdk:slim command: ["/bin/sleep", "infinity"] imagePullPolicy: IfNotPresent EOF
Esegui il deployment dell'applicazione di test nello spazio dei nomi
team-x
:kubectl -n team-x create -f ./test.yaml
Verifica che il deployment dell'applicazione di test sia stato eseguito su un nodo nell'impostazione predefinita e che venga inserito un container collaterale proxy. Ripeti quanto segue finché lo stato del pod non è
Running
:kubectl -n team-x get po -l app=test -o wide
L'output è simile al seguente:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES test-d5bdf6f4f-9nxfv 2/2 Running 0 19h 10.1.1.25 gke-cluster1-default-pool-f6c7a51f-wbzj
2 container su 2 sono
Running
. Un container è il test e l'altro è il collaterale proxy.Il pod è in esecuzione su un nodo nel pool di nodi predefinito.
Verifica che non sia possibile effettuare una richiesta HTTP dal test contenitore a un sito esterno:
kubectl -n team-x exec -it \ $(kubectl -n team-x get pod -l app=test -o jsonpath={.items..metadata.name}) \ -c test -- curl -v http://example.com
Viene generato un messaggio di errore dal proxy sidecar perché La regola firewall
global-deny-egress-all
nega la connessione upstream.
Utilizzo della risorsa Sidecar per limitare l'ambito della configurazione del proxy sidecar
Puoi utilizzare lo
Risorsa collaterale
per limitare l'ambito del listener in uscita configurato per il file collaterale
proxy. Per ridurre le dimensioni eccessive della configurazione e l'utilizzo della memoria, è buona norma
applica una risorsa Sidecar
predefinita per ogni spazio dei nomi.
Il proxy che Cloud Service Mesh esegue nel file collaterale è Envoy. Nella
Terminologia di Envoy,
un cluster
è un gruppo logicamente simile di endpoint upstream usati come
destinazioni per il bilanciamento del carico.
Controlla i cluster in uscita configurati nel proxy sidecar di Envoy per eseguendo il comando
istioctl proxy-config
:${ISTIOCTL} pc c $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}).team-x --direction outbound
Nell'elenco sono presenti circa 11 cluster Envoy, inclusi alcuni per il gateway in uscita.
Limita la configurazione del proxy alle route in uscita che sono state definite esplicitamente con voci di servizio nello spazio dei nomi in uscita e
team-x
. Applica una risorsaSidecar
a Spazio dei nomiteam-x
:cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: Sidecar metadata: name: default namespace: team-x spec: outboundTrafficPolicy: mode: REGISTRY_ONLY egress: - hosts: - 'istio-egress/*' - 'team-x/*' EOF
L'impostazione della modalità del criterio del traffico in uscita su
REGISTRY_ONLY
limita le configurazione proxy per includere solo gli host esterni che sono stati aggiunti esplicitamente al registro dei servizi del mesh definendo le voci di servizio.La configurazione di
egress.hosts
specifica che il proxy sidecar seleziona solo dallo spazio dei nomi in uscita, rese disponibili l'attributoexportTo
. "team-x/*
" include tutte le route che sono state configurate localmente nello spazio dei nomiteam-x
.Visualizzare i cluster in uscita configurati nel proxy sidecar di Envoy e e confrontarle con l'elenco dei cluster configurati prima dell'applicazione la risorsa
Sidecar
:${ISTIOCTL} pc c $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}).team-x --direction outbound
Vedrai dei cluster per il gateway in uscita e uno per il pod di test stesso.
Configurare Cloud Service Mesh per instradare il traffico attraverso il gateway in uscita
Configura un
Gateway
per il traffico HTTP sulla porta 80.Gateway
seleziona il proxy gateway in uscita di cui hai eseguito il deployment dello spazio dei nomi in uscita. La configurazioneGateway
viene applicata al traffico in uscita dello spazio dei nomi e gestisce il traffico per qualsiasi host.cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: egress-gateway namespace: istio-egress spec: selector: istio: egressgateway servers: - port: number: 80 name: https protocol: HTTPS hosts: - '*' tls: mode: ISTIO_MUTUAL EOF
Crea un
DestinationRule
per il gateway in uscita con TLS reciproco per l'autenticazione e la crittografia. Utilizza un'unica regola di destinazione condivisa per tutti per gli host esterni.cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: target-egress-gateway namespace: istio-egress spec: host: istio-egressgateway.istio-egress.svc.cluster.local subsets: - name: target-egress-gateway-mTLS trafficPolicy: tls: mode: ISTIO_MUTUAL EOF
Crea un
ServiceEntry
nello spazio dei nomi in uscita per registra example.com nel registro dei servizi del mesh perteam-x
spazio dei nomi:cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: example-com-ext namespace: istio-egress labels: # Show this service and its telemetry in the Cloud Service Mesh page of the Google Cloud console service.istio.io/canonical-name: example.com spec: hosts: - example.com ports: - number: 80 name: http protocol: HTTP - number: 443 name: tls protocol: TLS resolution: DNS location: MESH_EXTERNAL exportTo: - 'team-x' - 'istio-egress' EOF
Crea un'
VirtualService
per instradare il traffico a example.com tramite la gateway in uscita. Esistono due condizioni di corrispondenza: la prima condizione indirizza il traffico verso il gateway in uscita e il secondo indirizza il traffico dalla gateway in uscita all'host di destinazione. La proprietàexportTo
controlla gli spazi dei nomi che possono usare il servizio virtuale.cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: example-com-through-egress-gateway namespace: istio-egress spec: hosts: - example.com gateways: - istio-egress/egress-gateway - mesh http: - match: - gateways: - mesh port: 80 route: - destination: host: istio-egressgateway.istio-egress.svc.cluster.local subset: target-egress-gateway-mTLS port: number: 80 weight: 100 - match: - gateways: - istio-egress/egress-gateway port: 80 route: - destination: host: example.com port: number: 80 weight: 100 exportTo: - 'istio-egress' - 'team-x' EOF
Esegui
istioctl analyze
per verificare la presenza di errori di configurazione:${ISTIOCTL} analyze -n istio-egress --revision REVISION
L'output è simile al seguente:
✔ No validation issues found when analyzing namespace: istio-egress.
Invia diverse richieste attraverso il gateway in uscita al sito esterno:
for i in {1..4} do kubectl -n team-x exec -it $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- \ curl -s -o /dev/null -w "%{http_code}\n" http://example.com done
Verranno visualizzati i codici di stato
200
per tutte e quattro le risposte.Verifica che le richieste siano state indirizzate attraverso il gateway in uscita da controllare i log di accesso proxy. Controlla innanzitutto il log di accesso per il proxy il sidecar di cui è stato eseguito il deployment con l'applicazione di test:
kubectl -n team-x logs -f $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}) istio-proxy
Per ogni richiesta inviata viene visualizzata una voce di log simile alla seguente:
[2020-09-14T17:37:08.045Z] "HEAD / HTTP/1.1" 200 - "-" "-" 0 0 5 4 "-" "curl/7.67.0" "d57ea5ad-90e9-46d9-8b55-8e6e404a8f9b" "example.com" "10.1.4.12:8080" outbound|80||istio-egressgateway.istio-egress.svc.cluster.local 10.1.0.17:42140 93.184.216.34:80 10.1.0.17:60326 - -
Controlla anche il log di accesso al gateway in uscita:
kubectl -n istio-egress logs -f $(kubectl -n istio-egress get pod -l istio=egressgateway \ -o jsonpath="{.items[0].metadata.name}") istio-proxy
Per ogni richiesta inviata, viene visualizzata una voce di log di accesso al gateway in uscita simile al seguente:
[2020-09-14T17:37:08.045Z] "HEAD / HTTP/2" 200 - "-" "-" 0 0 4 3 "10.1.0.17" "curl/7.67.0" "095711e6-64ef-4de0-983e-59158e3c55e7" "example.com" "93.184.216.34:80" outbound|80||example.com 10.1.4.12:37636 10.1.4.12:8080 10.1.0.17:44404 outbound_.80_.target-egress-gateway-mTLS_.istio-egressgateway.istio-egress.svc.cluster.local -
Configura un routing diverso per un secondo spazio dei nomi
Configura il routing per un secondo host esterno per scoprire le differenze la connettività può essere configurata per team diversi.
Crea una risorsa
Sidecar
per lo spazio dei nomiteam-y
:cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: Sidecar metadata: name: default namespace: team-y spec: outboundTrafficPolicy: mode: REGISTRY_ONLY egress: - hosts: - 'istio-egress/*' - 'team-y/*' EOF
Esegui il deployment dell'applicazione di test nello spazio dei nomi
team-y
:kubectl -n team-y create -f ./test.yaml
Registra un secondo host esterno ed esportalo in
team-x
e lo spazio dei nomiteam-y
:cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: httpbin-org-ext namespace: istio-egress labels: # Show this service and its telemetry in the Cloud Service Mesh page of the Google Cloud console service.istio.io/canonical-name: httpbin.org spec: hosts: - httpbin.org ports: - number: 80 name: http protocol: HTTP - number: 443 name: tls protocol: TLS resolution: DNS location: MESH_EXTERNAL exportTo: - 'istio-egress' - 'team-x' - 'team-y' EOF
Creare un servizio virtuale per instradare il traffico a httpbin.org tramite la gateway in uscita:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: httpbin-org-through-egress-gateway namespace: istio-egress spec: hosts: - httpbin.org gateways: - istio-egress/egress-gateway - mesh http: - match: - gateways: - mesh port: 80 route: - destination: host: istio-egressgateway.istio-egress.svc.cluster.local subset: target-egress-gateway-mTLS port: number: 80 weight: 100 - match: - gateways: - istio-egress/egress-gateway port: 80 route: - destination: host: httpbin.org port: number: 80 weight: 100 exportTo: - 'istio-egress' - 'team-x' - 'team-y' EOF
Esegui
istioctl analyze
per verificare la presenza di errori di configurazione:${ISTIOCTL} analyze -n istio-egress --revision REVISION
Le voci della tabella sono:
✔ No validation issues found when analyzing namespace: istio-egress.
Effettua una richiesta a httpbin.org dall'app di prova
team-y
:kubectl -n team-y exec -it $(kubectl -n team-y get pod -l app=test -o \ jsonpath={.items..metadata.name}) -c test -- curl -I http://httpbin.org
Viene visualizzata una risposta
200 OK
.Effettua una richiesta anche a httpbin.org dall'app di prova
team-x
:kubectl -n team-x exec -it $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- curl -I http://httpbin.org
Viene visualizzata una risposta
200 OK
.Tentativo di effettuare una richiesta a example.com dallo spazio dei nomi
team-y
:kubectl -n team-y exec -it $(kubectl -n team-y get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- curl -I http://example.com
La richiesta non va a buon fine perché non è stata configurata alcuna route in uscita per Host
example.com
.
Utilizzo del criterio di autorizzazione per fornire ulteriore controllo sul traffico
In questo tutorial, i criteri di autorizzazione per il gateway in uscita vengono creati
nello istio-egress
spazio dei nomi. Puoi configurare Kubernetes RBAC in modo che
gli amministratori di rete possono accedere allo spazio dei nomi istio-egress
.
Crea un
AuthorizationPolicy
in modo che le applicazioni inteam-x
dello spazio dei nomi può connettersi a example.com ma non ad altri host esterni quando che invia richieste utilizzando la porta 80. Il valoretargetPort
corrispondente nella per i pod del gateway in uscita è 8080.cat <<EOF | kubectl apply -f - apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: egress-team-x-to-example-com namespace: istio-egress spec: action: ALLOW rules: - from: - source: namespaces: - 'team-x' to: - operation: hosts: - 'example.com' when: - key: destination.port values: ["8080"] EOF
Verifica di poter inviare una richiesta a example.com dal test applicazione nello spazio dei nomi
team-x
:kubectl -n team-x exec -it $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- curl -I http://example.com
Viene visualizzata una risposta
200 OK
.Prova a inviare una richiesta a httpbin.org dall'applicazione di test nel Spazio dei nomi
team-x
:kubectl -n team-x exec -it $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- curl -s -w " %{http_code}\n" \ http://httpbin.org
La richiesta non va a buon fine e viene restituito un messaggio
RBAC: access denied
e un errore 403 Codice di stato vietato. Potresti dover attendere qualche secondo perché spesso con un breve ritardo prima che i criteri di autorizzazione abbiano effetto.I criteri di autorizzazione offrono un controllo dettagliato sul traffico che viene consentito o non consentito. Applica il seguente criterio di autorizzazione per consentire test dell'app nello spazio dei nomi
team-y
per effettuare richieste a httpbin.org utilizzando a un determinato percorso dell'URL durante l'invio di richieste utilizzando la porta 80. La il valoretargetPort
corrispondente sui pod del gateway in uscita è 8080.cat <<EOF | kubectl apply -f - apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: egress-team-y-to-httpbin-teapot namespace: istio-egress spec: action: ALLOW rules: - from: - source: namespaces: - 'team-y' to: - operation: hosts: - httpbin.org paths: ['/status/418'] when: - key: destination.port values: ["8080"] EOF
Tentativo di connessione a httpbin.org dall'app di prova in
team-y
spazio dei nomi:kubectl -n team-y exec -it $(kubectl -n team-y get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- curl -s -w " %{http_code}\n" \ http://httpbin.org
La richiesta non va a buon fine e viene restituito un RBAC: messaggio di accesso negato e un errore 403 Codice di stato vietato.
Ora invia una richiesta a httpbin.org/status/418 dalla stessa app:
kubectl -n team-y exec -it $(kubectl -n team-y get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- curl http://httpbin.org/status/418
La richiesta ha esito positivo perché il percorso corrisponde al pattern nella criterio di autorizzazione. L'output è simile al seguente:
-=[ teapot ]=- _...._ .' _ _ `. | ."` ^ `". _, \_;`"---"`|// | ;/ \_ _/ `"""`
Originazione TLS al gateway in uscita
Puoi configurare i gateway in uscita per upgrade
(originare) HTTP semplice
a TLS o TLS reciproco. Consentire alle applicazioni di effettuare richieste HTTP semplici
offre diversi vantaggi quando viene utilizzato con TLS reciprocamente Istio e originazione TLS. Per
Per saperne di più, consulta la guida alle best practice.
La creazione di un
DestinationRule. The DestinationRule
specifica che il gateway ha origine da una connessione TLS a example.com.cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: example-com-originate-tls namespace: istio-egress spec: host: example.com subsets: - name: example-com-originate-TLS trafficPolicy: portLevelSettings: - port: number: 443 tls: mode: SIMPLE sni: example.com EOF
Aggiorna il servizio virtuale per example.com in modo che le richieste alla porta 80 sul gateway sono
upgraded
per TLS sulla porta 443 quando vengono inviati host di destinazione:cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: example-com-through-egress-gateway namespace: istio-egress spec: hosts: - example.com gateways: - mesh - istio-egress/egress-gateway http: - match: - gateways: - mesh port: 80 route: - destination: host: istio-egressgateway.istio-egress.svc.cluster.local subset: target-egress-gateway-mTLS port: number: 80 - match: - gateways: - istio-egress/egress-gateway port: 80 route: - destination: host: example.com port: number: 443 subset: example-com-originate-TLS weight: 100 EOF
Effettua diverse richieste a example.com dall'app di prova in
team-x
spazio dei nomi:for i in {1..4} do kubectl -n team-x exec -it $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- curl -I http://example.com done
Come in precedenza, le richieste hanno esito positivo con le risposte di
200 OK
.Controlla il log del gateway in uscita per verificare che il gateway abbia eseguito il routing richieste all'host di destinazione tramite le connessioni TLS di origine:
kubectl -n istio-egress logs -f $(kubectl -n istio-egress get pod -l istio=egressgateway \ -o jsonpath=" {.items[0].metadata.name}") istio-proxy
L'output è simile al seguente:
[2020-09-24T17:58:02.548Z] "HEAD / HTTP/2" 200 - "-" "-" 0 0 6 5 "10.1.1.15" "curl/7.67.0" "83a77acb-d994-424d-83da-dd8eac902dc8" "example.com" "93.184.216.34:443" outbound|443|example-com-originate-TLS|example.com 10.1.4.31:49866 10.1.4.31:8080 10.1.1.15:37334 outbound_.80_.target-egress-gateway-mTLS_.istio-egressgateway.istio-egress.svc.cluster.local -
Il sidecar del proxy ha inviato la richiesta al gateway utilizzando la porta 80 e TLS sulla porta 443 per inviare la richiesta all'host di destinazione.
Passthrough delle connessioni HTTPS/TLS
Le applicazioni esistenti potrebbero già utilizzare le connessioni TLS quando comunicare con servizi esterni. Puoi configurare il gateway in uscita per passare le connessioni TLS senza decriptarle.
Modifica la configurazione in modo che il gateway in uscita utilizzi TLS passthrough per le connessioni alla porta 443:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: egress-gateway namespace: istio-egress spec: selector: istio: egressgateway servers: - port: number: 80 name: https protocol: HTTPS hosts: - '*' tls: mode: ISTIO_MUTUAL - port: number: 443 name: tls protocol: TLS hosts: - '*' tls: mode: PASSTHROUGH EOF
Aggiorna
DestinationRule
che punta al gateway in uscita per aggiungere un secondo sottoinsieme per la porta 443 sul gateway. Questo nuovo sottoinsieme non utilizza TLS reciproco. TLS reciproco Istio non è supportato per il passthrough di TLS e connessioni a Internet. Le connessioni sulla porta 80 continuano a utilizzare mTLS:cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: target-egress-gateway namespace: istio-egress spec: host: istio-egressgateway.istio-egress.svc.cluster.local subsets: - name: target-egress-gateway-mTLS trafficPolicy: portLevelSettings: - port: number: 80 tls: mode: ISTIO_MUTUAL - name: target-egress-gateway-TLS-passthrough EOF
Aggiorna il servizio virtuale per example.com in modo che il traffico TLS sulla porta Viene fatto passare attraverso il gateway l'errore 443:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: example-com-through-egress-gateway namespace: istio-egress spec: hosts: - example.com gateways: - mesh - istio-egress/egress-gateway http: - match: - gateways: - mesh port: 80 route: - destination: host: istio-egressgateway.istio-egress.svc.cluster.local subset: target-egress-gateway-mTLS port: number: 80 - match: - gateways: - istio-egress/egress-gateway port: 80 route: - destination: host: example.com port: number: 443 subset: example-com-originate-TLS weight: 100 tls: - match: - gateways: - mesh port: 443 sniHosts: - example.com route: - destination: host: istio-egressgateway.istio-egress.svc.cluster.local subset: target-egress-gateway-TLS-passthrough port: number: 443 - match: - gateways: - istio-egress/egress-gateway port: 443 sniHosts: - example.com route: - destination: host: example.com port: number: 443 weight: 100 exportTo: - 'istio-egress' - 'team-x' EOF
Aggiorna il servizio virtuale per httpbin.org in modo che il traffico TLS sulla porta Viene fatto passare attraverso il gateway l'errore 443:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: httpbin-org-through-egress-gateway namespace: istio-egress spec: hosts: - httpbin.org gateways: - istio-egress/egress-gateway - mesh http: - match: - gateways: - mesh port: 80 route: - destination: host: istio-egressgateway.istio-egress.svc.cluster.local subset: target-egress-gateway-mTLS port: number: 80 weight: 100 - match: - gateways: - istio-egress/egress-gateway port: 80 route: - destination: host: httpbin.org port: number: 80 weight: 100 tls: - match: - gateways: - mesh port: 443 sniHosts: - httpbin.org route: - destination: host: istio-egressgateway.istio-egress.svc.cluster.local subset: target-egress-gateway-TLS-passthrough port: number: 443 - match: - gateways: - istio-egress/egress-gateway port: 443 sniHosts: - httpbin.org route: - destination: host: httpbin.org port: number: 443 weight: 100 exportTo: - 'istio-egress' - 'team-x' - 'team-y' EOF
Aggiungi un criterio di autorizzazione che accetti qualsiasi tipo di traffico inviato a la porta 443 del servizio gateway in uscita. Il valore di
targetPort
corrispondente attivato dei pod del gateway è 8443.cat <<EOF | kubectl apply -f - apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: egress-all-443 namespace: istio-egress spec: action: ALLOW rules: - when: - key: destination.port values: ["8443"] EOF
Esegui
istioctl analyze
per verificare la presenza di errori di configurazione:${ISTIOCTL} analyze -n istio-egress --revision REVISION
Le voci della tabella sono:
✔ No validation issues found when analyzing namespace: istio-egress.
Invia una semplice richiesta HTTP a example.com dall'applicazione di test in nello
team-x
spazio dei nomi:kubectl -n team-x exec -it $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- curl -I http://example.com
La richiesta ha esito positivo con una risposta
200 OK
.Ora effettua diverse richieste TLS (HTTPS) dall'applicazione di test nel Spazio dei nomi
team-x
:for i in {1..4} do kubectl -n team-x exec -it $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- curl -s -o /dev/null \ -w "%{http_code}\n" \ https://example.com done
Vengono visualizzate 200 risposte.
Esamina di nuovo il log del gateway in uscita:
kubectl -n istio-egress logs -f $(kubectl -n istio-egress get pod -l istio=egressgateway \ -o jsonpath="{.items[0].metadata.name}") istio-proxy
Vedrai voci di log simili alle seguenti:
[2020-09-24T18:04:38.608Z] "- - -" 0 - "-" "-" 1363 5539 10 - "-" "-" "-" "-" "93.184.216.34:443" outbound|443||example.com 10.1.4.31:51098 10.1.4.31:8443 10.1.1.15:57030 example.com -
La richiesta HTTPS è stata trattata come traffico TCP e trasmessa tramite la gateway all'host di destinazione, quindi nessuna informazione HTTP sarà inclusa nella log.
Utilizzo di Kubernetes NetworkPolicy come controllo aggiuntivo
Esistono molti scenari in cui un'applicazione può bypassare un proxy sidecar.
Puoi utilizzare Kubernetes NetworkPolicy
per specificare inoltre quali connessioni
carichi di lavoro. Dopo aver applicato un unico criterio di rete,
connessioni non consentite specificatamente vengono negate.
Questo tutorial considera solo le connessioni e i selettori in uscita per
criteri di rete. Se controlli il traffico in entrata con i criteri di rete autonomamente
devi creare criteri in entrata che corrispondano al traffico in uscita
criteri. Ad esempio, se consenti il traffico in uscita dai carichi di lavoro nell'area team-x
nello spazio dei nomi team-y
, devi consentire anche il traffico in entrata nello spazio dei nomi team-y
dello spazio dei nomi team-x
.
Consenti ai carichi di lavoro e ai proxy di cui è stato eseguito il deployment nello spazio dei nomi
team-x
di connettiti aistiod
e al gateway in uscita:cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-egress-to-control-plane namespace: team-x spec: podSelector: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: "kubernetes.io/metadata.name": istio-system podSelector: matchLabels: istio: istiod - namespaceSelector: matchLabels: "kubernetes.io/metadata.name": istio-egress podSelector: matchLabels: istio: egressgateway EOF
Consenti ai carichi di lavoro e ai proxy di eseguire query sul DNS:
cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-egress-to-dns namespace: team-x spec: podSelector: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: "kubernetes.io/metadata.name": kube-system ports: - port: 53 protocol: UDP - port: 53 protocol: TCP EOF
Consenti ai carichi di lavoro e ai proxy di connettersi agli IP che gestiscono Google API e servizi, inclusa l'autorità di certificazione Cloud Service Mesh:
cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-egress-to-google-apis namespace: team-x spec: podSelector: {} policyTypes: - Egress egress: - to: - ipBlock: cidr: 199.36.153.4/30 - ipBlock: cidr: 199.36.153.8/30 EOF
Consenti a carichi di lavoro e proxy di connettersi a GKE server metadati:
cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-egress-to-metadata-server namespace: team-x spec: podSelector: {} policyTypes: - Egress egress: - to: # For GKE data plane v2 - ipBlock: cidr: 169.254.169.254/32 - to: # For GKE data plane v1 - ipBlock: cidr: 127.0.0.1/32 # Prior to 1.21.0-gke.1000 - ipBlock: cidr: 169.254.169.252/32 # 1.21.0-gke.1000 and later ports: - protocol: TCP port: 987 - protocol: TCP port: 988 EOF
(Facoltativo) Consenti ai carichi di lavoro e ai proxy nello spazio dei nomi
team-x
di eseguire connessioni tra loro:cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-egress-to-same-namespace namespace: team-x spec: podSelector: {} ingress: - from: - podSelector: {} egress: - to: - podSelector: {} EOF
(Facoltativo) Consenti ai carichi di lavoro e ai proxy nello spazio dei nomi
team-x
di eseguire connessioni a carichi di lavoro di cui è stato eseguito il deployment da un team diverso:cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-egress-to-team-y namespace: team-x spec: podSelector: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: "kubernetes.io/metadata.name": team-y EOF
Le connessioni tra i proxy sidecar rimangono attive. Le connessioni esistenti sono non viene chiusa quando applichi un nuovo criterio di rete. Riavvia i carichi di lavoro in lo spazio dei nomi team-x per assicurarti che le connessioni esistenti siano chiuse:
kubectl -n team-x rollout restart deployment
Verifica di poter comunque effettuare una richiesta HTTP a example.com dal testa l'applicazione nello
team-x
spazio dei nomi:kubectl -n team-x exec -it $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- curl -I http://example.com
La richiesta ha esito positivo con una risposta
200 OK
.
Accesso diretto alle API di Google tramite accesso privato Google e autorizzazioni IAM
Le API e i servizi di Google sono esposti utilizzando indirizzi IP esterni. Quando i pod gli indirizzi IP alias nativi di VPC effettuano connessioni alle API di Google utilizzando Accesso privato Google, il traffico non esce mai dalla rete Google.
Quando hai configurato l'infrastruttura per questo tutorial, hai abilitato Accesso privato Google per la subnet utilizzata da GKE dei pod. Per consentire l'accesso agli indirizzi IP utilizzati dall'accesso privato Google: hai creato una route, una regola firewall VPC e una zona DNS privata. Questo consente ai pod di raggiungere direttamente le API di Google senza inviare traffico attraverso il gateway in uscita. Puoi controllare quali API sono disponibili per specifici gli account di servizio Kubernetes (e quindi gli spazi dei nomi) Federazione delle identità dei carichi di lavoro per GKE e o IAM. L'autorizzazione Istio non ha effetto perché il traffico in uscita Gateway non gestisce le connessioni alle API di Google.
Prima che i pod possano chiamare le API di Google, devi utilizzare IAM per concedere autorizzazioni aggiuntive. Il cluster che usi per questo tutorial è configurato per usare Federazione delle identità per i carichi di lavoro per GKE, che consente a un account di servizio Kubernetes di agire Account di servizio Google.
Crea un account di servizio Google da utilizzare per la tua applicazione:
gcloud iam service-accounts create sa-test-app-team-x
Consenti all'account di servizio Kubernetes di impersonare il servizio Google :
gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:${PROJECT_ID}.svc.id.goog[team-x/test]" \ sa-test-app-team-x@${PROJECT_ID}.iam.gserviceaccount.com
Annota l'account di servizio Kubernetes per l'app di test nella
team-x
con l'indirizzo email dell'account di servizio Google:cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: annotations: iam.gke.io/gcp-service-account: sa-test-app-team-x@${PROJECT_ID}.iam.gserviceaccount.com name: test namespace: team-x EOF
Il pod dell'applicazione di test deve essere in grado di accedere ai metadati Google server (in esecuzione come DaemonSet) per ottenere credenziali temporanee per le chiamate API di Google. Crea una voce di servizio per GKE server metadati:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: metadata-google-internal namespace: istio-egress labels: # Show this service and its telemetry in the Cloud Service Mesh page of the Google Cloud console service.istio.io/canonical-name: metadata.google.internal spec: hosts: - metadata.google.internal ports: - number: 80 name: http protocol: HTTP - number: 443 name: tls protocol: TLS resolution: DNS location: MESH_EXTERNAL exportTo: - 'istio-egress' - 'team-x' EOF
Crea anche una voce di servizio per private.googleapis.com e storage.googleapis.com:
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1beta1 kind: ServiceEntry metadata: name: private-googleapis-com namespace: istio-egress labels: # Show this service and its telemetry in the Cloud Service Mesh page of the Google Cloud console service.istio.io/canonical-name: googleapis.com spec: hosts: - private.googleapis.com - storage.googleapis.com ports: - number: 80 name: http protocol: HTTP - number: 443 name: tls protocol: TLS resolution: DNS location: MESH_EXTERNAL exportTo: - 'istio-egress' - 'team-x' EOF
Verifica che l'account di servizio Kubernetes sia configurato correttamente per fungere da account di servizio Google:
kubectl -n team-x exec -it $(kubectl -n team-x get pod -l app=test \ -o jsonpath={.items..metadata.name}) -c test -- gcloud auth list
Vedrai l'account di servizio Google elencato come unica identità attiva.
Crea un file di test in un bucket Cloud Storage:
echo "Hello, World!" > /tmp/hello gcloud storage buckets create gs://${PROJECT_ID}-bucket gcloud storage cp /tmp/hello gs://${PROJECT_ID}-bucket/
Concedi all'account di servizio l'autorizzazione a elencare e visualizzare i file nel del bucket:
gcloud storage buckets add-iam-policy-binding gs://${PROJECT_ID}-bucket/ \ --member=serviceAccount:sa-test-app-team-x@${PROJECT_ID}.iam.gserviceaccount.com \ --role=roles/storage.objectViewer
Verifica che l'applicazione di test possa accedere al bucket di test:
kubectl -n team-x exec -it \ $(kubectl -n team-x get pod -l app=test -o jsonpath={.items..metadata.name}) \ -c test \ -- gcloud storage cat gs://${PROJECT_ID}-bucket/hello
Le voci della tabella sono:
Hello, World!
Esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse usati in questo tutorial, completa i passaggi nelle seguenti sezioni:
Elimina il progetto
Il modo più semplice per eliminare la fatturazione è quello di eliminare il progetto
nel tutorial.
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Passaggi successivi
- Leggi guida alle best practice per gli annunci companion.
- Consulta il GKE di protezione avanzata.
- Scopri come automatizzare la gestione dei certificati TLS per Cloud Service Mesh gateway in entrata mediante il servizio CA.
- Scopri come gestire la configurazione e i criteri in tutti i tuoi dell'infrastruttura con Gestione della configurazione di GKE Enterprise.
- Per altre architetture di riferimento, diagrammi e best practice, esplora il Centro architetture cloud.