Risoluzione dei problemi relativi al proxy in Cloud Service Mesh
Questo documento spiega i problemi comuni di Cloud Service Mesh e come risolverli. Se hai bisogno di ulteriore assistenza, consulta Ricevere assistenza.
Connessione rifiutata quando si raggiunge un endpoint con Istio
Potresti riscontrare a intermittenza errori di connessione rifiutata (ECONNREFUSED
)
con la comunicazione dai cluster agli endpoint, ad esempio Memorystore
Redis, Cloud SQL o qualsiasi servizio esterno necessario per il carico di lavoro dell'applicazione
senza ostacoli.
Questo può verificarsi quando il carico di lavoro dell'applicazione si avvia più velocemente del contenitore istio-proxy (Envoy
) e tenta di raggiungere un endpoint esterno. Poiché
in questa fase istio-init (initContainer
) è già stato eseguito, ci sono
Sono state applicate regole iptables che reindirizzano tutto il traffico in uscita verso Envoy
. Poiché Istio-Proxy non è ancora pronto, le regole iptables reindirizzeranno il traffico a un proxy sidecar non ancora avviato e, di conseguenza, l'applicazione riceverà l'errore ECONNREFUSED
.
I passaggi che seguono descrivono in dettaglio come verificare se si tratta dell'errore che stai riscontrando:
Controlla i log di Stackdriver con il seguente filtro per identificare i pod ha 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 Stackdriver legacy, utilizza
resource.type="container"
.resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"
Espandi l'ultima occorrenza per ottenere il nome del pod, poi prendi nota di
pod_name
inresource.labels
.Ottieni la prima occorrenza del problema per il 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.
Utilizza il seguente filtro per visualizzare gli eventi di avvio del 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 si verificano quando
Envoy
non è pronto.Se gli errori si verificano quando il contenitore istio-proxy non è ancora pronto, è normale ricevere errori di connessione rifiutata. Nell'esempio precedente, il pod stava tentando di connettersi a Redis non appena era
2020-03-31T10:41:15.552128897Z
, ma a2020-03-31T10:41:58Z
istio-proxy continuava a non superare i controlli di idoneità.Anche se il contenitore istio-proxy è stato avviato per primo, è possibile che non sia stato pronto abbastanza rapidamente prima che l'app tentasse già di connettersi all'endpoint esterno.
Se si tratta del problema che stai riscontrando, continua con i seguenti passaggi per la 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 controlli se
Envoy
è pronto prima di tentare di effettuare altre richieste a servizi esterni. Ad esempio, all'avvio dell'applicazione, avvia un ciclo che invia richieste all'endpoint di salute istio-proxy e continua solo dopo aver ottenuto un codice 200. L'endpoint istio-proxy health è 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 questi casi,
i pod creati rimangono bloccati nello stato di inizializzazione dopo aver riavviato un deployment o
ne aver eseguito uno 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 condizione di gara, sia Istio che vault
iniettano il sidecar e Istio deve essere l'ultimo a farlo, il proxy istio
non è in esecuzione durante i contenitori di inizializzazione. Il container di inizializzazione istio
configura le regole iptables per
reindirizzando tutto il traffico al proxy. Poiché non è ancora in esecuzione, queste regole
non reindirizzando a nulla, bloccando tutto il traffico. Per questo motivo, il contenitore init deve essere l'ultimo, in modo che il proxy sia attivo e funzionante immediatamente dopo la configurazione delle regole iptables. Purtroppo l'ordine non è deterministico, quindi se viene inserito Istio
prima si rompe.
Per risolvere questa condizione, consenti l'indirizzo IP di vault
in modo che il traffico
l'indirizzo all'IP Vault non viene reindirizzato al proxy Envoy che non è pronto
bloccare la comunicazione. Per farlo, è necessario aggiungere una nuova annotazione excludeOutboundIPRanges
.
Per Cloud 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 Cloud Service Mesh nel cluster, è possibile 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.