Utilizzo di Istio come programma autonomo

Scopri come installare Istio come programma standalone sui cluster creati con Kubernetes Engine (OKE).

Questo argomento fornisce un esempio di come installare Istio come programma standalone sui cluster creati con Kubernetes Engine (OKE). Inoltre, sono dimostrate le caratteristiche chiave di OKE e Istio.

Gli argomenti trattati includono:

Tenere presente che i prodotti mesh di servizio (come Istio e Linkerd) sono supportati quando si utilizza il plugin CNI per il pod networking VCN nativo OCI. Si noti che, ad eccezione del componente aggiuntivo Istio, il supporto è attualmente limitato a Oracle Linux 7 (è previsto il supporto per Oracle Linux 8). L'add-on Istio è supportato sia da Oracle Linux 7 che da Oracle Linux 8. I nodi di lavoro devono eseguire Kubernetes 1.26 (o versioni successive).

Nota

È possibile utilizzare Istio con i pool di nodi gestiti, ma non con i pool di nodi virtuali.

Installazione di Istio come programma standalone

Per iniziare a utilizzare Istio, creare un cluster OKE o utilizzare un cluster OKE esistente, quindi installare Istio. Le sezioni riportate di seguito illustrano i passaggi per installare e testare la configurazione Istio. Per l'elenco completo delle opzioni di installazione, consultare questa pagina.

Creazione di un cluster OKE

Creare un cluster OKE.

  1. Se non è già stato fatto, creare un cluster OKE all'interno della tenancy OCI. Per creare un cluster OKE sono disponibili più opzioni. L'opzione più semplice è la procedura guidata Creazione rapida nella console Web.
  2. Per accedere al cluster OKE sul sistema locale, installare kubectl e oci-cli.
  3. Accedere al cluster OKE dalla riga di comando utilizzando kubectl impostando il file kubeconfig e assicurarsi che kubectl possa accedere al cluster.

Scarica Istio dalla riga di comando

Segui questi passaggi per scaricare Istio dalla riga di comando.

  1. Scaricare Istio eseguendo il seguente comando:
    curl -L https://istio.io/downloadIstio | sh -
  2. Spostarsi nella directory dei pacchetti Istio. Ad esempio, se il pacchetto è istio-1.11.2:
    cd istio-1.11.2
  3. Aggiungere lo strumento client istioctl a PATH per la workstation.
    export PATH=$PWD/bin:$PATH
  4. Verificare se il cluster soddisfa i requisiti di installazione Istio eseguendo il controllo preliminare:
    istioctl x precheck

Installazione di Istio con istioctl

Installare Istio con istioctl utilizzando il seguente comando:
istioctl install

Esecuzione dell'applicazione Bookinfo

Il progetto Istio fornisce l'applicazione Bookinfo come un modo per dimostrare le caratteristiche di Istio. L'applicazione visualizza informazioni su un libro, simili a una singola voce di catalogo di un negozio di libri online. Ogni pagina del libro contiene una descrizione del libro, dettagli sul libro (ISBN, numero di pagine), e alcune recensioni del libro. Per ulteriori informazioni sull'applicazione Bookinfo, vedere i documenti Bookinfo qui.

Diagramma dell'applicazione Bookinfo

Come si può vedere dal diagramma, l'applicazione Bookinfo è composta da quattro microservizi.

  • Servizio pagina prodotto: chiama i servizi Dettagli e Revisioni per creare una pagina prodotto.
  • Servizio dettagli: restituisce le informazioni sul registro.
  • Servizio revisioni: restituisce le revisioni dei registri e chiama il servizio Valutazioni.
  • Servizio rating: restituisce le informazioni sulla classificazione per una revisione del registro.

Per installare ed eseguire l'applicazione Bookinfo, procedere come segue.

  1. Assegnare un'etichetta allo spazio di nomi che ospita l'applicazione con istio-injection=enabled.
    kubectl label namespace default istio-injection=enabled
  2. Distribuzione dell'applicazione Bookinfo di esempio.
    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
  3. Verificare che tutti i servizi e i pod siano in esecuzione.
    kubectl get services
    kubectl get pods
  4. Verificare che l'applicazione sia in esecuzione inviando un comando curl da un pod.
    kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
  5. Rendere l'applicazione accessibile dall'esterno del cluster.
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  6. Verificare che l'applicazione stia utilizzando il gateway. Determinare INGRESS_HOST e INGRESS_PORT utilizzando queste istruzioni.
    curl -s "http://${INGRESS_HOST}:${INGRESS_PORT}/productpage" | grep -o "<title>.*</title>"

Aprire inoltre l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser per visualizzare la pagina Web Bookinfo. Aggiornare la pagina più volte per visualizzare diverse versioni delle recensioni mostrate nella pagina del prodotto.

Aggiunta di applicazioni di integrazione Istio

Istio si integra bene con diverse applicazioni popolari correlate a Kubernetes.

Prometeo

Istio fornisce un'installazione di esempio di base per ottenere rapidamente Prometheus attivo e funzionante.

kubectl apply -f samples/addons/prometheus.yaml

In alternativa, installare prometheus e configurarlo per analizzare le metriche Istio.

Per il monitoraggio su scala di produzione con Prometheus, vedere Utilizzo di Prometheus per il monitoraggio su scala di produzione.

Grafana

Istio fornisce un'installazione di esempio di base per rendere Grafana operativo rapidamente. Tutte le dashboard Istio sono incluse nell'installazione.

kubectl apply -f samples/addons/grafana.yaml

In alternativa, installare Grafana separatamente. È inoltre possibile importare i dashboard preconfigurati di Instio.

Jaeger

Istio fornisce un'installazione di esempio di base per ottenere rapidamente Jaeger attivo e funzionante.

kubectl apply -f samples/addons/jaeger.yaml

In alternativa, installare Jaeger separatamente e configurare Istio per inviare trace alla distribuzione Jaeger.

Zipkin

Istio fornisce un'installazione di esempio di base per ottenere rapidamente zipkin attivo e in esecuzione.

kubectl apply -f samples/addons/extras/zipkin.yaml

In alternativa, installare zipkin separatamente e configurare Istio per inviare i trace alla distribuzione zipkin.

Kiali

Istio fornisce un'installazione di esempio di base per rendere rapidamente Kiali operativo:

kubectl apply -f samples/addons/kiali.yaml
            

In alternativa, installare e configurare Kiali separatamente.

Esplorare l'osservabilità di Istio

In questa sezione vengono illustrate le metriche delle prestazioni e le funzioni di trace fornite dalle applicazioni di integrazione Istio.

Esecuzione di query sulle metriche dall'applicazione Prometheus for Bookinfo

Con Prometheus e Istio, i dati sulle prestazioni di Bookinfo vengono analizzati in diversi modi.

In primo luogo, verificare che Prometheus sia installato.

kubectl -n istio-system get svc prometheus

Avviare l'interfaccia utente Prometheus con il comando seguente:

istioctl dashboard prometheus

Fare clic su Grafico a destra di Prometeo nell'intestazione. Per visualizzare alcuni dati, generare traffico per la pagina del prodotto utilizzando un browser o curl. Il traffico si riflette nella dashboard Prometheus.

