Risoluzione dei problemi relativi al proxy in Cloud Service Mesh
Questo documento illustra i problemi comuni di Cloud Service Mesh e come risolverli. Se hai bisogno di ulteriore assistenza, consulta la pagina Ricevere assistenza.
Connessione rifiutata quando si raggiunge un endpoint con Istio
Potresti riscontrare a intermittenza errori di connessione rifiutata (ECONNREFUSED
) durante la comunicazione dai cluster agli endpoint, ad esempio Memorystore Redis, Cloud SQL o qualsiasi servizio esterno che il carico di lavoro dell'applicazione 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 iptables che reindirizzano tutto il traffico in uscita verso Envoy
. Poiché
istio-proxy non è ancora pronto, le regole iptables reindirizzano il traffico a un
proxy sidecar non ancora avviato, pertanto l'applicazione riceve
l'errore ECONNREFUSED
.
I passaggi seguenti spiegano come verificare se questo è l'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 precedente di Stackdriver, usa
resource.type="container"
.resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"
Espandi l'ultima occorrenza per ottenere il nome del pod, quindi annota
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 per questo pod.
Usa 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 si verificano quando
Envoy
non è pronto.Se gli errori si verificano mentre il container istio-proxy non è ancora pronto, è normale ottenere errori di connessione rifiutata. Nell'esempio precedente, il pod stava tentando di connettersi a Redis il giorno
2020-03-31T10:41:15.552128897Z
, ma tramite2020-03-31T10:41:58Z
istio-proxy non riusciva ancora a rilevare i probe di idoneità.Anche se il container istio-proxy è stato avviato per primo, è possibile che non sia pronto abbastanza velocemente prima che l'app stesse già tentando di connettersi all'endpoint esterno.
Se questo è il problema che stai riscontrando, procedi con la procedura di risoluzione dei problemi riportata di seguito.
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 che
Envoy
sia pronto prima di tentare di effettuare altre richieste a 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 il numero 200. L'endpoint di integrità istio-proxy è il seguente:http://localhost:15020/healthz/ready
Condizione di gara durante l'iniezione di 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 rimangono bloccati nello stato Init dopo il riavvio di un deployment o il deployment di un nuovo. 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, in quanto Istio e vault
inseriscono il file collaterale e Istio devono essere l'ultimo a eseguire questa operazione, il proxy istio
non è in esecuzione durante i container init. Il container di inizializzazione istio
configura le regole iptables per
reindirizzare tutto il traffico al proxy. Poiché non è ancora in esecuzione, queste regole
reindirizzeranno a nulla, bloccando tutto il traffico. Questo è il motivo per cui il container init deve essere l'ultimo, quindi il proxy è attivo e in esecuzione subito dopo la configurazione delle regole iptables. Purtroppo l'ordine non è deterministico, quindi se viene inserito
prima l'inserimento di Istio, si rompe.
Per risolvere questa condizione, consenti l'indirizzo IP di vault
in modo che il traffico diretto all'IP di Vault non venga reindirizzato al proxy Envoy che non è ancora pronto e che quindi blocca la comunicazione. A questo scopo, deve essere aggiunta una nuova annotazione
denominata excludeOutboundIPRanges
.
Per Cloud Service Mesh gestito, ciò è 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 Cloud 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.