Como resolver problemas de inicialização de cargas de trabalho no Cloud Service Mesh
Neste documento, explicamos problemas comuns do Cloud Service Mesh e como resolvê-los para resolvê-los com rapidez. Se você precisar de mais ajuda, consulte Como receber suporte.
Conexão recusada ao alcançar um endpoint do Cloud Service Mesh
Podem ocorrer, de modo intermitente, erros de conexão recusada (ECONNREFUSED
)
na comunicação dos clusters com os endpoints, como Memorystore Redis, Cloud SQL ou qualquer serviço externo que a carga de trabalho do aplicativo precise alcançar.
Isso pode ocorrer quando a carga de trabalho do aplicativo é iniciada mais rapidamente que o
contêiner istio-proxy (Envoy
) e tenta alcançar um endpoint externo. Como
o istio-init (initContainer
) já foi executado
nesta etapa, por isso, há
regras em vigor que redirecionam todo o tráfego de saída para Envoy
. Como
o istio-proxy ainda não está pronto, as regras do iptables redirecionam o tráfego para um
proxy secundário que ainda não foi iniciado e, portanto, o aplicativo recebe o
erro ECONNREFUSED
.
As etapas a seguir detalham como verificar se esse é o erro que você está enfrentando:
Verifique os registros do Stackdriver com o seguinte filtro para identificar quais pods tiveram o problema.
O exemplo a seguir mostra uma mensagem de erro típica:
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
Pesquise uma ocorrência do problema. Se você estiver usando o Stackdriver legado, use
resource.type="container"
.resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"
Expanda a ocorrência mais recente para ver o nome do pod e anote
pod_name
emresource.labels
.Encontre a primeira ocorrência do problema para esse pod:
resource.type="k8s_container" resource.labels.pod_name="$POD_NAME$"
Exemplo de saída:
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
Anote o carimbo de data/hora do primeiro erro desse pod.
Use o filtro a seguir para ver os eventos de inicialização do pod.
resource.type="k8s_container" resource.labels.pod_name="$POD_NAME$"
Exemplo de saída:
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}
Use os carimbos de data/hora dos erros e eventos de inicialização do istio-proxy para confirmar se os erros estão acontecendo quando o
Envoy
não está pronto.Se os erros ocorrem enquanto o contêiner istio-proxy ainda não está pronto, é normal receber erros de conexão recusada. No exemplo anterior, o pod tentava se conectar ao Redis assim que
2020-03-31T10:41:15.552128897Z
, mas por2020-03-31T10:41:58Z
o istio-proxy ainda falhava nas sondagens de prontidão.Mesmo que o contêiner istio-proxy tenha sido iniciado primeiro, é possível que ele não tenha ficado pronto rápido o suficiente antes de o app já estar tentando se conectar ao endpoint externo.
Se esse for o problema que você está enfrentando, continue com as seguintes etapas de solução de problemas.
Anote a configuração no nível do pod. Isso está disponível apenas no nível do pod e não em nível global.
annotations: proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
Modifique o código do aplicativo para que ele verifique se o
Envoy
está pronto antes de tentar fazer outras solicitações para serviços externos. Por exemplo, na inicialização do aplicativo, inicie um loop que faça solicitações para o endpoint de integridade do istio-proxy e só continue depois que um número 200 for recebido. O endpoint de integridade do istio-proxy é este:http://localhost:15020/healthz/ready
Disputa durante a injeção de sidecar entre o Vault e o Cloud Service Mesh
Ao usar vault
para gerenciamento de secrets, às vezes vault
injeta o arquivo secundário antes de istio
, fazendo com que os pods fiquem travados no status Init
. Quando isso acontece, os pods criados ficam travados no status Init depois de reiniciar qualquer implantação ou implantar uma nova. Exemplo:
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
Esse problema é causado por uma disputa. Tanto o Istio quanto vault
injetam o
arquivo secundário, e o Istio precisa ser o último a fazer isso. O proxy istio
não está em execução
durante os contêineres init. O contêiner init istio
configura as regras do AndroidManifest para redirecionar todo o tráfego para o proxy. Como ela ainda não está em execução, essas regras
redirecionam para nada, bloqueando todo o tráfego. É por isso que o contêiner init precisa
ser o último, para que o proxy entre em execução imediatamente após as regras do Dockerfile serem
configuradas. Infelizmente, a ordem não é determinista. Portanto, se o Istio for injetado
primeiro, ele falhará.
Para resolver essa condição, permita o endereço IP de vault
para que o tráfego
que vai para o IP do Vault não seja redirecionado para o proxy Envoy, que ainda não está pronto
e, portanto, bloqueando a comunicação. Para isso, uma nova anotação
chamada excludeOutboundIPRanges
precisa ser adicionada.
No Cloud Service Mesh gerenciado, isso só é possível na implantação ou no pod
nível em spec.template.metadata.annotations
, por exemplo:
apiVersion: apps/v1
kind: Deployment
...
...
...
spec:
template:
metadata:
annotations:
traffic.sidecar.istio.io/excludeOutboundIPRanges:
Para o Cloud Service Mesh no cluster, há uma opção para defini-lo como global
com um IstioOperator em spec.values.global.proxy.excludeIPRanges
. Por
exemplo:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
values:
global:
proxy:
excludeIPRanges: ""
Depois de adicionar a anotação, reinicie suas cargas de trabalho.