Visualizzazione delle metriche per l'applicazione Bookinfo con Grafana

La combinazione di Prometheus e Grafana offre alcuni dashboard sulle prestazioni per le applicazioni. Per utilizzare i dashboard, verificare innanzitutto che siano installati sia Prometheus che Grafana.

kubectl -n istio-system get svc prometheus
kubectl -n istio-system get svc grafana

Avviare il dashboard Istio Grafana.

istioctl dashboard grafana

Gestione dei dashboard Grafana

Il service mesh Istio offre sei dashboard Grafana. Qui vengono acquisiti gli snapshot del dashboard Grafana mesh del servizio Istio.

Nota

Genera il traffico verso la pagina del prodotto utilizzando un browser o curl e lo visualizza nel dashboard Grafana.

Dashboard mesh Istio

Snapshot dashboard mesh Istio

Dashboard servizi Istio

Snapshot dashboard servizio Istio

Dashboard carico di lavoro Istio

Snapshot dashboard carico di lavoro Istio

Dashboard prestazioni Istio

Snapshot dashboard prestazioni Istio

Dashboard pannello di controllo Istio

Snapshot dashboard pannello di controllo Istio

Per ulteriori informazioni su come creare, configurare e modificare i dashboard, consulta la documentazione di Grafana.

Esecuzione del trace distribuito mediante Jaeger

Utilizzare il framework open source Jaeger per eseguire il trace delle applicazioni con Istio.

  1. Abilitare e configurare il trace utilizzando istioctl:
    istioctl install --set meshConfig.enableTracing=true
  2. Con l'applicazione Bookinfo distribuita, aprire l'interfaccia utente Jaeger utilizzando istioctl.
    istioctl dashboard jaeger
  3. Per generare trace, inviare richieste alla pagina del prodotto.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Le tracce si riflettono nel dashboard Jaeger.

Dashboard Jaeger

Istantanea dashboard Istio Jaeger

Trace applicazione Jaeger

Istantanea traccia applicazione Istio Jaeger

Esecuzione del trace distribuito mediante zipkin

Utilizzare il framework open source zipkin per eseguire il trace delle applicazioni con Istio.

  1. Abilitare e configurare il trace utilizzando istioctl.
    istioctl install --set meshConfig.enableTracing=true
  2. Con l'applicazione Bookinfo distribuita, aprire l'interfaccia utente zipkin utilizzando istioctl.
    istioctl dashboard zipkin
  3. Per generare trace, inviare richieste alla pagina del prodotto.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

I trace vengono visualizzati nel dashboard zipkin.

Dashboard zipkin di esempio

Istantanea dashboard Istio Zipkin

Esecuzione del trace distribuito con OCI Application Performance Monitoring

OCI Application Performance Monitoring (APM) si integra con strumenti di sistema di trace open source come Jaeger e zipkin. APM consente di caricare i dati di trace in OCI. Per eseguire l'integrazione con OCI APM, creare un dominio APM seguendo le istruzioni menzionate qui. Un dominio APM è una risorsa OCI che contiene i sistemi monitorati da APM.

Dopo aver creato il dominio, visualizzare i dettagli del dominio e ottenere l'endpoint di caricamento dati, la chiave privata e la chiave pubblica per creare l'URL del Collector APM. L'URL del Collector APM è obbligatorio quando si configurano i traccianti open source per comunicare con il servizio APM. Il formato URL Collector richiede un URL creato utilizzando l'endpoint di caricamento dati come URL di base e genera il percorso in base alle scelte, inclusi i valori della chiave privata o pubblica. Il formato è documentato qui. Con il percorso URL costruito, collegare l'URL alla configurazione Istio.

Nota

Per informazioni più dettagliate sulla configurazione dei criteri del servizio APM, vedere:

Configurazione di Istio per l'invio di trace ad APM

  1. Abilita trace con istioctl.
    istioctl install --set meshConfig.defaultConfig.tracing.zipkin.address=aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com:443
    Nota

    L'indirizzo dell'endpoint di aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com è un esempio e non un endpoint effettivo.
  2. Configurare Envoy per inviare i trace zipkin a APM. Sostituire il codice in samples/custom-bootstrap/custom-bootstrap.yaml con il blocco di codice seguente.
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: istio-custom-bootstrap-config
      namespace: default
    data:
      custom_bootstrap.json: |
        {
            "tracing": {
                "http": {
                    "name": "envoy.tracers.zipkin",
                    "typed_config": {
                        "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
                        "collector_cluster": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "collector_endpoint": "/20200101/observations/private-span?dataFormat=zipkin&dataFormatVersion=2&dataKey=2C6YOLQSUZ5Q7IGN", // [Replace with the private datakey of your apm domain. You can also use public datakey but change the observation type to public-span]
                        "collectorEndpointVersion": "HTTP_JSON",
                        "trace_id_128bit": true,
                        "shared_span_context": false
                    }
                }
            },
            "static_resources": {
                "clusters": [{
                    "name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain:443]
                    "type": "STRICT_DNS",
                    "lb_policy": "ROUND_ROBIN",
                    "load_assignment": {
                        "cluster_name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "endpoints": [{
                            "lb_endpoints": [{
                                "endpoint": {
                                    "address": {
                                        "socket_address": {
                                            "address": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                                            "port_value": 443
                                        }
                                    }
                                }
                            }]
                        }]
                    },
                    "transport_socket": {
                        "name": "envoy.transport_sockets.tls",
                        "typed_config": {
                            "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
                            "sni": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com" // [Replace this with data upload endpoint of your apm domain]
                        }
                    }
                }]
            }
        }
    EOF
  3. Applicare la configurazione personalizzata.
    kubectl apply -f samples/custom-bootstrap/custom-bootstrap.yaml
  4. Affinché tutti i nostri servizi in Bookinfo utilizzino questa configurazione di bootstrap personalizzata, aggiungere un'annotazione sidecar.istio.io/bootstrapOverride con il nome ConfigMap personalizzato come valore. Nell'esempio seguente viene aggiunta un'annotazione per la pagina del prodotto in samples/bookinfo/platform/kube/bookinfo.yaml. Aggiungere un'annotazione simile ad altri servizi.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: productpage-v1
      labels:
        app: productpage
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: productpage
          version: v1
      template:
        metadata:
          labels:
            app: productpage
            version: v1
          annotations:
            sidecar.istio.io/bootstrapOverride: "istio-custom-bootstrap-config" #[Name of custom configmap]
        spec:
          serviceAccountName: bookinfo-productpage
          containers:
            - name: productpage
              image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 9080
              volumeMounts:
                - name: tmp
                  mountPath: /tmp
              securityContext:
                runAsUser: 1000
          volumes:
            - name: tmp
              emptyDir: {}
    ---
  5. Applica lo yaml, tutti i pod riavviati iniziano a inviare tracce ad APM.
    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
  6. Per abilitare un gateway di entrata per l'invio dei trace, creare un configmap denominato custom-bootstrap.yaml nello spazio di nomi istio-system:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: istio-custom-bootstrap-config
      namespace: istio-system
    data:
      custom_bootstrap.json: |
        {
            "tracing": {
                "http": {
                    "name": "envoy.tracers.zipkin",
                    "typed_config": {
                        "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
                        "collector_cluster": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "collector_endpoint": "/20200101/observations/private-span?dataFormat=zipkin&dataFormatVersion=2&dataKey=2C6YOLQSUZ5Q7IGN", // [Replace with the private datakey of your apm domain. You can also use public datakey but change the observation type to public-span]
                        "collectorEndpointVersion": "HTTP_JSON",
                        "trace_id_128bit": true,
                        "shared_span_context": false
                    }
                }
            },
            "static_resources": {
                "clusters": [{
                    "name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain:443]
                    "type": "STRICT_DNS",
                    "lb_policy": "ROUND_ROBIN",
                    "load_assignment": {
                        "cluster_name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "endpoints": [{
                            "lb_endpoints": [{
                                "endpoint": {
                                    "address": {
                                        "socket_address": {
                                            "address": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                                            "port_value": 443
                                        }
                                    }
                                }
                            }]
                        }]
                    },
                    "transport_socket": {
                        "name": "envoy.transport_sockets.tls",
                        "typed_config": {
                            "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
                            "sni": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com" // [Replace this with data upload endpoint of your apm domain]
                        }
                    }
                }]
            }
        }
    EOF
  7. Creare una patch denominata gateway-patch.yaml per il gateway di entrata per avviare l'utilizzo della configurazione custom-bootstrap:
    spec:
      template:
        spec:
          containers:
          - name: istio-proxy
            env:
            - name: ISTIO_BOOTSTRAP_OVERRIDE
              value: /etc/istio/custom-bootstrap/custom_bootstrap.json
            volumeMounts:
            - mountPath: /etc/istio/custom-bootstrap
              name: custom-bootstrap-volume
              readOnly: true
          volumes:
          - configMap:
              name: istio-custom-bootstrap-config
              defaultMode: 420
              optional: false
            name: custom-bootstrap-volume
  8. Applicare la patch precedente per il gateway in entrata:
    kubectl --namespace istio-system patch deployment istio-ingressgateway --patch "$(cat gateway-patch.yaml)"
  9. Per generare trace, inviare richieste alla pagina del prodotto.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

