Risoluzione dei problemi del proxy in Anthos Service Mesh
Questo documento illustra i problemi comuni di Anthos Service Mesh e come risolverli. Se hai bisogno di ulteriore assistenza, consulta Assistenza.
Connessione rifiutata quando si raggiunge un endpoint con Istio
A intermittenza, potresti riscontrare errori di connessione rifiutata (ECONNREFUSED
)
nella comunicazione dai cluster ai tuoi endpoint, ad esempio Memorystore
Redis, Cloud SQL o qualsiasi servizio esterno che il tuo 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 istio-init (initContainer
) è già stato eseguito, sono presenti regole itables che reindirizzano tutto il traffico in uscita a Envoy
. Dal momento che
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 Google Cloud Observability con il filtro seguente per identificare quali pod hanno riscontrato il problema.
Nell'esempio seguente è riportato un messaggio di errore tipico:
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
Controlla i log di Google Cloud Observability con il filtro seguente per verificare che il container Istio-proxy (
Envoy
) non sia pronto.resource.labels.pod_name="$POD_FROM_STEP_1$" resource.type="k8s_container" resource.labels.container_name="istio-proxy" textPayload:"Envoy proxy is NOT ready"
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 quel pod:
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 mentre il container istio-proxy non è ancora pronto, è normale che vengano visualizzati 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 da parte di2020-03-31T10:41:58Z
continuava a non riuscire a risolvere i probe di idoneità.Anche se il container istio-proxy è stato avviato prima, è possibile che non sia stato pronto abbastanza velocemente prima che l'app stesse già tentando di connettersi all'endpoint esterno.
In questo caso, continua a svolgere la procedura per la risoluzione dei problemi che segue.
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'inserimento di sidecar tra vault e istio
Quando utilizzi vault
per la gestione dei secret, a volte vault
inserisce un file collaterale prima di istio
, causando il blocco dei pod nello stato Init
. In questo caso,
i pod creati rimangono bloccati nello stato Init dopo il riavvio di un deployment o il 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 sia vault
iniettano il file collaterale e Istio devono essere l'ultimo a farlo. Il proxy istio
non è in esecuzione durante i container di inizializzazione. Il container init istio
configura le regole iptables per reindirizzare tutto il traffico al proxy. Poiché non è ancora in esecuzione, queste regole non reindirizzano a nulla, 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 l'impostazione delle regole iptables. Sfortunatamente, l'ordine non è deterministico, quindi se Istio viene inserito prima, non funziona.
Per risolvere questo problema, consenti l'indirizzo IP di vault
in modo che il traffico verso l'IP di Vault non venga reindirizzato al proxy Envoy che non è ancora pronto e blocca quindi la comunicazione. A questo scopo, è necessario aggiungere una nuova
annotazione denominata excludeOutboundIPRanges
.
Per Anthos Service Mesh gestito, ciò è possibile solo a livello di deployment o di 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.