Utilisation d'Istio en tant que programme autonome

Découvrez comment installer Istio en tant que programme autonome sur les grappes que vous avez créées avec Kubernetes Engine (OKE).

Cette rubrique fournit un exemple d'installation d'Istio en tant que programme autonome sur les grappes que vous avez créées avec Kubernetes Engine (OKE). En outre, les fonctionnalités clés d'OKE et d'Istio sont démontrées.

Rubriques couvertes :

Notez que les produits de maillage de services (tels que Istio et Linkerd) sont pris en charge lors de l'utilisation du plugiciel CNI de réseau de pods natifs du VCN OCI pour le réseau de pods. Notez qu'à l'exception du module complémentaire Istio, la prise en charge est actuellement limitée à Oracle Linux 7 (la prise en charge d'Oracle Linux 8 est planifiée). Le module complémentaire Istio est pris en charge à la fois avec Oracle Linux 7 et Oracle Linux 8. Les noeuds de travail doivent exécuter Kubernetes 1.26 (ou version ultérieure).

Note

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

Installation d'Istio en tant que programme autonome

Pour commencer à utiliser Istio, créez une grappe OKE ou utilisez une grappe OKE existante, 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éer un cluster OKE

Créez un cluster OKE.

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

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 vérification préalable :
    istioctl x precheck

Installation d'Istio avec istioctl

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

Exécution de l'application Bookinfo

Le projet Istio fournit l'application Bookinfo comme un moyen de démontrer les fonctionnalités d'Istio. L'application affiche des informations sur un livre, similaires à une entrée de catalogue unique d'un magasin de livres 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, consultez les documents Bookinfo ici.

Un diagramme de l'application Bookinfo

Comme vous pouvez le voir sur 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 : Retourne les informations sur le registre.
  • Service d'évaluations : Retourne les révisions de registre et appelle le service Notations.
  • Service de notation : Retourne les informations de classement pour une révision de registre.

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

  1. Étiquette de l'espace de noms qui héberge l'application avec istio-injection=enabled.
    kubectl label namespace default istio-injection=enabled
  2. Déployez l'exemple d'application Bookinfo.
    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. Rendre 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 évaluations affichées sur la page du produit.

Ajout d'applications d'intégration Istio

Istio s'intègre parfaitement à plusieurs applications connexes populaires à Kubernetes.

Prométhée

Istio fournit un exemple d'installation de base pour rapidement mettre en service Prometheus.

kubectl apply -f samples/addons/prometheus.yaml

Vous pouvez également installer prometheus et configurer celui-ci pour gratter les mesures Istio.

Pour la surveillance à l'échelle de la production à l'aide de Prometheus, voir 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, il est possible d'importer les tableaux de bord préconfigurés d'Istio.

Jaeger

Istio fournit un exemple d'installation de base pour permettre à Jaeger de fonctionner rapidement.

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 rapidement mettre en marche le zipkin.

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

Dans cette section, vous allez explorer les mesures de performances et les fonctions de trace fournies par les applications d'intégration Istio.

Interrogation de mesures 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

Sélectionnez Graph à droite de Prometheus dans l'en-tête. Pour voir 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 et de Grafana fournit des tableaux de bord performants 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 du tableau de bord du maillage de services Istio Grafana sont saisis ici.

Note

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

Tableau de bord Istio Mesh

Instantané du tableau de bord du maillage Istio

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

Istio Performance - Tableau de bord

Instantané du tableau de bord de rendement 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, consultez la documentation sur Grafana.

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

Utilisez l'environnement open source Jaeger pour effectuer le suivi des applications avec Istio.

  1. Activez et configurez le traçage à 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

Instantané du tableau de bord Istio Jaeger

Trace de l'application Jaeger

Instantané de la trace de l'application Istio Jaeger

Effectuer un traçage distribué à l'aide de zipkin

Utilisez le cadre open source zipkin pour effectuer le traçage d'application avec Istio.

  1. Activez et configurez le traçage à 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

Vous voyez que les traces se reflètent dans le tableau de bord zipkin.

Exemple de tableau de bord zipkin

Instantané du tableau de bord Istio Zipkin

Exécution du traçage distribué avec OCI Application Performance Monitoring

OCI Application Performance Monitoring (APM) s'intègre à des outils de système de suivi à code source libre tels que Jaeger et zipkin. APM vous permet de charger des données de trace dans OCI. Pour l'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éé, consultez les détails du domaine et obtenez le point d'extrémité de chargement des 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 du collecteur nécessite une URL construite à l'aide du point d'extrémité de chargement des données comme URL de base et génère le chemin d'accès 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-le à la configuration Istio.