I trace vengono visualizzati nel dashboard APM effettuando la procedura qui.

Explorer di Zipkin Trace

Screenshot di Zipkin Trace Explorer

Traccia Zipkin

Screenshot di una traccia Zipkin

Intervalli Zipkin

Per visualizzare gli intervalli, fare clic su Home nell'elenco APM.

Screenshot di un intervallo Zipkin

Dashboard app Zipkin

APM fornisce funzionalità per creare dashboard ed esplorare gli intervalli generati nel tempo. I dashboard possono essere creati seguendo i passi qui.

Screenshot di un dashboard dell'app Zipkin

Explorer metriche Zipkin

APM consente di monitorare lo stato, la capacità e le prestazioni delle applicazioni utilizzando metriche, allarmi e notifiche. Effettuare le operazioni riportate di seguito qui per configurare le metriche.

Screenshot di un Explorer metriche Zipkin

Osservazione dei log con OCI Logging

OCI Logging è un componente centrale per l'analisi e la ricerca delle voci dei file di log per le tenancy in OCI. I log dei container Kubernetes dai nodi di lavoro OKE possono essere pubblicati come log personalizzati in OCI Logging. Segui i passi descritti qui per configurare OCI Logging e includere i log dei container.

  1. Abilita il log degli accessi inviati in Istio con istioctl.
    istioctl install --set meshConfig.accessLogFile=/dev/stdout
  2. Accedi alla pagina del prodotto Bookinfo utilizzando un browser o un curl. I log degli accessi generati possono essere visualizzati utilizzando il comando kubectl.
    kubectl logs -l app=productpage -c istio-proxy

Se OCI Logging è configurato per il cluster, è possibile eseguire query e analizzare questi log utilizzando la pagina di ricerca dei log di OCI Console.

Ricerca log OCI

Screenshot di una ricerca di OCI Logging

Ricerca di log OCI espansa

Screenshot di una ricerca estesa di OCI Logging

Visualizzazione della mesh mediante Kiali

Verificare che Kiali sia installato.

kubectl -n istio-system get svc kiali

Aprire l'interfaccia utente di Kiali nel browser.

istioctl dashboard kiali

Invia un po' di traffico alla pagina del prodotto.

for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Visualizza il tuo mesh in Kiali seguendo il passo 5 da qui.

Gestione del traffico

Le regole di instradamento del traffico di Istio ti consentono di controllare il flusso di traffico tra i servizi e semplifica la configurazione delle proprietà a livello di servizio come interruttori di circuito, timeout e nuovi tentativi. Istio semplifica l'impostazione di attività importanti come i test A/B, i rollout canary e i rollout in staging con suddivisioni del traffico basate sulla percentuale.

Risorse API per la gestione del traffico di Istio:

Affinché Istio controlli l'instradamento della versione dell'applicazione Bookinfo, definire tutte le versioni disponibili del servizio, denominate sottoinsiemi, nelle regole di destinazione. Creare le regole di destinazione predefinite per i servizi Bookinfo:
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

Spostamento del traffico

Istio ci permette di migrare gradualmente il traffico da una versione di un microservizio a un'altra utilizzando la funzione di routing ponderata di Istio. L'esempio seguente mostra come configurare l'invio del 50% del traffico a reviews:v1 e del 50% a reviews:v3. Successivamente, completa la migrazione inviando il 100% del traffico a reviews:v3.

  1. Instrada tutto il traffico alla versione v1 di ogni microservizio.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

    Per visualizzare la pagina Web Bookinfo, aprire l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser. Si noti che la parte delle recensioni della pagina viene visualizzata senza stelle di valutazione, indipendentemente dal numero di volte che si aggiorna. Istio è configurato per instradare tutto il traffico per il servizio recensioni a reviews:v1 e questa versione del servizio non accede al servizio valutazioni a stelle.

  2. Trasferire il 50% del traffico da reviews:v1 a reviews:v3 con il comando seguente e attendere la propagazione delle nuove regole.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml

    Aggiornare l'URL /productpage nel browser e visualizzare le valutazioni delle stelle colorate di rosso circa il 50% delle volte. reviews:v3 accede al servizio di classificazione a stelle, ma la versione reviews:v1 non lo fa.

  3. Ora indirizza il 100% del traffico a reviews:v3.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml
  4. Aggiornare l'URL /productpage nel browser e visualizzare sempre le valutazioni a stelle colorate di rosso per ogni recensione.

Gestione dell'instradamento delle richieste di gestione

Istio può indirizzare il traffico in diversi modi. Per iniziare, configurare Istio per instradare tutto il traffico attraverso v1 di ogni microservizio.
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

Per visualizzare la pagina Web Bookinfo, aprire l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser. Si noti che la parte delle recensioni della pagina viene visualizzata senza stelle di valutazione, indipendentemente dal numero di volte che si aggiorna. Perché Istio è configurato per instradare tutto il traffico per il servizio recensioni alla versione reviews:v1. Questa versione del servizio non accede al servizio di classificazione a stelle.

