Risoluzione dei problemi del proxy in Anthos Service Mesh
Questo documento spiega i problemi comuni di Anthos Service Mesh e come risolverli. Se hai bisogno di ulteriore aiuto, consulta Ricevere assistenza.
Connessione rifiutata quando si raggiunge un endpoint con Istio
Potresti riscontrare a intermittenza errori di connessione rifiutata (ECONNREFUSED
) nella comunicazione dai cluster agli endpoint, ad esempio Memorystore Redis, Cloud SQL o qualsiasi servizio esterno che il carico di lavoro delle applicazioni deve raggiungere.
Questo può verificarsi quando il carico di lavoro dell'applicazione viene avviato più velocemente del container Istio-proxy (Envoy
) e tenta di raggiungere un endpoint esterno. Poiché in questa fase è già stato eseguito istio-init (initContainer
), sono presenti regole iptables che reindirizzano tutto il traffico in uscita a Envoy
. Poiché
istio-proxy non è ancora pronto, le regole iptables reindirizzano il traffico
a un proxy sidecar non ancora avviato e, di conseguenza, l'applicazione riceve l'errore
ECONNREFUSED
.
I passaggi seguenti spiegano come verificare se si tratta dell'errore che stai riscontrando:
Controlla i log di Stackdriver con il seguente filtro per identificare quali pod hanno riscontrato il problema.
L'esempio seguente mostra un tipico messaggio di errore:
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
Cerca un'occorrenza del problema. Se utilizzi la versione legacy di Stackdriver, utilizza
resource.type="container"
.resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"
Espandi l'ultima occorrenza per ottenere il nome del pod, quindi prendi nota di
pod_name
inresource.labels
.Ottieni la prima occorrenza del problema per il pod in questione:
resource.type="k8s_container" resource.labels.pod_name="$POD_NAME$"
Output di esempio:
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
Prendi nota del timestamp del primo errore di questo pod.
Utilizza il filtro seguente per visualizzare gli eventi di avvio dei pod.
resource.type="k8s_container" resource.labels.pod_name="$POD_NAME$"
Output di esempio:
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}
Utilizza i timestamp degli errori e degli eventi di avvio istio-proxy per confermare che gli errori si verificano quando
Envoy
non è pronto.Se gli errori si verificano quando il container istio-proxy non è ancora pronto, è normale ricevere errori di connessione rifiutata. Nell'esempio precedente, il pod stava cercando di connettersi a Redis non appena
2020-03-31T10:41:15.552128897Z
ma istio-proxy per2020-03-31T10:41:58Z
continuava a non superare i probe di idoneità.Anche se il container istio-proxy è stato avviato per primo, è possibile che non sia diventato pronto abbastanza rapidamente prima che l'app stesse già tentando di connettersi all'endpoint esterno.
Se questo è il tuo problema, continua con la seguente procedura di risoluzione dei problemi.
Annota la configurazione a livello di pod. Questa opzione è disponibile solo a livello di pod e non a livello globale.
annotations: proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
Modifica il codice dell'applicazione in modo che verifichi se
Envoy
è pronto prima di provare a effettuare altre richieste ai servizi esterni. Ad esempio, all'avvio dell'applicazione, avvia un loop che invia richieste all'endpoint di integrità istio-proxy e continua solo una volta ottenuto un valore 200. L'endpoint di integrità istio-proxy è il seguente:http://localhost:15020/healthz/ready
Condizione di gara durante l'iniezione del sidecar tra vault e istio
Quando utilizzi vault
per la gestione dei secret, a volte vault
inserisce il file collaterale prima di istio
, causando il blocco dei pod nello stato Init
. In questo caso, i pod creati si bloccano nello stato di inizializzazione dopo il riavvio di un deployment o l'esecuzione del deployment di un nuovo deployment. Ad esempio:
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
Questo problema è causato da una race condition, sia Istio che vault
inseriscono il file collaterale e Istio devono essere l'ultimo a farlo. Il proxy istio
non è in esecuzione durante i container di inizializzazione. Il contenitore di inizializzazione istio
configura le regole iptables per reindirizzare tutto il traffico al proxy. Poiché non è ancora in esecuzione, queste regole non reindirizzano a niente, bloccando tutto il traffico. Questo è il motivo per cui il container init deve essere l'ultimo, in modo che il proxy sia attivo e in esecuzione subito dopo la configurazione delle regole iptables. Sfortunatamente, l'ordine non è deterministico, quindi se Istio viene inserito prima, non funziona.
Per risolvere i problemi di questa condizione, consenti l'indirizzo IP di vault
in modo che il traffico verso l'IP Vault non venga reindirizzato al proxy Envoy che non è ancora pronto e, di conseguenza, blocca la comunicazione. A tal fine, deve essere aggiunta una nuova annotazione
denominata excludeOutboundIPRanges
.
Per Anthos Service Mesh gestito, questa operazione è possibile solo a livello di deployment o pod in spec.template.metadata.annotations
, ad esempio:
apiVersion: apps/v1
kind: Deployment
...
...
...
spec:
template:
metadata:
annotations:
traffic.sidecar.istio.io/excludeOutboundIPRanges:
Per Anthos Service Mesh nel cluster, esiste un'opzione per impostarlo come globale con
un IstioOperator in spec.values.global.proxy.excludeIPRanges
, ad esempio:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
proxy:
excludeIPRanges: ""
Dopo aver aggiunto l'annotazione, riavvia i carichi di lavoro.