Note

Pour plus d'informations sur la configuration des politiques de service APM, voir :

Configuration d'Istio pour envoyer des traces à APM

  1. Activez le traçage avec istioctl.
    istioctl install --set meshConfig.defaultConfig.tracing.zipkin.address=aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com:443
    Note

    L'adresse du point d'extrémité aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com est un exemple et non un point d'extrémité réel.
  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 d'amorçage 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 valeur 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 correctif nommé gateway-patch.yaml pour que la passerelle entrante commence à utiliser la configuration d'amorçage personnalisée :
    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 correctif 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 apparaissent dans le tableau de bord APM en suivant les étapes ici.

Zipkin Trace Explorer

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

Zipkin Trace

Capture d'écran d'une trace Zipkin

Zipkin Spans

Pour voir les intervalles, sélectionnez Accueil dans la liste APM.

Capture d'écran d'une portée de Zipkin

Tableau de bord de l'application Zipkin

APM offre des fonctionnalités permettant de créer des tableaux de bord et d'explorer les intervalles générés 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

Explorer les mesures Zipkin

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

Capture d'écran d'un explorateur de mesures Zipkin

Observation des journaux à l'aide du service de journalisation OCI

Le service de journalisation OCI est un composant central pour analyser et rechercher des entrées de fichier journal pour les locations dans OCI. Les journaux de conteneur Kubernetes des noeuds de travail OKE peuvent être publiés en tant que journaux personnalisés dans le service de journalisation OCI. Suivez les étapes décrites ici pour configurer le service de journalisation pour OCI afin d'ingérer les journaux de conteneur.

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

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

Recherche de journaux OCI

Capture d'écran d'une recherche de journalisation OCI

Recherche de journalisation OCI développée

Capture d'écran d'une recherche de journalisation OCI développée

Visualiser le 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.

Gestion du trafic

Les règles d'acheminement 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 temporisations et les nouvelles tentatives. Istio facilite la configuration de tâches importantes telles que les tests A/B, les déploiements de test canari et les déploiements intermédiaires avec des fractionnements de trafic basés sur un pourcentage.

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

Pour qu'Istio contrôle le routage de la version 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

Déplacement du trafic

Istio nous permet de migrer progressivement le trafic d'une version d'un microservice vers une autre version à l'aide de la fonction de routage pondéré d'Istio. L'exemple suivant montre comment configurer pour envoyer 50 % du trafic à reviews:v1 et 50 % à 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 de notation, quel que soit le nombre de fois que vous actualisez. Istio est configuré pour acheminer tout le trafic pour le service d'évaluation vers reviews:v1 et cette version du service n'accède pas au service d'évaluation en étoile.

  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 les notations en étoile de couleur rouge environ 50 % du temps. reviews:v3 accède au service de notation en étoile, 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 les notations en étoile de couleur rouge tout le temps pour chaque évaluation.

Gestion de l'acheminement des demandes

Istio peut acheminer le trafic de plusieurs façons. Pour commencer, 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 de notation, quel que soit le nombre de fois que vous actualisez. Parce qu'Istio est configuré pour acheminer tout le trafic du service d'évaluation vers la version reviews:v1. Cette version du service n'accède pas au service de notation en étoile.

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

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

Pour acheminer 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 voir 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 notations en étoile apparaissent à côté de chaque évaluation.

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

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

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

Dans cet exemple, les demandes HTTP dont le chemin commence par /products ou /bookinfoproductpage sont réécrites en /productpage. Des demandes HTTP sont envoyées aux pods dont productpage s'exécute sur le port 9080. Pour plus d'informations sur la réécriture de l'URL Istio, voir ici.

  1. Appliquer 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 voir 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 exemple de livre Booinfo avec /produits
  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 l'yaml ne réécrit pas la demande.

    Erreur/produits 404

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

    Erreur 404 /booksproductpage

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

Test de la résilience du réseau

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

Définition des délais d'attente des demandes

Une temporisation est la durée pendant laquelle un mandataire Envoy attend les réponses d'un service donné. La temporisation garantit que les services n'attendent pas de réponse indéfiniment et que les appels réussissent ou échouent dans un délai prévisible. Pour plus d'informations sur les temporisations, voir ici.

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

  1. Initialisez l'acheminement de version d'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 de notation :
    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 de notation :
    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 des é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 chaque fois que vous actualisez la page.
    Capture d'écran de la page Web du produit du livre.
  5. Ajoutez une temporisation 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 avis 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 la temporisation est configurée à une demi-seconde, est qu'une nouvelle tentative codée en dur dans le service productpage. Le service appelle le service de révision expiré deux fois avant de revenir.