Screenshot di un libro Booinfo di esempio.

Instradamento basato sull'identità utente

Per instradare in base all'identità utente:

  1. Modificare la configurazione dell'instradamento in modo che tutto il traffico proveniente da un utente specifico denominato jason venga instradato a reviews:v2. Istio non ha alcuna comprensione speciale e integrata dell'identità dell'utente. In questo esempio, il servizio productpage aggiunge un'intestazione utente finale personalizzata a tutte le richieste HTTP in uscita al servizio di revisione.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
  2. Per visualizzare la pagina Web Bookinfo ed eseguire il login come utente jason, aprire l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser. Aggiorna il browser per visualizzare le valutazioni a stelle accanto a ogni recensione.

    Screenshot di un campione di libro Booinfo con stelle
  3. Aprire l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser per visualizzare la pagina Web Bookinfo ed eseguire il login come utente diverso da jason. Aggiorna il browser per non visualizzare stelle per ogni recensione.

    Screenshot di un campione di libro Booinfo senza stelle

Instradamento basato su riscrittura URL

In questo esempio, le richieste HTTP con un percorso che inizia con /products o /bookinfoproductpage vengono riscritte in /productpage. Le richieste HTTP vengono inviate ai pod con productpage in esecuzione sulla porta 9080. Per ulteriori informazioni sulla riscrittura dell'URL Istio, vedere qui.

  1. Applicare il seguente yaml:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: bookinfo
    spec:
      hosts:
      - "*"
      gateways:
      - bookinfo-gateway
      http:
      - match:
        - uri:
            prefix: /products
        - uri:
            prefix: /bookinfoproductpage
        rewrite:
          uri: /productpage
        route:
        - destination:
            host: productpage
            port:
              number: 9080
    EOF
  2. Per visualizzare la pagina Web Bookinfo, aprire gli URL http://${INGRESS_HOST}:${INGRESS_PORT}/products e http://${INGRESS_HOST}:${INGRESS_PORT}/bookinfoproductpage in un browser. In entrambi i casi, viene eseguita una riscrittura prima di inoltrare la richiesta.

    Riscrivi /bookproductpage

    Screenshot di un libro Booinfo di esempio con /bookproductpage

    Riscrivi /prodotti

    Screenshot di un libro Booinfo di esempio con /products
  3. Pulire il file yaml nella versione originale fornita da Istio e applicarlo.
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  4. Aprire l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/bookinfoproductpage o http://${INGRESS_HOST}:${INGRESS_PORT}/products per non visualizzare la pagina del prodotto poiché yaml non riscrive la richiesta.

    Errore 404 /prodotti

    Screenshot di un libro Booinfo di esempio con /products 404

    Errore 404 /booksproductpage

    Screenshot di un esempio di libro Booinfo con /booksproductpage 404

Test della resilienza della rete

Istio consente di configurare l'installazione per timeout di richiesta, iniezione di guasti e interruttori. Queste impostazioni consentono di gestire e testare la tolleranza agli errori delle applicazioni distribuite.

Impostazione timeout richieste

Il timeout indica il periodo di tempo durante il quale un proxy Envoy attende le risposte da un determinato servizio. Il timeout garantisce che i servizi non attendano le risposte a tempo indeterminato e garantisce che le chiamate abbiano esito positivo o negativo entro un intervallo di tempo prevedibile. Per ulteriori informazioni sui timeout, vedere qui.

È possibile specificare un timeout per le richieste HTTP utilizzando il campo di timeout della regola di instradamento. Per impostazione predefinita, il timeout della richiesta è disabilitato.

  1. Inizializzare il routing della versione dell'applicazione eseguendo il comando seguente:
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. Instrada le richieste al servizio reviews:v2, in effetti una versione che chiama il servizio di rating:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
        - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v2
    EOF
  3. Aggiungere un ritardo di 2 secondi alle chiamate al servizio di valutazione:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - fault:
          delay:
            percent: 100
            fixedDelay: 2s
        route:
        - destination:
            host: ratings
            subset: v1
    EOF
  4. Per visualizzare la pagina Web Bookinfo con le stelle di valutazione visualizzate, aprire l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser. Un ritardo di 2 secondi si verifica ogni volta che si aggiorna la pagina.
    Screenshot della pagina Web del prodotto del libro.
  5. Aggiungere un timeout di richiesta di mezzo secondo per le chiamate al servizio recensioni:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
      - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v2
        timeout: 0.5s
    EOF
  6. Per visualizzare la pagina Web Bookinfo, aprire l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser. Notate che la pagina ritorna in circa 1 secondo, invece di 2, e le recensioni non sono disponibili.
    Screenshot della pagina Web del prodotto del libro.

Il motivo per cui la risposta richiede 1 secondo, anche se il timeout è configurato a mezzo secondo, è perché un nuovo tentativo non modificabile nel servizio productpage. Il servizio chiama il servizio di recensioni scadute due volte prima di tornare.

Oltre a sostituirle nelle regole di instradamento, il timeout può essere sostituito anche in base alla richiesta se l'applicazione aggiunge un'intestazione x-envoy-upstream-rq-timeout-ms nelle richieste in uscita.

Gestione dell'inserimento dell'errore

L'inserimento di errori è un metodo di test che introduce errori in un sistema per garantire che il sistema resista e si riprenda dalle condizioni di errore. Istio consente l'inserimento di errori a livello di applicazione, ad esempio i codici di errore HTTP. Istio inserisce due tipi di errori, entrambi configurati utilizzando un servizio virtuale. Per ulteriori informazioni sull'inserimento degli errori, vedere qui.

  • Ritardi: i ritardi sono errori di temporizzazione che imitano una maggiore latenza di rete o un servizio a monte sovraccarico.
  • Interruzioni: le interruzioni sono errori di arresto anomalo che imitano gli errori nei servizi a monte. Interrompe il file manifesto sotto forma di codici di errore HTTP o errori di connessione TCP.

Per eseguire il test dell'inserimento degli errori, eseguire il comando seguente per inizializzare il routing della versione dell'applicazione:

kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml

Inserimento di un errore di ritardo HTTP

Per iniettare un errore di ritardo, attenersi alla seguente procedura:

  • Creare una regola di inserimento degli errori per ritardare il traffico proveniente dall'utente jason. Il comando seguente inserisce un ritardo di 7 secondi tra reviews:v2 e i microservizi di rating per l'utente jason.
    kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
    Nota

    Il servizio reviews:v2 dispone di un timeout di connessione non modificabile di 10 secondi per le chiamate al servizio di rating. Con un ritardo di 7 secondi, aspettatevi che il flusso end-to-end continui senza errori.
  • Per visualizzare la pagina Web Bookinfo, aprire l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser.
    Snapshot della pagina Bookinfo con errori di ritardo

    La home page di Bookinfo viene caricata senza errori in circa sette secondi. Tuttavia, nella sezione delle revisioni viene visualizzato un messaggio di errore: Le recensioni dei prodotti non sono attualmente disponibili per questo manuale. Esiste un bug nel codice dell'applicazione. Il timeout non modificabile tra il servizio productpage e il servizio reviews determina un ritardo di 6 secondi, 3 secondi più 1 nuovo tentativo. Di conseguenza, la chiamata productpage a reviews si esaurisce prematuramente e genera un errore dopo 6 secondi.

    Per correggere il bug, aumentare il timeout del servizio productpage a reviews oppure ridurre il timeout reviews a ratings a meno di 3 secondi.

  • Risolviamo il bug aggiungendo un ritardo di 2 secondi al servizio ratings per l'utente jason.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - match:
        - headers:
            end-user:
              exact: jason
        fault:
          delay:
            percentage:
              value: 100.0
            fixedDelay: 2s
        route:
        - destination:
            host: ratings
            subset: v1
      - route:
        - destination:
            host: ratings
            subset: v1
    EOF
  • Ora che il bug è stato corretto, aprire l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser per visualizzare la pagina Web Bookinfo. Accedi come jason con le stelle di valutazione visualizzate.
    Istantanea della pagina Bookinfo senza errori dely

