Utiliser Istio en tant que programme autonome

Découvrez comment installer Istio en tant que programme autonome sur des clusters créés à l'aide de Kubernetes Engine (OKE).

Cette rubrique fournit un exemple d'installation d'Istio en tant que programme autonome sur des clusters créés à l'aide de Kubernetes Engine (OKE). En outre, les fonctionnalités clés d'OKE et d'Istio sont présentées.

Les rubriques sont les suivantes :

Notez que les produits de maillage de services (tels qu'Oracle Cloud Infrastructure Service Mesh, Istio et Linkerd) sont pris en charge lors de l'utilisation du module d'extension CNI OCI VCN-Native Pod Networking pour le réseau de pod. Notez qu'à l'exception de l'extension Istio, le support est actuellement limité à Oracle Linux 7 (le support Oracle Linux 8 est prévu). L'extension Istio est prise en charge avec Oracle Linux 7 et Oracle Linux 8. Les noeuds de processus actif doivent exécuter Kubernetes 1.26 (ou une version ultérieure).

Remarque

Vous pouvez utiliser Istio avec des pools de noeuds gérés, mais pas avec des pools de noeuds virtuels.

Installer Istio en tant que programme autonome

Pour commencer à utiliser Istio, créez un cluster OKE ou utilisez un cluster OKE existant, puis installez Istio. Les sections ci-dessous décrivent les étapes à suivre pour installer et tester votre configuration Istio. Pour obtenir la liste complète des options d'installation, voir ici.

Création d'un cluster OKE

Créez un cluster OKE.

  1. Si vous ne l'avez pas déjà fait, créez un cluster OKE dans votre location OCI. Plusieurs options sont disponibles pour créer un cluster OKE. L'option la plus simple est l'assistant Création rapide de la console Web.
  2. Pour accéder au cluster OKE sur votre ordinateur local, installez kubectl et oci-cli.
  3. Accédez au cluster OKE à partir de la ligne de commande à l'aide de kubectl en configurant le fichier kubeconfig et assurez-vous que kubectl peut accéder au cluster.

Téléchargement d'Istio à partir de la ligne de commande

Suivez ces étapes pour télécharger Istio à partir de la ligne de commande.

  1. Téléchargez Istio en exécutant la commande suivante :
    curl -L https://istio.io/downloadIstio | sh -
  2. Accédez au répertoire du package Istio. Par exemple, si le package est istio-1.11.2 :
    cd istio-1.11.2
  3. Ajoutez l'outil client istioctl à PATH pour votre poste de travail.
    export PATH=$PWD/bin:$PATH
  4. Vérifiez si le cluster répond aux exigences d'installation Istio en exécutant la prévérification :
    istioctl x precheck

Installation d'Istio avec istioctl

Installez Istio avec istioctl à l'aide de la commande suivante :
istioctl install

Exécuter l'application Bookinfo

Le projet Istio fournit l'application Bookinfo comme moyen de démontrer les fonctionnalités d'Istio. L'application affiche des informations sur un livre, comme une entrée de catalogue unique d'une librairie en ligne. Chaque page de livre contient une description du livre, des détails sur le livre (ISBN, nombre de pages), et quelques critiques de livre. Pour plus d'informations sur l'application Bookinfo, reportez-vous à la documentation Bookinfo ici.

Diagramme de l'application Bookinfo

Comme vous pouvez le voir dans le diagramme, l'application Bookinfo est composée de quatre microservices.

  • Service de page de produit : appelle les services Détails et Vérifications pour créer une page de produit.
  • Service de détails : Renvoie les informations sur le livre.
  • Vérifie le service : renvoie les révisions de livre et appelle le service Notes.
  • Service d'évaluation : Renvoie les informations de classement pour une vérification de livre.

Pour installer et exécuter l'application Bookinfo, procédez comme suit.

  1. Intitulez l'espace de noms qui héberge l'application avec istio-injection=enabled.
    kubectl label namespace default istio-injection=enabled
  2. Déployez l'application Bookinfo échantillon.
    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
  3. Vérifiez que tous les services et pods sont en cours d'exécution.
    kubectl get services
    kubectl get pods
  4. Vérifiez que l'application est en cours d'exécution en envoyant une commande curl à partir d'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. Rendez l'application accessible depuis l'extérieur du cluster.
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  6. Vérifiez que l'application utilise la passerelle. Déterminez INGRESS_HOST et INGRESS_PORT à l'aide de ces instructions.
    curl -s "http://${INGRESS_HOST}:${INGRESS_PORT}/productpage" | grep -o "<title>.*</title>"

Ouvrez également l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur pour afficher la page Web Bookinfo. Actualisez la page plusieurs fois pour voir les différentes versions des critiques affichées sur la page du produit.

Ajout d'applications d'intégration Istio

Istio s'intègre bien avec plusieurs applications populaires liées à Kubernetes.

Prometheus

Istio fournit un exemple d'installation de base pour rendre Prometheus opérationnel rapidement.

kubectl apply -f samples/addons/prometheus.yaml

Vous pouvez également installer prometheus et le configurer pour extraire les mesures Istio.

Pour la surveillance à l'échelle de la production à l'aide de Prometheus, reportez-vous à Utilisation de Prometheus pour la surveillance à l'échelle de la production.

Grafana

Istio fournit un exemple d'installation de base pour rendre Grafana opérationnel rapidement. Tous les tableaux de bord Istio sont inclus dans l'installation.

kubectl apply -f samples/addons/grafana.yaml

Vous pouvez également installer Grafana séparément. En outre, vous pouvez importer les tableaux de bord préconfigurés d'Istio.

Jaeger

Istio fournit un exemple d'installation de base pour que Jaeger soit rapidement opérationnel.

kubectl apply -f samples/addons/jaeger.yaml

Vous pouvez également installer Jaeger séparément et configurer Istio pour envoyer des traces au déploiement Jaeger.

Zipkin

Istio fournit un exemple d'installation de base pour obtenir rapidement zipkin opérationnel.

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

Vous pouvez également installer zipkin séparément et configurer Istio pour envoyer des traces au déploiement zipkin.

Kiali

Istio fournit un exemple d'installation de base pour que Kiali soit rapidement opérationnel :

kubectl apply -f samples/addons/kiali.yaml
            

Vous pouvez également installer et configurer Kiali séparément.

Explorer l'observabilité Istio

Cette section présente les mesures de performances et les fonctionnalités de trace fournies par les applications d'intégration Istio.

Interrogation des mesures à partir de Prometheus pour l'application Bookinfo

Avec Prometheus et Istio, les données de performance de Bookinfo sont analysées de plusieurs façons.

Vérifiez d'abord que Prometheus est installé.

kubectl -n istio-system get svc prometheus

Démarrez l'interface utilisateur Prometheus à l'aide de la commande suivante :

istioctl dashboard prometheus

Cliquez sur Graph à droite de Prometheus dans l'en-tête. Pour afficher certaines données, générez du trafic pour la page du produit à l'aide d'un navigateur ou de curl. Le trafic est reflété dans le tableau de bord Prometheus.

Visualisation des mesures pour l'application Bookinfo avec Grafana

La combinaison de Prometheus avec Grafana fournit de jolis tableaux de bord de performances pour les applications. Pour utiliser les tableaux de bord, vérifiez d'abord que Prometheus et Grafana sont installés.

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

Démarrez le tableau de bord Istio Grafana.

istioctl dashboard grafana

Gestion des tableaux de bord Grafana

Le maillage de services Istio fournit six tableaux de bord Grafana. Les instantanés de tableau de bord Grafana du maillage de service Istio sont capturés ici.

Remarque

Générez le trafic vers la page du produit à l'aide d'un navigateur ou de curl et consultez-le dans le tableau de bord Grafana.

Tableau de bord Istio Mesh

Instantané du tableau de bord Istio Mesh

Tableau de bord de service Istio

Instantané du tableau de bord du service Istio

Tableau de bord de charge de travail Istio

Instantané du tableau de bord de charge de travail Istio

Tableau de bord Performances Istio

Instantané du tableau de bord des performances Istio

Tableau de bord du volet de contrôle Istio

Instantané du tableau de bord du volet de contrôle Istio

Pour plus d'informations sur la création, la configuration et la modification de tableaux de bord, reportez-vous à la documentation Grafana.

Effectuer une trace distribuée à l'aide de Jaeger

Utilisez la structure open source Jaeger pour effectuer le suivi des applications avec Istio.

  1. Activez et configurez la fonction de trace à l'aide de istioctl :
    istioctl install --set meshConfig.enableTracing=true
  2. Une fois l'application Bookinfo déployée, ouvrez l'interface utilisateur Jaeger à l'aide de istioctl.
    istioctl dashboard jaeger
  3. Pour générer des traces, envoyez des demandes à la page du produit.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Vous constatez que les traces sont reflétées dans le tableau de bord Jaeger.

Tableau de bord Jaeger

Tableau de bord Istio Jaeger

Trace dans l'application Jaeger

Instantané de la trace de l'application Istio Jaeger

Effectuer une trace distribuée à l'aide de zipkin

Utilisez la structure open source zipkin pour effectuer le suivi des applications avec Istio.

  1. Activez et configurez la fonction de trace à l'aide de istioctl.
    istioctl install --set meshConfig.enableTracing=true
  2. Une fois l'application Bookinfo déployée, ouvrez l'interface utilisateur zipkin à l'aide de istioctl.
    istioctl dashboard zipkin
  3. Pour générer des traces, envoyez des demandes à la page du produit.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Les traces sont visibles dans le tableau de bord zipkin.

Exemple de tableau de bord zipkin

Instantané du tableau de bord Istio Zipkin

Exécution de la fonction de trace distribuée avec OCI Application Performance Monitoring

OCI Application Performance Monitoring (APM) s'intègre à des outils système de trace open source tels que Jaeger et Zipkin. APM vous permet de télécharger des données de trace dans OCI. Pour effectuer une intégration à OCI APM, créez un domaine APM en suivant les instructions mentionnées ici. Un domaine APM est une ressource OCI qui contient les systèmes surveillés par APM.

Une fois le domaine créé, affichez les détails du domaine et obtenez l'adresse de téléchargement de données, la clé privée et la clé publique pour construire l'URL du collecteur APM. L'URL du collecteur APM est requise lors de la configuration des traceurs open source pour communiquer avec le service APM. Le format d'URL de collecteur nécessite une URL construite à l'aide de l'adresse de téléchargement de données en tant qu'URL de base et génère le chemin en fonction de choix, y compris les valeurs de notre clé privée ou publique. Le format est documenté ici. Une fois le chemin d'URL construit, connectez l'URL à la configuration Istio.

Remarque

Pour plus d'informations sur la configuration des stratégies de service APM, reportez-vous aux sections suivantes :

Configuration d'Istio pour l'envoi de traces à APM

  1. Activez la fonction de trace avec istioctl.
    istioctl install --set meshConfig.defaultConfig.tracing.zipkin.address=aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com:443
    Remarque

    L'adresse d'adresse de aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com est un exemple et non une adresse réelle.
  2. Configurez Envoy pour envoyer les traces zipkin à APM. Remplacez le code dans samples/custom-bootstrap/custom-bootstrap.yaml par le bloc de code suivant.
    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. Appliquez la configuration personnalisée.
    kubectl apply -f samples/custom-bootstrap/custom-bootstrap.yaml
  4. Pour que tous nos services dans Bookinfo utilisent cette configuration de démarrage personnalisée, ajoutez une annotation sidecar.istio.io/bootstrapOverride avec le nom ConfigMap personnalisé comme valeur. Dans l'exemple suivant, une annotation est ajoutée pour la page de produit sous samples/bookinfo/platform/kube/bookinfo.yaml. Ajoutez une annotation similaire à d'autres services.
    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. Appliquez le yaml, tous les pods redémarrés commencent à envoyer des traces à APM.
    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
  6. Pour permettre à une passerelle entrante d'envoyer des traces, créez une instance configmap nommée custom-bootstrap.yaml dans l'espace de noms istio-système :
    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. Créez un patch nommé gateway-patch.yaml pour la passerelle entrante afin de commencer à utiliser la configuration 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. Appliquez le patch précédent pour la passerelle entrante :
    kubectl --namespace istio-system patch deployment istio-ingressgateway --patch "$(cat gateway-patch.yaml)"
  9. Pour générer des traces, envoyez des demandes à la page du produit.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Vous voyez que les traces sont reflétées dans le tableau de bord APM en suivant les étapes ici.

Explorateur de traces Zipkin

Capture d'écran de l'explorateur de traces Zipkin

Trace Zipkin

Capture d'écran d'une trace Zipkin

Espaces Zipkin

Pour afficher les étendues, cliquez sur Accueil dans la liste APM.

Capture d'écran d'une étendue Zipkin

Tableau de bord de l'application Zipkin

APM fournit des fonctionnalités permettant de créer des tableaux de bord et d'explorer les étendues générées au fil du temps. Vous pouvez créer des tableaux de bord en suivant les étapes ici.

Capture d'écran d'un tableau de bord d'application Zipkin

Explorateur de mesures Zipkin

APM vous permet de surveiller l'état, la capacité et les performances de vos applications à l'aide de mesures, d'alarmes et de notifications. Suivez les étapes ici pour configurer les mesures.

Capture d'écran d'un explorateur de métriques Zipkin

Observation des journaux avec OCI Logging

OCI Logging est un composant central permettant d'analyser et de rechercher des entrées de fichier journal pour les locations dans OCI. Les journaux de conteneur Kubernetes des noeuds de processus actif OKE peuvent être publiés en tant que journaux personnalisés vers OCI Logging. Suivez les étapes décrites ici pour configurer OCI Logging afin d'inclure les journaux de conteneur.

  1. Activez la connexion de l'accès envoyé à Istio avec istioctl.
    istioctl install --set meshConfig.accessLogFile=/dev/stdout
  2. Accédez à la page produit Bookinfo à l'aide d'un navigateur ou d'une boucle. Les journaux d'accès générés peuvent être affichés à l'aide de la commande kubectl.
    kubectl logs -l app=productpage -c istio-proxy

Si OCI Logging est configuré pour le cluster, ces journaux peuvent être interrogés et analysés à l'aide de la page de recherche de journal de la console OCI.

Recherche OCI Logging

Capture d'écran d'une recherche OCI Logging

Recherche OCI Logging étendue

Capture d'écran d'une recherche OCI Logging étendue

Visualisation du maillage à l'aide de Kiali

Vérifiez que Kiali est installé.

kubectl -n istio-system get svc kiali

Ouvrez l'interface utilisateur Kiali dans le navigateur.

istioctl dashboard kiali

Envoyez du trafic vers la page du produit.

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

Visualisez votre maillage dans Kiali en suivant l'étape 5 ici.

Gérer le trafic

Les règles de routage du trafic d'Istio vous permettent de contrôler le flux du trafic entre les services et simplifient la configuration des propriétés de niveau de service telles que les disjoncteurs, les délais d'attente et les nouvelles tentatives. Istio facilite la configuration de tâches importantes telles que les tests A/B, les déploiements de canari et les déploiements intermédiaires avec des fractionnements de trafic basés sur un pourcentage.

Ressources de l'API de gestion du trafic d'Istio :

Pour qu'Istio contrôle le routage des versions de l'application Bookinfo, définissez toutes les versions disponibles de votre service, appelées sous-ensembles, dans les règles de destination. Créez des règles de destination par défaut pour les services Bookinfo :
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

Changer le trafic

Istio nous permet de migrer progressivement le trafic d'une version d'un microservice à une autre en utilisant la fonction de routage pondéré d'Istio. L'exemple suivant montre comment configurer pour envoyer 50 % du trafic vers reviews:v1 et 50 % vers reviews:v3. Ensuite, terminez la migration en envoyant 100 % du trafic à reviews:v3.

  1. Acheminez tout le trafic vers la version v1 de chaque microservice.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

    Pour afficher la page Web Bookinfo, ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur. Notez que la partie des évaluations de la page s'affiche sans étoiles d'évaluation, quel que soit le nombre d'actualisations. Istio est configuré pour acheminer tout le trafic du service de révision vers reviews:v1 et cette version du service n'accède pas au service de classement par étoiles.

  2. Transférez 50 % du trafic de reviews:v1 vers reviews:v3 à l'aide de la commande suivante et attendez que les nouvelles règles se propagent.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml

    Actualisez l'URL /productpage dans votre navigateur et voyez des étoiles de couleur rouge environ 50 % du temps. reviews:v3 accède au service d'évaluation par étoiles, mais pas à la version reviews:v1.

  3. Acheminez maintenant 100 % du trafic vers reviews:v3.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml
  4. Actualisez l'URL /productpage dans votre navigateur et voyez des étoiles de couleur rouge tout le temps pour chaque critique.

Gestion du routage des demandes

Istio peut acheminer le trafic de plusieurs façons. Pour démarrer, configurez Istio pour acheminer tout le trafic via v1 de chaque microservice.
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

Pour afficher la page Web Bookinfo, ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur. Notez que la partie des évaluations de la page s'affiche sans étoiles d'évaluation, quel que soit le nombre d'actualisations. Parce qu'Istio est configuré pour acheminer tout le trafic du service de révisions vers la version reviews:v1. Cette version du service n'accède pas au service d'évaluation par étoiles.

Capture d'écran d'un exemple de livre Booinfo.

Routage basé sur l'identité de l'utilisateur

Pour effectuer un routage en fonction de l'identité de l'utilisateur :

  1. Modifiez la configuration de routage de sorte que tout le trafic d'un utilisateur spécifique nommé jason soit acheminé vers reviews:v2. Istio n'a aucune compréhension spéciale et intégrée de l'identité de l'utilisateur. Dans cet exemple, le service productpage ajoute un en-tête d'utilisateur final personnalisé à toutes les demandes HTTP sortantes au service de révision.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
  2. Pour afficher la page Web Bookinfo et vous connecter en tant qu'utilisateur jason, ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur. Actualisez le navigateur pour voir que les étoiles s'affichent en regard de chaque évaluation.

    Capture d'écran d'un échantillon de livre Booinfo avec des étoiles
  3. Ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur pour afficher la page Web Bookinfo et connectez-vous en tant qu'utilisateur autre que jason. Actualisez le navigateur pour ne voir aucune étoile pour chaque évaluation.

    Capture d'écran d'un échantillon de livre Booinfo sans étoiles

Routage basé sur la réécriture d'URL

Dans cet exemple, les demandes HTTP dont le chemin commence par /products ou /bookinfoproductpage sont réécrites vers /productpage. Les demandes HTTP sont envoyées aux pods avec productpage en cours d'exécution sur le port 9080. Pour plus d'informations sur la réécriture d'URL Istio, consultez cette page.

  1. Appliquez le yaml suivant :
    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. Pour afficher la page Web Bookinfo, ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/products et http://${INGRESS_HOST}:${INGRESS_PORT}/bookinfoproductpage dans un navigateur. Dans les deux cas, une réécriture est effectuée avant le transfert de la demande.

    Réécrire /bookproductpage

    Capture d'écran d'un exemple de livre Booinfo avec /bookproductpage

    Réécrire /produits

    Capture d'écran d'un échantillon de livre Booinfo avec /products
  3. Nettoyez le fichier yaml à la version originale fournie par Istio et appliquez-le.
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  4. Ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/bookinfoproductpage ou http://${INGRESS_HOST}:${INGRESS_PORT}/products pour ne pas voir la page du produit car yaml ne réécrit pas la demande.

    Erreur 404 /produits

    Capture d'écran d'un échantillon de livre Booinfo avec /products 404

    Erreur 404 /booksproductpage

    Capture d'écran d'un exemple de livre Booinfo avec /booksproductpage 404

Tester la résilience du réseau

Istio vous permet de configurer votre installation pour les délais d'attente des demandes, l'injection de pannes et les disjoncteurs. Ces paramètres permettent de gérer et de tester la tolérance aux pannes des applications déployées.

Définir des délais d'expiration de demande

Un délai d'expiration est la durée pendant laquelle un proxy Envoy attend les réponses d'un service donné. Le délai d'attente garantit que les services n'attendent pas les réponses indéfiniment et que les appels réussissent ou échouent dans un délai prévisible. Pour plus d'informations sur les délais d'expiration, voir ici.

Un délai d'expiration pour les demandes HTTP peut être spécifié à l'aide du champ de délai d'expiration de la règle de routage. Par défaut, le délai d'expiration de la demande est désactivé.

  1. Initialisez le routage de la version de l'application en exécutant la commande suivante :
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. Acheminez les demandes vers le service reviews:v2, en fait, une version qui appelle le service d'évaluation :
    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. Ajoutez un délai de 2 secondes aux appels au service d'évaluation :
    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. Pour afficher la page Web Bookinfo avec les étoiles d'évaluation affichées, ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur. Un délai de 2 secondes se produit lorsque vous actualisez la page.
    Capture d'écran de la page Web du produit du livre.
  5. Ajoutez un délai d'expiration de demande d'une demi-seconde pour les appels au service de révision :
    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. Pour afficher la page Web Bookinfo, ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur. Notez que la page revient dans environ 1 seconde, au lieu de 2, et que les commentaires ne sont pas disponibles.
    Capture d'écran de la page Web du produit du livre.

La raison pour laquelle la réponse prend 1 seconde, même si le délai d'expiration est configuré à une demi-seconde, est une nouvelle tentative codée en dur dans le service productpage. Le service appelle deux fois le service des révisions expirées avant de revenir.

En plus de les remplacer dans les règles de routage, le délai d'expiration peut également être remplacé par demande si l'application ajoute un en-tête x-envoy-upstream-rq-timeout-ms sur les demandes sortantes.

Gestion de l'injection d'erreur

L'injection de pannes est une méthode de test qui introduit des erreurs dans un système pour s'assurer que le système résiste et récupère des conditions d'erreur. Istio permet l'injection de pannes au niveau de la couche d'application, comme les codes d'erreur HTTP. Istio injecte deux types de pannes, tous deux configurés à l'aide d'un service virtuel. Pour plus d'informations sur l'injection de pannes, voir ici.

  • Délais : les retards sont des échecs de synchronisation qui imitent une latence réseau accrue ou un service en amont surchargé.
  • Abandons : les abandons sont des pannes qui imitent les pannes des services en amont. Abandonne le manifeste sous la forme de codes d'erreur HTTP ou d'échecs de connexion TCP.

Pour tester l'injection de panne, exécutez la commande suivante pour initialiser le routage de la version de l'application :

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

Injection d'une erreur de délai HTTP

Pour injecter une erreur de retard, procédez comme suit :

  • Créez une règle d'injection de panne pour retarder le trafic provenant de l'utilisateur jason. La commande suivante injecte un délai de 7 secondes entre reviews:v2 et les microservices d'évaluation pour l'utilisateur jason.
    kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
    Remarque

    Le service reviews:v2 a un délai d'expiration de connexion codée en dur de 10 secondes pour les appels au service d'évaluation. Avec un délai de 7 secondes, attendez-vous à ce que le flux de bout en bout se poursuive sans erreur.
  • Pour afficher la page Web Bookinfo, ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur.
    Cliché de la page Bookinfo affichant les erreurs de délai

    La page d'accueil Bookinfo se charge sans erreur en environ sept secondes. Toutefois, la section des révisions affiche un message d'erreur : Désolé, les révisions de produit ne sont actuellement pas disponibles pour ce livre. Un bogue existe dans le code de l'application. Le délai d'expiration codé en dur entre le service productpage et le service reviews entraîne un délai de 6 secondes, 3 secondes plus 1 nouvelle tentative. Par conséquent, l'appel productpage vers reviews expire prématurément et génère une erreur au bout de 6 secondes.

    Pour corriger le bogue, augmentez le délai d'expiration du service productpage à reviews ou réduisez le délai d'expiration du service reviews à ratings à moins de 3 secondes.

  • Corrigeons le bogue en ajoutant un délai de 2 secondes au service ratings pour l'utilisateur 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
  • Maintenant que le bogue est corrigé, ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur pour afficher la page Web Bookinfo. Connectez-vous en tant que jason avec des étoiles d'évaluation affichées.
    Cliché de la page Bookinfo sans erreurs dely

Injection d'une erreur d'abandon HTTP

Pour injecter une erreur d'abandon, procédez comme suit :

  1. Créez une règle d'injection d'erreur pour envoyer une réponse d'abandon HTTP à l'utilisateur jason :
    kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
  2. Pour afficher la page Web Bookinfo, ouvrez l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur. Connectez-vous en tant qu'utilisateur jason. Un message indique que le service ratings n'est pas disponible.
    Capture d'écran de la page Bookinfo avec service d'évaluation indisponible

    Déconnectez-vous de l'utilisateur jason ou connectez-vous avec un autre utilisateur pour ne voir aucun message d'erreur.

    Capture d'écran de la page Bookinfo sans erreur

Création de disjoncteurs

La coupure de circuit nous permet d'écrire des applications qui limitent l'impact des pannes, des pics de latence et d'autres effets indésirables des particularités du réseau. Pour plus d'informations sur les disjoncteurs, voir ici.

  1. Créez une règle de destination pour appliquer les paramètres de coupure de circuit lors de l'appel du service produit. La règle suivante définit le nombre maximal de connexions à ne pas dépasser une et comporte un maximum d'une demande HTTP en attente. En outre, les règles configurent les hôtes à analyser toutes les 1 seconde. Tout hôte qui échoue une fois avec un code d'erreur 5XX est éjecté pendant 3 minutes. En outre, 100 % des hôtes du pool d'équilibrage de charge pour le service en amont sont éjectés.
    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. Acheminez tout le trafic vers la version v1 de chaque microservice.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  3. Créez un client pour envoyer du trafic au service produit. Fortio vous permet de contrôler le nombre de connexions, la simultanéité et les délais pour les appels HTTP sortants. Si vous avez activé l'injection sidecar automatique, déployez le service fortio :
    kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml
    Vous pouvez également injecter manuellement le sidecar avant de déployer l'application fortio.
    kubectl apply -f <(istioctl kube-inject -f samples/httpbin/sample-client/fortio-deploy.yaml)
  4. Connectez-vous au pod client et utilisez l'outil fortio pour appeler productpage et vérifiez que le code de statut de réponse est 200 avec les commandes suivantes.
    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
    
    La sortie suivante est générée :
    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. Appelez le service avec 2 connexions simultanées (-c 2) et envoyez 20 demandes (-n 20). Fait intéressant, 16 demandes de transfert et 4 échouent.
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://productpage:9080
    La commande produit un résultat semblable à ce qui suit.
    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. Augmentez le nombre de connexions simultanées à 3.
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 30 -loglevel Warning http://productpage:9080
    Seulement 26,7% des demandes ont réussi et la coupure de circuit piège le reste.
    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. Interrogez les statistiques istio-proxy pour obtenir plus d'informations.
    kubectl exec "$FORTIO_POD" -c istio-proxy -- pilot-agent request GET stats | grep productpage | grep pending
    Indicateur de coupure de circuit 32 appels en examinant la mesure 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. Nettoyez le client.
    kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
    kubectl delete deploy fortio-deploy
    kubectl delete svc fortio

Mise en miroir

La mise en miroir du trafic, également appelée ombrage, permet aux équipes d'apporter des modifications à la production avec le moins de risques possible. La mise en miroir envoie une copie du trafic en direct à un service mis en miroir. Le trafic mis en miroir se produit en dehors du chemin de demande critique pour le service principal.

  1. Acheminez tout le trafic vers la version v1 de chaque microservice.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. Remplacez la règle de routage par le trafic miroir 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 règle de routage précédente envoie 100 % du trafic vers reviews:v1 et met en miroir 100 % du même trafic vers le service reviews:v2.

    Lorsque le trafic est mis en miroir, les demandes sont envoyées au service mis en miroir avec leurs en-têtes d'hôte/d'autorité ajoutés à la fin de -shadow. Par exemple, les critiques deviennent des demandes reviews-shadow.Mirrored considérées comme "fire and forget". Les réponses mises en miroir sont ignorées.

    Au lieu de mettre en miroir toutes les demandes, modifiez le champ de valeur sous le champ mirrorPercentage pour mettre en miroir une fraction du trafic. Si ce champ est absent, tout le trafic est mis en miroir.

  3. Envoyez du trafic en actualisant l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur.
  4. Journaux du service reviews:v1. Notez que le service v1 n'appelle pas le service d'évaluation.
    Capture à plusieurs degrés du service reviews:v1
  5. Journaux du service mis en miroir reviews:v2. Pour le service v2, l'en-tête est ajouté à la fin avec -shadow.
    Capture à plusieurs degrés du service reviews:v2 avec -shadow

Gestion des passerelles

Gateway décrit un équilibreur de charge fonctionnant en périphérie du maillage recevant des connexions HTTP/TCP entrantes ou sortantes. Les configurations de passerelle sont appliquées aux proxies Envoy autonomes qui s'exécutent en périphérie du maillage, plutôt qu'aux proxies Envoy sidecar s'exécutant parallèlement à vos charges globales de service. Istio fournit des déploiements de proxy de passerelle préconfigurés : istio-ingressgateway et istio-egressgateway.

Si vous n'avez pas configuré les passerelles Istio dans le cadre de l'installation, exécutez la commande suivante pour les installer.
istioctl install

La commande déploie Istio en utilisant les paramètres par défaut qui incluent une passerelle. Pour plus d'informations, voir ici.

Remarque

Déterminez INGRESS_HOST et INGRESS_PORT à l'aide de ces instructions.

Configuration de l'entrée à l'aide d'Istio Gateway

La passerelle entrante configure des ports et des protocoles exposés, mais contrairement aux ressources entrantes Kubernetes, elle n'inclut aucune configuration de routage de trafic. Le routage du trafic entrant est configuré à l'aide des règles de routage Istio. Pour plus d'informations sur l'entrée Istio, consultez cette page.

Remarque

Si vous avez déjà déployé l'application Bookinfo, les étapes suivantes ne sont pas requises.
  1. Créez une passerelle Istio qui configure sur le port 80 pour le trafic 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. Configurez les routages pour le trafic entrant via la passerelle :
    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. Pour déployer l'application Bookinfo, reportez-vous à la section "Exécution de l'application Bookinfo" de la page Installation d'Istio et d'OKE.
  4. Accédez au service productpage à l'aide de curl :
    curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/productpage

    La commande génère la sortie suivante :

    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. Accédez à toute autre URL qui n'a pas été explicitement exposée. Une erreur HTTP 404 s'affiche.
    curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/any

    La commande génère la sortie suivante :

    HTTP/1.1 404 Not Found
    date: Tue, 07 Sep 2021 13:49:45 GMT
    server: istio-envoy
    transfer-encoding: chunked
  6. Pour les hôtes explicites dans les passerelles, utilisez l'indicateur -H pour définir l'en-tête HTTP de l'hôte. L'indicateur est nécessaire car la passerelle entrante et le service virtuel sont configurés pour gérer l'hôte. Par exemple, l'hôte est example.com et le nom est indiqué dans les passerelles et le service virtuel.
    curl -s -I -HHost:example.com http://$INGRESS_HOST:$INGRESS_PORT/productpage
  7. Ouvrez également l'URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage dans un navigateur pour afficher la page Web Bookinfo.

Configuration de l'entrée à l'aide de la ressource entrante Kubernetes

Le lecteur suppose que l'application Bookinfo est déployée dans le cluster. Pour déployer l'application Bookinfo, reportez-vous à la section "Exécution de l'application Bookinfo" de la page Installation d'Istio et d'OKE.

  1. Supprimez la passerelle Istio si la configuration est déjà appliquée.
    kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml
  2. Créez une ressource entrante sur le port 80 pour le trafic 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'annotation kubernetes.io/ingress.class est requise pour indiquer au contrôleur de passerelle Istio de gérer ce Ingress.

  3. Vérifiez l'accès à l'application Bookinfo en suivant les instructions de la section précédente.
  4. Supprimez la ressource et activez la passerelle Istio pour d'autres tâches.
    kubectl delete ingress ingress
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

Accéder aux services externes avec la sortie

Par défaut, tout le trafic sortant d'un pod compatible Istio est redirigé vers son proxy sidecar et Istio configure le proxy Envoy pour qu'il transmette les demandes de services inconnus. Istio configure la gestion sidecar des services externes via un champ de configuration meshConfig.outboundTrafficPolicy.mode. Si cette option est définie sur :

  • ALLOW_ANY (valeur par défaut) : le proxy Istio permet le passage des appels vers des services inconnus.
  • REGISTRY_ONLY : le proxy Istio bloque tout hôte sans entrée de service ou de service HTTP définie dans le maillage.

Le lecteur suppose que l'application Bookinfo est déployée dans le cluster. Si ce n'est pas le cas, suivez les étapes pour déployer l'application Bookinfo.

Gestion du transfert d'Envoy aux services externes

Pour activer le transfert vers des services externes, procédez comme suit.

  1. Remplacez l'option meshConfig.outboundTrafficPolicy.mode par ALLOW_ANY avec istioctl.
    istioctl install --set meshConfig.outboundTrafficPolicy.mode=ALLOW_ANY
    Remarque

    Cette étape est requise uniquement si vous avez explicitement défini l'option sur REGISTRY_ONLY au cours de l'installation.
  2. Pour confirmer les 200 réponses réussies, adressez une demande aux services externes à partir de 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"
    La commande génère la sortie suivante :
    HTTP/1.1 200 OK

Cependant, l'inconvénient de cette approche est que la surveillance et le contrôle Istio du trafic vers les services externes sont perdus.

Contrôle de l'accès aux services externes [Recommandé]

Pour paramétrer l'accès contrôlé aux services externes, procédez comme suit :

  1. Remplacez l'option meshConfig.outboundTrafficPolicy.mode par REGISTRY_ONLY. Cette étape est requise uniquement si vous n'avez pas défini explicitement l'option sur REGISTRY_ONLY au cours de l'installation.
  2. Suivez uniquement l'étape 1 de la section "Transfert d'Envoyé vers des services externes". La seule modification à apporter ici est de remplacer ALLOW_ANY par REGISTRY_ONLY.
  3. Pour vérifier que les services externes sont bloqués, effectuez quelques demandes aux services HTTPS externes à partir de SOURCE_POD. La propagation des modifications de configuration prend plusieurs secondes, de sorte que les connexions réussies sont possibles. Attendez plusieurs secondes, puis réessayez la dernière commande.
    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"

    La commande génère la sortie suivante :

    HTTP/1.1 502 Bad Gateway
  4. Créez un élément ServiceEntry pour autoriser l'accès à un service HTTP externe.
    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. Faites une demande au service HTTP externe à partir de SOURCE_POD. Notez que les en-têtes ajoutés par le proxy Istio sidecar sont X-Envoy-Decorator-Operation.
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
    La commande génère la sortie suivante :
    HTTP/1.1 200 OK

    Supprimez la commande grep pour afficher tous les en-têtes.

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

    La commande génère la sortie suivante :

    {
      "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. Pour accéder aux appels HTTPS, remplacez le port et le protocole lors de la création des entrées de service.
  7. Cette approche ajoute des fonctionnalités de gestion du trafic de service externe telles que les délais d'attente et l'injection de pannes. La demande suivante renvoie 200 (OK) en environ cinq secondes.
    kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
    Utilisez kubectl pour définir un délai d'expiration de 3 secondes sur les appels au service externe 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
    Cette fois, un délai d'expiration apparaît au bout de 3 secondes. Même si httpbin.org attendait cinq secondes, Istio a interrompu la demande à 3 secondes :
    kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
  8. Nettoyez les ressources pour d'autres tâches futures.
    kubectl delete serviceentry httpbin-ext
    kubectl delete virtualservice httpbin-ext --ignore-not-found=true

Diriger l'accès aux services externes

Cette approche contourne le proxy Istio sidecar, donnant aux services un accès direct à tout serveur externe. Toutefois, la configuration du proxy nécessite des connaissances et une configuration spécifiques au fournisseur de cluster. Comme pour la première approche, nous perdons la surveillance de l'accès aux services externes et ne pouvons pas appliquer les fonctionnalités Istio sur le trafic aux services externes. Suivez ces étapes pour fournir un accès direct aux services externes.

Sécuriser Istio

Les fonctionnalités de sécurité Istio fournissent une identité forte, une stratégie puissante, un cryptage TLS transparent et des outils d'authentification, d'autorisation et d'audit (AAA) pour protéger vos services et vos données.

Configuration de l'authentification

Istio offre le TLS mutuel en tant que solution de pile complète pour l'authentification de transport, qui est activée sans nécessiter de modifications de code de service.

Déployez les services sleep et httpbin dans l'espace de noms par défaut.
kubectl apply -f samples/sleep/sleep.yaml
kubectl apply -f samples/httpbin/httpbin.yaml

Par défaut, Istio effectue plusieurs tâches. Istio suit les charges de travail du serveur migrées vers les proxies Istio. Istio configure les proxies client pour envoyer automatiquement le trafic TLS mutuel à ces charges de travail. Istio envoie du trafic de texte brut aux charges de travail sans sidecars.

Pour vérifier que les certificats sont envoyés, envoyez une demande à partir d'un pod sleep vers le pod httpbin et recherchez l'en-tête 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>;/'
Déployez une autre instance des services sleep et httpbin sans activer le sidecar.
kubectl create ns legacy
kubectl apply -f samples/sleep/sleep.yaml -n legacy
kubectl apply -f samples/httpbin/httpbin.yaml -n legacy
La demande du pod sleep dans l'espace de noms par défaut au pod httpbin dans l'espace de noms hérité est en texte brut car la destination n'est pas activée en mode sidecar. Vérifiez que le texte brut est envoyé en exécutant la commande suivante.
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
La demande du pod sleep dans l'espace de noms hérité vers httpbin dans l'espace de noms par défaut réussit également avec une connexion en texte brut. Vous pouvez le vérifier à l'aide de la commande suivante.
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
Pour empêcher le trafic TLS non mutuel pour l'ensemble du maillage, définissez une stratégie d'authentification de pair à l'échelle du maillage avec le mode TLS mutuel défini sur STRICT.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "default"
  namespace: "istio-system"
spec:
  mtls:
    mode: STRICT
EOF
La connexion entre un pod sleep dans l'espace de noms hérité et httpbin dans l'espace de noms par défaut ne fonctionne plus lorsque le mode TLS mutuel est défini sur 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
Rétablissez le paramètre d'authentification pair STRICT en supprimant le CR.
kubectl delete peerauthentication -n istio-system default

Outre le paramètre TLS mutuel global, il peut également être défini au niveau d'un espace de noms ou d'une charge globale. Suivez la documentation Istio pour obtenir des configurations d'authentification détaillées.

Configurer l'autorisation

Istio vous permet de configurer des stratégies d'autorisation pour vos applications.

Configurez d'abord une stratégie allow-nothing simple qui rejette toutes les demandes de la charge globale, puis accorde un accès plus important à la charge globale progressivement et de manière incrémentielle.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing
  namespace: default
spec:
  {}
EOF

Ouvrez la page produit Bookinfo dans votre navigateur. Elle affiche l'erreur "RBAC: access denied" confirmant que la stratégie deny-all fonctionne comme prévu.

Créez une stratégie pour accorder à tous les utilisateurs et charges globales l'accès à la page du produit à l'aide de la commande suivante.
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

La page "Exemple Bookinfo" s'affiche, mais le service productpage ne peut pas accéder à la page de détails et de révisions.

Ajoutez les stratégies suivantes pour accorder à la charge globale productpage l'accès aux détails, examiner les charges globales et examiner l'accès à la charge globale ratings.

Définir le visualiseur de détails

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

Définir la visionneuse des révisions

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

Définir le visualiseur de notations

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

Afficher la page du produit à partir d'un navigateur sans erreur.

Pour rétablir les stratégies appliquées, entrez les commandes suivantes.

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

Sécurisation des passerelles avec TLS

Nous pouvons exposer l'application Bookinfo en tant que service HTTPS sécurisé à l'aide de TLS simple ou mutuel. Pour signer les certificats de vos services, créez un certificat racine et une clé privée :

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

Créez un certificat et une clé privée pour 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

Assurez-vous d'avoir déployé l'application Bookinfo. Créez une clé secrète pour les certificats de passerelle entrante.

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

Mettez à jour la passerelle Bookinfo pour inclure un port sécurisé.

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

Créez des règles de destination Bookinfo si elles ne sont pas déjà créées.

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

Créez un service virtuel lié à la passerelle.

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

Vous pouvez vérifier la connexion TLS à la passerelle à l'aide de la commande curl suivante.

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