Risoluzione dei problemi di avvio del workload in Cloud Service Mesh
Questo documento spiega i problemi comuni di Cloud Service Mesh e come risolverli. Se hai bisogno di ulteriore assistenza, consulta la sezione Richiesta di assistenza.
Il gateway non viene avviato con il proxy distroless quando viene esposta una porta con privilegi
Per impostazione predefinita, il proxy distroless viene avviato con autorizzazioni non root, il che in alcuni casi potrebbe causare errori di binding sulle porte con privilegi. Se durante l'avvio del proxy vengono visualizzati errori simili ai seguenti, è necessario applicare un securityContext aggiuntivo per un deployment del gateway.
Error adding/updating listener(s) 0.0.0.0_80: cannot bind '0.0.0.0:80': Permission denied
L'esempio seguente mostra il file YAML per un deployment del gateway in uscita:
apiVersion: apps/v1
kind: Deployment
metadata:
name: istio-egressgateway
spec:
selector:
matchLabels:
app: istio-egressgateway
istio: egressgateway
template:
metadata:
annotations:
# This is required to tell Anthos Service Mesh to inject the gateway with the
# required configuration.
inject.istio.io/templates: gateway
labels:
app: istio-egressgateway
istio: egressgateway
spec:
containers:
- name: istio-proxy
image: auto # The image will automatically update each time the pod starts.
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
# Allow binding to all ports (such as 80 and 443)
securityContext:
sysctls:
- name: net.ipv4.ip_unprivileged_port_start
value: "0"
serviceAccountName: istio-egressgateway
Connessione rifiutata quando si raggiunge un endpoint Cloud Service Mesh
Potresti riscontrare in modo intermittente errori di connessione rifiutata (ECONNREFUSED) con la comunicazione dai cluster agli endpoint, ad esempio Memorystore Redis, Cloud SQL o qualsiasi servizio esterno che il workload dell'applicazione deve raggiungere.
Questo può verificarsi quando il workload dell'applicazione viene avviato più rapidamente del container istio-proxy (Envoy) e tenta di raggiungere un endpoint esterno. Poiché a questo punto istio-init (initContainer) è già stato eseguito, sono presenti regole iptables che reindirizzano tutto il traffico in uscita a 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 seguenti passaggi descrivono come verificare se si tratta dell'errore che stai riscontrando:
Controlla i log di Stackdriver con il seguente filtro per identificare i pod che hanno riscontrato il problema.
L'esempio seguente mostra 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 ECONNREFUSEDCerca un'occorrenza del problema. Se utilizzi Stackdriver legacy, usa
resource.type="container".resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"Espandi l'ultima occorrenza per ottenere il nome del pod e poi prendi nota di
pod_nameinresource.labels.Ottieni la prima occorrenza del problema per questo 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-g7fvbPrendi 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 di istio-proxy per confermare che gli errori si verificano quando
Envoynon è 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 ha tentato di connettersi a Redis non appena
2020-03-31T10:41:15.552128897Z, ma entro2020-03-31T10:41:58Zistio-proxy non riusciva ancora a eseguire 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 tentasse di connettersi all'endpoint esterno.
Se questo è il problema che stai riscontrando, continua con i seguenti passaggi per la risoluzione dei problemi.
Aggiungi un'annotazione alla 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 tentare di effettuare altre richieste a servizi esterni. Ad esempio, all'avvio dell'applicazione, avvia un loop che effettua richieste all'endpoint di controllo dello stato di istio-proxy e continua solo dopo aver ottenuto un codice 200. L'endpoint di controllo dello stato di istio-proxy è il seguente:http://localhost:15020/healthz/ready
Condizione di race durante l'iniezione di sidecar tra Vault e Cloud Service Mesh
Quando utilizzi vault per la gestione dei secret, a volte vault inietta il sidecar 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 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 race condition: sia Istio sia vault iniettano il sidecar e Istio deve essere l'ultimo a farlo. Il proxy istio non è in esecuzione durante i container di inizializzazione. Il container di inizializzazione 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. Per questo motivo, il container di inizializzazione deve essere l'ultimo, in modo che il proxy sia attivo e in esecuzione immediatamente dopo la configurazione delle regole iptables. Purtroppo, l'ordine non è deterministico, quindi se Istio viene iniettato per primo, si verifica un errore.
Per risolvere questo problema, 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 quindi blocca la comunicazione. Per farlo, devi aggiungere una nuova annotazione denominata 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 in-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 workload.
Identificare il tipo di immagine proxy utilizzato nel cluster
Per identificare il tipo di immagine proxy (default o distroless) utilizzato da un pod specifico, puoi esaminare la specifica del pod.
Esegui il seguente comando per controllare l'immagine utilizzata dal container istio-proxy:
kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.spec.containers[?(@.name=="istio-proxy")].image}'
- Se il percorso dell'immagine non contiene
-distrolessnel tag o nel suffisso, utilizza l'immaginedefault. - Se il percorso dell'immagine contiene
-distrolessnel tag o nel suffisso, utilizza l'immaginedistroless.
Verificare l'intento di configurazione
Il tipo di immagine può essere configurato in due modi (l'annotazione ha la precedenza su MeshConfig):
Annotazione del pod: controlla se il pod ha l'annotazione
sidecar.istio.io/proxyImageType.kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.metadata.annotations["sidecar.istio.io/proxyImageType"]}'MeshConfig: controlla l'
defaultConfig.image.imageTypeimpostazione nelistio-RELEASE_CHANNELConfigMap nello spazio dei nomiistio-system.
Nota: per i cluster con il control plane gestito TRAFFIC_DIRECTOR:
- Per i cluster di cui è stato eseguito il provisioning direttamente con un control plane
TRAFFIC_DIRECTORgestito, sono supportate solo le immaginidistroless. Le sostituzioni di altri tipi di immagini vengono ignorate. - Per i cluster migrati al control plane
TRAFFIC_DIRECTOR(ad esempio quelli migrati da CSM-ISTIOD), il tipo di immagine predefinito è l'immaginedefault, ma puoi attivaredistrolessutilizzandoMeshConfigo l'annotazione del pod. Le sostituzioni di altri tipi di immagini (ad esempiodebug) non sono supportate.