Inserimento di un errore di interruzione HTTP

Seguire questi passaggi per iniettare un errore di interruzione:

  1. Creare una regola di inserimento degli errori per inviare una risposta di interruzione HTTP per l'utente jason:
    kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
  2. Per visualizzare la pagina Web Bookinfo, aprire l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser. Eseguire il login come utente jason. Un messaggio indica che il servizio ratings non è disponibile.
    Screenshot della pagina Bookinfo con il servizio di rating non disponibile

    Eseguire il logout dall'utente jason o eseguire il login con qualsiasi altro utente per non visualizzare alcun messaggio di errore.

    creenshot della pagina Bookinfo senza errori

Creazione degli interruttori di circuito

L'interruzione del circuito ci consente di scrivere applicazioni che limitano l'impatto di guasti, picchi di latenza e altri effetti indesiderati delle peculiarità della rete. Per ulteriori informazioni sugli interruttori di circuito, consultare questa pagina.

  1. Creare una regola di destinazione per applicare le impostazioni di interruzione di circuito durante la chiamata al servizio del prodotto. La regola seguente imposta il numero massimo di connessioni su non più di una e dispone al massimo di una richiesta HTTP in sospeso. Inoltre, le regole configurano gli host da sottoporre a scansione ogni 1 secondo. Qualsiasi host che si guasta una volta con un codice di errore 5XX viene espulso per 3 minuti. Viene inoltre espulso il 100% degli host nel pool di bilanciamento del carico per il servizio a monte.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productpage
    spec:
      host: productpage
      trafficPolicy:
        connectionPool:
          tcp:
            maxConnections: 1
          http:
            http1MaxPendingRequests: 1
            maxRequestsPerConnection: 1
        outlierDetection:
          consecutive5xxErrors: 1
          interval: 1s
          baseEjectionTime: 3m
          maxEjectionPercent: 100
      subsets:
      - name: v1
        labels:
          version: v1
    EOF
  2. Instrada tutto il traffico alla versione v1 di ogni microservizio.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  3. Creare un client per inviare traffico al servizio prodotto. Fortio consente di controllare il numero di connessioni, concorrenza e ritardi per le chiamate HTTP in uscita. Se è stata abilitata l'iniezione sidecar automatica, distribuire il servizio fortio:
    kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml
    In alternativa, inserire manualmente il sidecar prima di distribuire l'applicazione fortio.
    kubectl apply -f <(istioctl kube-inject -f samples/httpbin/sample-client/fortio-deploy.yaml)
  4. Eseguire il login al pod client e utilizzare lo strumento fortio per chiamare productpage e verificare che il codice di stato della risposta sia 200 con i comandi seguenti.
    export FORTIO_POD=$(kubectl get pods -l app=fortio -o 'jsonpath={.items[0].metadata.name}')
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio curl http://productpage:9080
    
    Viene prodotto il seguente output:
    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 1683
    server: envoy
    date: Tue, 07 Sep 2021 11:01:02 GMT
    x-envoy-upstream-service-time: 5
  5. Chiama il servizio con 2 connessioni simultanee (-c 2) e invia 20 richieste (-n 20). È interessante notare che 16 richieste passthrough e 4 falliscono.
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://productpage:9080
    Il comando produce un output simile a quello seguente:
    11:03:43 I logger.go:127> Log level is now 3 Warning (was 2 Info)
    Fortio 1.11.3 running at 0 queries per second, 128->128 procs, for 20 calls: http://productpage:9080
    Starting at max qps with 2 thread(s) [gomax 128] for exactly 20 calls (10 per thread + 0)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    Ended after 51.340006ms : 20 calls. qps=389.56
    Aggregated Function Time : count 20 avg 0.0045031997 +/- 0.002036 min 0.000387421 max 0.007704444 sum 0.090063995
    # range, mid point, percentile, count
    >= 0.000387421 <= 0.001 , 0.000693711 , 15.00, 3
    > 0.003 <= 0.004 , 0.0035 , 20.00, 1
    > 0.004 <= 0.005 , 0.0045 , 65.00, 9
    > 0.005 <= 0.006 , 0.0055 , 75.00, 2
    > 0.006 <= 0.007 , 0.0065 , 95.00, 4
    > 0.007 <= 0.00770444 , 0.00735222 , 100.00, 1
    # target 50% 0.00466667
    # target 75% 0.006
    # target 90% 0.00675
    # target 99% 0.00756356
    # target 99.9% 0.00769036
    Sockets used: 5 (for perfect keepalive, would be 2)
    Jitter: false
    Code 200 : 16 (80.0 %)
    Code 503 : 4 (20.0 %)
    Response Header Sizes : count 20 avg 133.6 +/- 66.8 min 0 max 167 sum 2672
    Response Body/Total Sizes : count 20 avg 1528.2 +/- 643.6 min 241 max 1850 sum 30564
    All done 20 calls (plus 0 warmup) 4.503 ms avg, 389.6 qps
  6. Aumentare il numero di connessioni concorrenti a 3.
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 30 -loglevel Warning http://productpage:9080
    Solo il 26,7% delle richieste è riuscito e l'interruzione del circuito intrappola il resto.
    11:10:19 I logger.go:127> Log level is now 3 Warning (was 2 Info)
    Fortio 1.11.3 running at 0 queries per second, 128->128 procs, for 30 calls: http://productpage:9080
    Starting at max qps with 3 thread(s) [gomax 128] for exactly 30 calls (10 per thread + 0)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    Ended after 28.105508ms : 30 calls. qps=1067.4
    Aggregated Function Time : count 30 avg 0.0024256753 +/- 0.003264 min 0.000261072 max 0.010510116 sum 0.07277026
    # range, mid point, percentile, count
    >= 0.000261072 <= 0.001 , 0.000630536 , 66.67, 20
    > 0.001 <= 0.002 , 0.0015 , 73.33, 2
    > 0.005 <= 0.006 , 0.0055 , 76.67, 1
    > 0.006 <= 0.007 , 0.0065 , 83.33, 2
    > 0.007 <= 0.008 , 0.0075 , 93.33, 3
    > 0.009 <= 0.01 , 0.0095 , 96.67, 1
    > 0.01 <= 0.0105101 , 0.0102551 , 100.00, 1
    # target 50% 0.000805545
    # target 75% 0.0055
    # target 90% 0.00766667
    # target 99% 0.0103571
    # target 99.9% 0.0104948
    Sockets used: 25 (for perfect keepalive, would be 3)
    Jitter: false
    Code 200 : 8 (26.7 %)
    Code 503 : 22 (73.3 %)
    Response Header Sizes : count 30 avg 44.533333 +/- 73.85 min 0 max 167 sum 1336
    Response Body/Total Sizes : count 30 avg 670.06667 +/- 711.5 min 241 max 1850 sum 20102
    All done 30 calls (plus 0 warmup) 2.426 ms avg, 1067.4 qps
  7. Eseguire una query sulle statistiche istio-proxy per ottenere ulteriori informazioni.
    kubectl exec "$FORTIO_POD" -c istio-proxy -- pilot-agent request GET stats | grep productpage | grep pending
    L'interruzione del circuito segnala 32 chiamate guardando la metrica upstream_rq_pending_overflow.
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.default.remaining_pending: 1
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_active: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_failure_eject: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_overflow: 32
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_total: 39
  8. Eseguire il cleanup del client.
    kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
    kubectl delete deploy fortio-deploy
    kubectl delete svc fortio

