Résoudre les problèmes de proxy dans Cloud Service Mesh

Ce document décrit les problèmes courants liés à Cloud Service Mesh et explique comment les résoudre. Si vous avez besoin d'une aide supplémentaire, consultez la page Obtenir de l'aide.

Connexion refusée lors de l'accès à un point de terminaison avec Istio

Des erreurs de connexion refusée (ECONNREFUSED) peuvent se produire par intermittence. avec les communications de vos clusters vers vos points de terminaison, par exemple Memorystore Redis, Cloud SQL ou tout service externe dont la charge de travail de l'application a besoin de votre audience.

Cela peut se produire lorsque la charge de travail de votre application démarre plus rapidement que istio-proxy (Envoy) et tente d'atteindre un point de terminaison externe. En effet, À ce stade, istio-init (initContainer) a déjà été exécuté, règles iptables mises en place pour rediriger tout le trafic sortant vers Envoy. Depuis istio-proxy n'est pas encore prêt, les règles iptables redirigent le trafic un proxy side-car qui n'a pas encore démarré. Par conséquent, l'application obtient ECONNREFUSED erreur.

Les étapes suivantes expliquent comment vérifier s'il s'agit de l'erreur que vous rencontrez rencontre:

  1. Vérifiez les journaux Stackdriver à l'aide du filtre suivant pour identifier les pods a rencontré ce problème.

    Voici un exemple de message d'erreur typique:

    Error: failed to create connection to feature-store redis, err=dial tcp   192.168.9.16:19209: connect: connection refused
    [ioredis] Unhandled error event: Error: connect ECONNREFUSED
    
  2. Recherchez une occurrence du problème. Si vous utilisez l'ancien Stackdriver, puis utilisez resource.type="container".

    resource.type="k8s_container"
    textPayload:"$ERROR_MESSAGE$"
    
  3. Développez la dernière occurrence pour obtenir le nom du pod, puis notez de pod_name sous resource.labels.

  4. Obtenez la première occurrence du problème pour ce pod:

    resource.type="k8s_container"
    resource.labels.pod_name="$POD_NAME$"
    

    Exemple de résultat :

    E 2020-03-31T10:41:15.552128897Z
    post-feature-service post-feature-service-v1-67d56cdd-g7fvb failed to create
    connection to feature-store redis, err=dial tcp 192.168.9.16:19209: connect:
    connection refused post-feature-service post-feature-service-v1-67d56cdd-g7fvb
    
  5. Notez le code temporel de la première erreur pour ce pod.

  6. Utilisez le filtre suivant pour afficher les événements de démarrage des pods.

    resource.type="k8s_container"
    resource.labels.pod_name="$POD_NAME$"
    

    Exemple de résultat :

    I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Container image "docker.io/istio/proxyv2:1.3.3" already present on machine  spec.containers{istio-proxy}
    I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Created container  spec.containers{istio-proxy}
    I 2020-03-31T10:41:15Z spec.containers{istio-proxy} Started container  spec.containers{istio-proxy}
    I 2020-03-31T10:41:15Z spec.containers{APP-CONTAINER-NAME} Created container  spec.containers{APP-CONTAINER-NAME}
    W 2020-03-31T10:41:17Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:26Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:28Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:31Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    W 2020-03-31T10:41:58Z spec.containers{istio-proxy} Readiness probe failed: HTTP probe failed with statuscode: 503  spec.containers{istio-proxy}
    
  7. Utilisez les codes temporels des erreurs et des événements de démarrage d'istio-proxy pour confirmer des erreurs se produisent lorsque Envoy n'est pas prêt.

    Si les erreurs se produisent alors que le conteneur istio-proxy n'est pas encore prêt, normal d'obtenir des erreurs de connexion refusée. Dans l'exemple précédent, le pod tentait de se connecter à Redis dès que 2020-03-31T10:41:15.552128897Z mais 2020-03-31T10:41:58Z. istio-proxy échouait toujours aux vérifications d'aptitude.

    Même si le conteneur istio-proxy a démarré en premier, il est possible qu'il ne s'est pas lancée assez rapidement lorsque l'application tentait déjà de se connecter au point de terminaison externe.

    S'il s'agit du problème que vous rencontrez, suivez les instructions de la en suivant les étapes de dépannage.

  8. Annotez la configuration au niveau du pod. Cette option n'est disponible que au niveau du pod. et non au niveau global.

    annotations:
    proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
    
  9. Modifiez le code de l'application pour qu'il vérifie si Envoy est prêt avant lui. tente d'envoyer toute autre requête à des services externes. Par exemple, sur démarrer l'application, initier une boucle qui envoie des requêtes au proxy et ne continue qu'une fois la valeur 200 obtenue. Le proxy istio-proxy le point de terminaison Health est le suivant:

    http://localhost:15020/healthz/ready
    

Condition de concurrence lors de l'injection side-car entre Vault et Istio

Lorsque vous utilisez vault pour gérer les secrets, vault injecte parfois un side-car. avant istio. Les pods restent donc bloqués à l'état Init. Dans ce cas, les pods créés restent bloqués à l'état "Init" après le redémarrage d'un déploiement en déployant un nouveau. Exemple :

E 2020-03-31T10:41:15.552128897Z
post-feature-service post-feature-service-v1-67d56cdd-g7fvb failed to create
connection to feature-store redis, err=dial tcp 192.168.9.16:19209: connect:
connection refused post-feature-service post-feature-service-v1-67d56cdd-g7fvb

Ce problème est causé par une condition de concurrence, Istio et vault injectent tous deux le side-car et Istio doivent être les derniers à effectuer cette opération, le proxy istio n'est pas en cours d'exécution. pendant les conteneurs init. Le conteneur init istio configure les règles iptables pour : rediriger tout le trafic vers le proxy. Comme elle n'est pas encore exécutée, ces règles rediriger vers rien, bloquant tout le trafic. C'est pourquoi le conteneur "init" être en dernier, de sorte que le proxy est opérationnel dès que les règles iptables sont configuration. Malheureusement, l'ordre n'est pas déterministe. Par conséquent, si Istio est injecté elle tombe en panne.

Pour résoudre ce problème, autorisez l'adresse IP de vault afin que le trafic qui accède à l'adresse IP Vault n'est pas redirigé vers le proxy Envoy, qui n'est pas prêt et donc bloquant la communication. Pour ce faire, une nouvelle annotation nommé excludeOutboundIPRanges doit être ajouté.

Pour Cloud Service Mesh géré, cela n'est possible qu'au niveau du déploiement ou du pod sous spec.template.metadata.annotations, par exemple:

apiVersion: apps/v1
kind: Deployment
...
...
...
spec:
  template:
    metadata:
      annotations:
        traffic.sidecar.istio.io/excludeOutboundIPRanges:

Vous pouvez définir le maillage de services Cloud Service intégré au cluster en tant que maillage global un opérateur IstioOperator sous spec.values.global.proxy.excludeIPRanges, par exemple:

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  values:
    global:
      proxy:
        excludeIPRanges: ""

Une fois l'annotation ajoutée, redémarrez vos charges de travail.