En plus de les remplacer dans les règles de routage, la temporisation peut également être remplacée sur une base par demande si l'application ajoute un en-tête x-envoy-upstream-rq-timeout-ms aux demandes sortantes.

Gestion de l'injection de faute

L'injection de défaut 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 d'erreur au niveau de la couche d'application, par exemple les codes d'erreur HTTP. Istio insère deux types d'erreur, tous deux configurés à l'aide d'un service virtuel. Pour plus d'informations sur l'injection d'erreur, voir ici.

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

Pour tester l'injection d'erreur, exécutez la commande suivante pour initialiser le routage de version d'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 un défaut de retard, procédez comme suit :

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

    Le service reviews:v2 a une temporisation de connexion codée en dur de 10 secondes pour les appels au service de notation. 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.
    Instantané de la page Bookinfo affichant les erreurs de délai

    La page d'accueil de Bookinfo se charge sans erreur en environ sept secondes. Toutefois, la section des évaluations affiche un message d'erreur : Désolé, les évaluations de produits ne sont pas disponibles pour ce dossier. Un bogue existe dans le code de l'application. La temporisation codée en dur entre 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 à reviews expire prématurément et génère une erreur après 6 secondes.

    Pour corriger le bogue, augmentez la temporisation du service productpage à reviews ou réduisez la temporisation de 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 les étoiles d'évaluation affichées.
    Instantané de la page Bookinfo sans erreurs dely

Injection d'une erreur d'abandon HTTP

Suivez ces étapes pour injecter une erreur d'abandon :

  1. Créez une règle d'injection de faute 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 de notation non disponible

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

    Creenshot de la page Bookinfo sans erreurs

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 de produit. La règle suivante définit le nombre maximal de connexions pour qu'elles ne soient pas supérieures à une et qu'elles aient 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 de produit. Fortio vous permet de contrôler le nombre de connexions, d'accès simultané et de délais pour les appels HTTP sortants. Si vous avez activé l'injection automatique de side-car, déployez le service fortio :
    kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml
    Vous pouvez également injecter manuellement le side-car 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 module de réseautage client et utilisez l'outil fortio pour appeler productpage et vérifier que le code de statut de la 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 produite :
    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 ont échoué et 4 ont échoué.
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://productpage:9080
    La commande produit une sortie similaire à la suivante.
    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 concurrentes à 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
    Les indicateurs de coupure de circuit 32 appellent en regardant 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 changements à la production avec le moins de risques possible. La mise en miroir envoie une copie du trafic réel à un service en miroir. Le trafic 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. Modifiez la règle de routage pour qu'elle reflète le trafic à 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 à 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 Host/Authority ajoutés à -shadow. Par exemple, les critiques deviennent des demandes reviews-shadow.Mirrored considérées comme "feu et oublier". Les réponses en miroir sont abandonné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 de notation.
    Capture d'écran du service reviews:v1
  5. Journaux du service en miroir reviews:v2. Note pour le service v2, l'en-tête est ajouté à -shadow.
    Capture d'écran du service reviews:v2 avec -shadow

Gestion des passerelles

La passerelle décrit un équilibreur de charge fonctionnant en périphérie du maillage recevant les connexions HTTP/TCP entrantes ou sortantes. Les configurations de passerelle sont appliquées aux mandataires Envoy autonomes qui s'exécutent en périphérie du maillage, plutôt qu'aux mandataires Envoy sidecar s'exécutant en même temps que vos charges de travail de service. Istio fournit certains déploiements de mandataire 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.

Note

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

Configuration du trafic entrant à l'aide de la passerelle Istio

La passerelle entrante configure les ports et les protocoles exposés, mais contrairement aux ressources entrantes de Kubernetes, elle n'inclut aucune configuration d'acheminement du trafic. L'acheminement du trafic entrant est configuré à la place à l'aide de règles d'acheminement Istio. Pour plus d'informations sur le trafic entrant Istio, voir ici.

Note

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 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 routes 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, voir 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 produit le résultat suivant :

    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é exposée explicitement. Vous voyez une erreur HTTP 404.
    curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/any

    La commande produit le résultat suivant :

    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 votre passerelle entrante et votre service virtuel sont configurés pour gérer l'hôte. Par exemple, votre hôte est example.com et le nom est spécifié 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 du trafic entrant à l'aide de la ressource de trafic entrant Kubernetes

Le lecteur suppose que l'application Bookinfo est déployée dans le cluster. Pour déployer l'application Bookinfo, voir 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 cette 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ès aux services externes avec trafic sortant