Mirroring

Il mirroring del traffico, chiamato anche shadowing, consente ai team di apportare modifiche alla produzione con il minor rischio possibile. Il mirroring invia una copia del traffico attivo a un servizio con mirroring. Il traffico con mirroring si verifica al di fuori del percorso di richiesta critico per il servizio primario.

  1. Instrada tutto il traffico alla versione v1 di ogni microservizio.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. Modificare la regola di instradamento in modo che esegua il mirroring del traffico in reviews:v2.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
        - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v1
          weight: 100
        mirror:
          host: reviews
          subset: v2
        mirrorPercentage:
          value: 100.0
    EOF

    La regola di instradamento precedente invia il 100% del traffico a reviews:v1 ed esegue il mirroring del 100% dello stesso traffico al servizio reviews:v2.

    Quando viene eseguito il mirroring del traffico, le richieste vengono inviate al servizio con mirroring con le relative intestazioni di host/autorità aggiunte con -shadow. Ad esempio, le recensioni diventano richieste reviews-shadow.Mirrored considerate come "fuoco e dimentica". Le risposte in mirroring vengono eliminate.

    Anziché eseguire il mirroring di tutte le richieste, modificare il campo del valore nel campo mirrorPercentage per eseguire il mirroring di una frazione del traffico. Se questo campo è assente, viene eseguito il mirroring di tutto il traffico.

  3. Inviare traffico aggiornando l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser.
  4. Log del servizio reviews:v1. Nota: il servizio v1 non chiama il servizio di rating.
    Screeshot del servizio reviews:v1
  5. Log del servizio con mirroring reviews:v2. Nota per il servizio v2, l'intestazione viene aggiunta con -shadow.
    Screeshot del servizio reviews:v2 con -shadow

Gestione dei gateway

Gateway descrive un load balancer che opera sul bordo della rete e riceve connessioni HTTP/TCP in entrata o in uscita. Le configurazioni del gateway vengono applicate ai proxy Envoy standalone in esecuzione sul bordo della mesh, anziché ai proxy Envoy sidecar in esecuzione accanto ai carichi di lavoro del servizio. Istio fornisce alcune distribuzioni proxy gateway preconfigurate istio-ingressgateway e istio-egressgateway.

Se i gateway Istio non sono stati configurati nell'ambito dell'installazione, eseguire il comando seguente per installarli.
istioctl install

Il comando distribuisce Istio utilizzando le impostazioni predefinite che includono un gateway. Per ulteriori informazioni, vedi qui.

Nota

Determinare i valori INGRESS_HOST e INGRESS_PORT utilizzando queste istruzioni.

Configurazione dell'ingresso mediante il gateway Istio

Il gateway in entrata configura porte e protocolli esposti, ma a differenza delle risorse in entrata di Kubernetes, non include alcuna configurazione di instradamento del traffico. L'instradamento del traffico per il traffico in entrata viene invece configurato utilizzando le regole di instradamento Istio. Per ulteriori informazioni sull'ingresso Istio, vedere qui.

Nota

Se l'applicazione Bookinfo è già stata distribuita, non sono necessari i passi riportati di seguito.
  1. Crea un gateway Istio che si configura sulla porta 80 per il traffico HTTP.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: bookinfo-gateway
    spec:
      selector:
        istio: ingressgateway # use istio default controller
      servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
            - "*"
    EOF
  2. Configurare gli instradamenti per il traffico in entrata tramite il gateway:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: bookinfo
    spec:
      hosts:
      - "*"
      gateways:
      - bookinfo-gateway
      http:
      - match:
        - uri:
            exact: /productpage
        - uri:
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
        route:
        - destination:
            host: productpage
            port:
              number: 9080
    EOF
  3. Per distribuire l'applicazione Bookinfo, vedere la sezione "Esecuzione dell'applicazione Bookinfo" della pagina Installazione di Istio e OKE.
  4. Accedere al servizio productpage utilizzando curl:
    curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/productpage

    Il comando produce il seguente output:

    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 4183
    server: istio-envoy
    date: Tue, 07 Sep 2021 13:48:39 GMT
    x-envoy-upstream-service-time: 36
  5. Accedere a qualsiasi altro URL non esposto in modo esplicito. Viene visualizzato un errore HTTP 404.
    curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/any

    Il comando produce il seguente output:

    HTTP/1.1 404 Not Found
    date: Tue, 07 Sep 2021 13:49:45 GMT
    server: istio-envoy
    transfer-encoding: chunked
  6. Per gli host espliciti nei gateway, utilizzare il flag -H per impostare l'intestazione HTTP dell'host. Il flag è necessario perché il gateway in entrata e il servizio virtuale sono configurati per gestire l'host. Ad esempio, l'host è example.com e il nome viene specificato sia nei gateway che nel servizio virtuale.
    curl -s -I -HHost:example.com http://$INGRESS_HOST:$INGRESS_PORT/productpage
  7. Aprire inoltre l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage in un browser per visualizzare la pagina Web Bookinfo.

Configurazione dell'ingresso mediante la risorsa in entrata Kubernetes

Il lettore presuppone che l'applicazione Bookinfo venga distribuita nel cluster. Per distribuire l'applicazione Bookinfo, vedere la sezione "Esecuzione dell'applicazione Bookinfo" della pagina Installazione di Istio e OKE.

  1. Rimuovere il gateway Istio se la configurazione è già applicata.
    kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml
  2. Creare una risorsa in entrata sulla porta 80 per il traffico HTTP.
    kubectl apply -f - <<EOF
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: istio
      name: ingress
    spec:
      rules:
      - http:
         paths:
         - path: /productpage
           pathType: Prefix
           backend:
              service:
                name: productpage
                port:
                  number: 9080
    EOF

    L'annotazione kubernetes.io/ingress.class è necessaria per indicare al controller del gateway Istio di gestire questo Ingress.

  3. Verificare l'accesso all'applicazione Bookinfo seguendo le istruzioni della sezione precedente.
  4. Eliminare la risorsa e abilitare il gateway Istio per ulteriori task.
    kubectl delete ingress ingress
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

Accesso ai servizi esterni con uscita

Per impostazione predefinita, tutto il traffico in uscita da un pod abilitato per Istio viene reindirizzato al relativo proxy sidecar e Istio configura il proxy Envoy per passare le richieste di servizi sconosciuti. Istio configura la gestione sidecar dei servizi esterni tramite un campo di configurazione meshConfig.outboundTrafficPolicy.mode. Se questa opzione è impostata su:

  • ALLOW_ANY (impostazione predefinita): il proxy Istio consente il passaggio di chiamate a servizi sconosciuti.
  • REGISTRY_ONLY: il proxy Istio blocca qualsiasi host senza una voce di servizio o servizio HTTP definita all'interno del mesh.

Il lettore presuppone che l'applicazione Bookinfo venga distribuita nel cluster. In caso contrario, seguire la procedura per distribuire l'applicazione Bookinfo.

Gestione di Envoy Passthrough a servizi esterni

Per abilitare il passthrough ai servizi esterni, attenersi alla procedura riportata di seguito.

  1. Modificare l'opzione meshConfig.outboundTrafficPolicy.mode in ALLOW_ANY con istioctl.
    istioctl install --set meshConfig.outboundTrafficPolicy.mode=ALLOW_ANY
    Nota

    Questo passaggio è necessario solo se l'opzione è stata impostata in modo esplicito su REGISTRY_ONLY durante l'installazione.
  2. Per confermare le 200 risposte riuscite, effettuare una richiesta ai servizi esterni dal sito SOURCE_POD:
    export SOURCE_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items..metadata.name}')
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
    Il comando produce il seguente output:
    HTTP/1.1 200 OK

Tuttavia, lo svantaggio di questo approccio è che il monitoraggio e il controllo Istio per il traffico verso servizi esterni sono persi.

Controllo dell'accesso ai servizi esterni [consigliato]

Per impostare l'accesso controllato ai servizi esterni, attenersi alla procedura riportata di seguito.

  1. Modificare l'opzione meshConfig.outboundTrafficPolicy.mode in REGISTRY_ONLY. Questo passaggio è necessario solo se l'opzione non è stata impostata in modo esplicito su REGISTRY_ONLY durante l'installazione.
  2. Seguire solo il passo 1 dalla sezione "Envoy Passthrough to External Services". L'unica modifica da apportare qui è quella di sostituire ALLOW_ANY con REGISTRY_ONLY.
  3. Per verificare che i servizi esterni siano bloccati, effettuare un paio di richieste ai servizi HTTPS esterni dall'indirizzo SOURCE_POD. La propagazione delle modifiche alla configurazione richiede alcuni secondi, pertanto sono possibili connessioni riuscite. Attendere alcuni secondi, quindi riprovare a eseguire l'ultimo comando.
    export SOURCE_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items..metadata.name}')
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"

    Il comando produce il seguente output:

    HTTP/1.1 502 Bad Gateway
  4. Creare un ServiceEntry per consentire l'accesso a un servizio HTTP esterno.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: ServiceEntry
    metadata:
      name: httpbin-ext
    spec:
      hosts:
      - httpbin.org
      ports:
      - number: 80
        name: http
        protocol: HTTP
      resolution: DNS
      location: MESH_EXTERNAL
    EOF
  5. Effettuare una richiesta al servizio HTTP esterno da SOURCE_POD. Si noti che le intestazioni aggiunte dal proxy Istio sidecar: X-Envoy-Decorator-Operation.
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
    Il comando produce il seguente output:
    HTTP/1.1 200 OK

    Rimuovere il comando grep per visualizzare tutte le intestazioni.

    kubectl exec $SOURCE_POD -c ratings -- curl -sS http://httpbin.org/headers

    Il comando produce il seguente output:

    {
      "headers": {
        "Accept": "*/*",
        "Host": "httpbin.org",
        "User-Agent": "curl/7.52.1",
        "X-Amzn-Trace-Id": "Root=1-61384b41-2d3cf8b5571ba7504ab9a834",
        "X-B3-Sampled": "0",
        "X-B3-Spanid": "6983ef0cec914f83",
        "X-B3-Traceid": "d510c4d190cb099d6983ef0cec914f83",
        "X-Envoy-Attempt-Count": "1",
        "X-Envoy-Decorator-Operation": "httpbin.org:80/*",
        "X-Envoy-Peer-Metadata": "ChsKDkFQUF9DT05UQUlORVJTEgkaB3JhdGluZ3MKGgoKQ0xVU1RFUl9JRBIMGgpLdWJlcm5ldGVzChkKDUlTVElPX1ZFUlNJT04SCBoGMS4xMS4xCtQBCgZMQUJFTFMSyQEqxgEKEAoDYXBwEgkaB3JhdGluZ3MKIAoRcG9kLXRlbXBsYXRlLWhhc2gSCxoJYzk5NDdiOTlmCiQKGXNlY3VyaXR5LmlzdGlvLmlvL3Rsc01vZGUSBxoFaXN0aW8KLAofc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtbmFtZRIJGgdyYXRpbmdzCisKI3NlcnZpY2UuaXN0aW8uaW8vY2Fub25pY2FsLXJldmlzaW9uEgQaAnYxCg8KB3ZlcnNpb24SBBoCdjEKGgoHTUVTSF9JRBIPGg1jbHVzdGVyLmxvY2FsCiQKBE5BTUUSHBoacmF0aW5ncy12MS1jOTk0N2I5OWYtbGN4bHQKFgoJTkFNRVNQQUNFEgkaB2RlZmF1bHQKTgoFT1dORVISRRpDa3ViZXJuZXRlczovL2FwaXMvYXBwcy92MS9uYW1lc3BhY2VzL2RlZmF1bHQvZGVwbG95bWVudHMvcmF0aW5ncy12MQoXChFQTEFURk9STV9NRVRBREFUQRICKgAKHQoNV09SS0xPQURfTkFNRRIMGgpyYXRpbmdzLXYx",
        "X-Envoy-Peer-Metadata-Id": "sidecar~10.244.0.11~ratings-v1-c9947b99f-lcxlt.default~default.svc.cluster.local"
      }
    }
  6. Per accedere alle chiamate HTTPS, sostituire la porta e il protocollo durante la creazione delle voci di servizio.
  7. L'approccio aggiunge funzionalità di gestione del traffico del servizio esterno come timeout e inserimento di errori. La richiesta seguente restituisce 200 (OK) in circa cinque secondi.
    kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
    Utilizzare kubectl per impostare un timeout di 3 secondi per le chiamate al servizio esterno httpbin.org:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: httpbin-ext
    spec:
      hosts:
        - httpbin.org
      http:
      - timeout: 3s
        route:
          - destination:
              host: httpbin.org
            weight: 100
    EOF
    Questa volta viene visualizzato un timeout dopo 3 secondi. Sebbene httpbin.org fosse in attesa di cinque secondi, Istio ha interrotto la richiesta a 3 secondi:
    kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
  8. Pulire le risorse per ulteriori attività future.
    kubectl delete serviceentry httpbin-ext
    kubectl delete virtualservice httpbin-ext --ignore-not-found=true