Par défaut, tout le trafic sortant d'un pod activé par Istio est redirigé vers son mandataire sidecar et Istio configure le mandataire Envoy pour qu'il transmette les demandes de services inconnus. Istio configure le traitement side-car des services externes via un champ de configuration meshConfig.outboundTrafficPolicy.mode. Si cette option est réglée à :

  • ALLOW_ANY (par défaut) : Le mandataire Istio permet aux appels vers des services inconnus de passer.
  • REGISTRY_ONLY : Le mandataire Istio bloque tout hôte sans qu'un service HTTP ou une entrée de service ne soit défini dans le maillage.

Le lecteur suppose que l'application Bookinfo est déployée dans le cluster. Sinon, suivez les étapes pour déployer l'application Bookinfo.

Gestion du transfert d'Envoy vers des services externes

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

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

    Cette étape est requise uniquement si vous avez explicitement réglé l'option à REGISTRY_ONLY lors de l'installation.
  2. Pour confirmer le succès de 200 réponses, faites 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 produit le résultat suivant :
    HTTP/1.1 200 OK

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

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

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

  1. Remplacez l'option meshConfig.outboundTrafficPolicy.mode par REGISTRY_ONLY. Cette étape n'est requise que si vous n'avez pas explicitement réglé l'option à REGISTRY_ONLY lors de l'installation.
  2. Suivez uniquement l'étape 1 de la section " Transfert 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 des 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 produit le résultat suivant :

    HTTP/1.1 502 Bad Gateway
  4. Créez un fichier 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 mandataire de side-car Istio sont : X-Envoy-Decorator-Operation.
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
    La commande produit le résultat suivant :
    HTTP/1.1 200 OK

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

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

    La commande produit le résultat suivant :

    {
      "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 d'entrées de service.
  7. L'approche ajoute des fonctions de gestion du trafic de service externe telles que les temporisations et l'injection d'erreur. La demande suivante retourne 200 (OK) en environ cinq secondes.
    kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
    Utilisez kubectl pour définir une temporisation de 3 secondes pour 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, une temporisation apparaît au bout de 3 secondes. Bien que httpbin.org attendait cinq secondes, Istio a coupé 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

Accès direct aux services externes

Cette approche contourne le proxy sidecar Istio, donnant aux services un accès direct à n'importe quel serveur externe. Toutefois, cette configuration nécessite des connaissances et une configuration propres au fournisseur du cluster. Semblable à 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 vers les services externes. Suivez ces étapes pour fournir un accès direct à des services externes.

Sécuriser Istio

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

Configuration de l'authentification

Istio offre TLS mutuel comme solution complète pour l'authentification du transport, qui est activée sans modification du 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 assure le suivi des charges de travail du serveur migrées vers les mandataires Istio. Istio configure les mandataires clients pour envoyer automatiquement le trafic TLS mutuel à ces charges de travail. Istio envoie le trafic en texte brut aux charges de travail sans side-car.

Pour vérifier que des certificats sont envoyés, envoyez une demande à partir d'un pod sleep au 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 que le side-car soit activé.
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 vers le pod httpbin dans l'espace de noms existant est en texte brut, car la destination n'est pas activée pour les side-cars. 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 existant 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, réglez une politique d'authentification pair à l'échelle du maillage avec le mode TLS mutuel réglé à 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 d'un pod sleep dans l'espace de noms existant à httpbin dans l'espace de noms par défaut ne fonctionne plus lorsque le mode TLS mutuel est réglé à 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 de pair STRICT en supprimant la CR.
kubectl delete peerauthentication -n istio-system default

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

Configuration de l'autorisation

Istio vous permet de configurer des politiques d'autorisation pour vos applications.

Tout d'abord, configurez une politique allow-nothing simple qui rejette toutes les demandes pour la charge de travail, puis accorde plus d'accès à la charge de travail 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 politique deny-all fonctionne comme prévu.

Créez une politique pour accorder à tous les utilisateurs et à toutes les charges de travail l'accès à la page de 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 "Échantillon Bookinfo" s'affiche, mais le service productpage ne peut pas accéder à la page des détails et des évaluations.

Ajoutez les politiques suivantes pour accorder à la charge de travail productpage l'accès aux détails et révise les charges de travail, ainsi que l'accès à la charge de travail ratings.

Définir le visualiseur des 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 le visualiseur des évaluations

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

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

Pour rétablir les politiques 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é en utilisant un TLS simple ou mutuel. Pour signer les certificats pour 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 n'ont pas déjà été 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"