Accesso diretto a servizi esterni

Questo approccio ignora il proxy sidecar Istio, offrendo ai servizi l'accesso diretto a qualsiasi server esterno. Tuttavia, la configurazione del proxy in questo modo richiede conoscenze e configurazione specifiche del provider di cluster. Analogamente al primo approccio, perdiamo il monitoraggio dell'accesso ai servizi esterni e non possiamo applicare le funzionalità Istio al traffico verso servizi esterni. Seguire queste procedure per fornire accesso diretto ai servizi esterni.

Protezione di Istio

Le funzioni di sicurezza Istio offrono una forte identità, criteri potenti, crittografia TLS trasparente e strumenti di autenticazione, autorizzazione e audit (AAA) per proteggere i servizi e i dati.

Configurazione dell'autenticazione

Istio offre TLS reciproca come soluzione full-stack per l'autenticazione del trasporto, che è abilitata senza richiedere modifiche al codice di servizio.

Distribuire i servizi sleep e httpbin nello spazio di nomi predefinito.
kubectl apply -f samples/sleep/sleep.yaml
kubectl apply -f samples/httpbin/httpbin.yaml

Per impostazione predefinita, Istio esegue diverse attività. Istio tiene traccia dei carichi di lavoro del server migrati ai proxy Istio. Istio configura i proxy client per inviare automaticamente il traffico TLS reciproco a tali carichi di lavoro. Istio invia traffico di testo normale ai carichi di lavoro senza sidecar.

Per verificare che i certificati vengano inviati, inviare una richiesta da un pod sleep al pod httpbin e cercare l'intestazione X-Forwarded-Client-Cert.
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -s http://httpbin.default:8000/headers -s | grep X-Forwarded-Client-Cert | sed 's/Hash=[a-z0-9]*;/Hash=<redacted>;/'
Distribuire un'altra istanza dei servizi sleep e httpbin senza il sidecar abilitato.
kubectl create ns legacy
kubectl apply -f samples/sleep/sleep.yaml -n legacy
kubectl apply -f samples/httpbin/httpbin.yaml -n legacy
La richiesta dal pod sleep nello spazio di nomi predefinito al pod httpbin nello spazio di nomi legacy è in chiaro perché la destinazione non è abilitata per sidecar. Verificare che venga inviato testo normale eseguendo il comando seguente.
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl http://httpbin.legacy:8000/headers -s | grep X-Forwarded-Client-Cert
Anche la richiesta dal pod sleep nello spazio di nomi legacy a httpbin nello spazio di nomi predefinito riesce con una connessione di testo normale. La verifica può essere eseguita con il seguente comando.
kubectl exec "$(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name})" -n legacy -c sleep -- curl http://httpbin.default:8000/headers
Per impedire il traffico TLS non reciproco per l'intero mesh, impostare un criterio di autenticazione peer a livello mesh con la modalità TLS reciproca impostata su STRICT.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "default"
  namespace: "istio-system"
spec:
  mtls:
    mode: STRICT
EOF
La connessione da un pod sleep nello spazio di nomi legacy a httpbin nello spazio di nomi predefinito non funziona più quando la modalità TLS reciproca è impostata su STRICT.
kubectl exec "$(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name})" -n legacy -c sleep -- curl http://httpbin.default:8000/headers
Ripristinare l'impostazione di autenticazione peer STRICT eliminando il CR.
kubectl delete peerauthentication -n istio-system default

In addition to the global mutual TLS setting, it can also be set at a namespace or workload level. Follow the Istio documentation for detailed authentication configurations.

Configurazione dell'autorizzazione

Istio consente di configurare i criteri di autorizzazione per le applicazioni.

In primo luogo, configurare un semplice criterio allow-nothing che rifiuta tutte le richieste al carico di lavoro, quindi concede un maggiore accesso al carico di lavoro in modo graduale e incrementale.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing
  namespace: default
spec:
  {}
EOF

Apri la pagina del prodotto Bookinfo nel tuo browser. Viene visualizzato l'errore "RBAC: access denied" che conferma che il criterio deny-all funziona come previsto.

Creare un criterio per concedere a tutti gli utenti e i carichi di lavoro l'accesso alla pagina del prodotto utilizzando il comando seguente.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "productpage-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  action: ALLOW
  rules:
  - to:
    - operation:
        methods: ["GET"]
EOF

Viene visualizzata la pagina "Bookinfo Sample", ma il servizio productpage non è in grado di accedere alla pagina dei dettagli e delle recensioni.

Aggiungere i criteri riportati di seguito per concedere al carico di lavoro productpage l'accesso ai dettagli e rivedere i carichi di lavoro e rivedere l'accesso al carico di lavoro ratings.

Imposta visualizzatore dettagli

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "details-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: details
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
EOF

Imposta visualizzatore revisioni

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "reviews-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: reviews
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
EOF

Imposta visualizzatore valutazioni

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "ratings-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: ratings
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-reviews"]
    to:
    - operation:
        methods: ["GET"]
EOF

Visualizzare la pagina del prodotto da un browser senza errori.

Per ripristinare i criteri applicati, immettere i comandi seguenti.

kubectl delete authorizationpolicy.security.istio.io/allow-nothing
kubectl delete authorizationpolicy.security.istio.io/productpage-viewer
kubectl delete authorizationpolicy.security.istio.io/details-viewer
kubectl delete authorizationpolicy.security.istio.io/reviews-viewer
kubectl delete authorizationpolicy.security.istio.io/ratings-viewer

Protezione dei gateway con TLS

Possiamo esporre l'applicazione Bookinfo come un servizio HTTPS sicuro utilizzando TLS semplice o reciproco. Per firmare i certificati per i servizi in uso, creare un certificato root e una chiave privata:

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt

Creare un certificato e una chiave privata per productpage.bookinfo.com.

openssl req -out bookinfo.example.com.csr -newkey rsa:2048 -nodes -keyout bookinfo.example.com.key -subj "/CN=bookinfo.example.com/O=bookinfo organization"
openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in bookinfo.example.com.csr -out bookinfo.example.com.crt

Assicurarsi di aver distribuito l'applicazione Bookinfo. Creare un segreto per i certificati del gateway in entrata.

kubectl create -n istio-system secret tls bookinfo-credential --key=bookinfo.example.com.key --cert=bookinfo.example.com.crt

Aggiornare il gateway Bookinfo per includere una porta sicura.

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: bookinfo-gateway-https
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: bookinfo-credential
    hosts:
    - bookinfo.example.com
EOF

Creare le regole di destinazione Bookinfo se non sono già state create.

kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

Creare un servizio virtuale associato al gateway.

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: bookinfo-https
spec:
  hosts:
  - "bookinfo.example.com"
  gateways:
  - bookinfo-gateway-https
  http:
  - route:
    - destination:
        host: productpage
        subset: v1
EOF

È possibile verificare la connessione TLS al gateway con il seguente comando curl.

curl -v -HHost:bookinfo.example.com --resolve "bookinfo.example.com:443:$INGRESS_HOST" --cacert example.com.crt "https://bookinfo.example.com/productpage"