Resolver problemas de arranque de cargas de trabalho no Cloud Service Mesh
Este documento explica os problemas comuns do Cloud Service Mesh e como os resolver. Se precisar de assistência adicional, consulte a secção Receber apoio técnico.
O gateway não é iniciado com o proxy sem distribuição quando é exposta uma porta privilegiada
Por predefinição, o proxy distroless é iniciado com autorizações não de raiz, o que, em alguns casos, pode causar falhas de associação em portas privilegiadas. Se vir erros semelhantes aos seguintes durante o arranque do proxy, tem de aplicar um securityContext adicional para uma implementação de gateway.
Error adding/updating listener(s) 0.0.0.0_80: cannot bind '0.0.0.0:80': Permission denied
O exemplo seguinte é o YAML para uma implementação de gateway de saída:
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
Ligação recusada ao aceder a um ponto final do Cloud Service Mesh
Pode ter intermitentemente erros de ligação recusada (ECONNREFUSED) com a comunicação dos seus clusters para os seus pontos finais, por exemplo, o Memorystore Redis, o Cloud SQL ou qualquer serviço externo que a carga de trabalho da sua aplicação precise de alcançar.
Isto pode ocorrer quando a carga de trabalho da aplicação é iniciada mais rapidamente do que o contentor istio-proxy (Envoy) e tenta alcançar um ponto final externo. Uma vez que, nesta fase, o istio-init (initContainer) já foi executado, existem regras de iptables que redirecionam todo o tráfego de saída para Envoy. Uma vez que o istio-proxy ainda não está pronto, as regras de iptables vão redirecionar o tráfego para um proxy sidecar que ainda não foi iniciado e, por isso, a aplicação recebe o erro ECONNREFUSED.
Os passos seguintes detalham como verificar se este é o erro que está a ter:
Verifique os registos do Stackdriver com o seguinte filtro para identificar os pods que tiveram o problema.
O exemplo seguinte 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 ECONNREFUSEDPesquise uma ocorrência do problema. Se estiver a usar o Stackdriver antigo, use
resource.type="container".resource.type="k8s_container" textPayload:"$ERROR_MESSAGE$"Expanda a ocorrência mais recente para obter o nome do pod e, em seguida, tome nota do
pod_nameemresource.labels.Obtenha a primeira ocorrência do problema para esse agrupamento:
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-g7fvbTome nota da data/hora do primeiro erro deste pod.
Use o seguinte filtro para ver os eventos de arranque 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 as datas/horas dos erros e dos eventos de arranque do istio-proxy para confirmar que os erros ocorrem quando o
Envoynão está pronto.Se os erros ocorrerem enquanto o contentor istio-proxy ainda não estiver pronto, é normal receber erros de ligação recusada. No exemplo anterior, o pod estava a tentar estabelecer ligação ao Redis assim que
2020-03-31T10:41:15.552128897Z, mas, por2020-03-31T10:41:58Z, o istio-proxy ainda estava a falhar as sondagens de prontidão.Embora o contentor istio-proxy tenha sido iniciado primeiro, é possível que não tenha ficado pronto com a rapidez suficiente antes de a app já estar a tentar ligar-se ao ponto final externo.
Se este for o problema que está a ter, continue com os seguintes passos de resolução de problemas.
Anotar a configuração ao nível do pod. Esta opção só está disponível ao nível do grupo de anúncios e não ao nível global.
annotations: proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'Modifique o código da aplicação para que verifique se
Envoyestá pronto antes de tentar fazer outros pedidos a serviços externos. Por exemplo, no início da aplicação, inicie um ciclo que faça pedidos ao ponto final de verificação do estado de funcionamento do istio-proxy e só continue quando for obtido um 200. O ponto final de verificação do estado de funcionamento do istio-proxy é o seguinte:http://localhost:15020/healthz/ready
Condição de corrida durante a injeção de sidecar entre o Vault e o Cloud Service Mesh
Quando usa o vault para a gestão de segredos, por vezes, o vault injeta o sidecar antes do istio, o que faz com que os pods fiquem bloqueados no estado Init. Quando isto acontece, os pods criados ficam bloqueados no estado Init depois de reiniciar qualquer implementação ou implementar uma nova. Por 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
Este problema é causado por uma condição de corrida. Tanto o Istio como o vault injetam o sidecar, e o Istio tem de ser o último a fazê-lo. O proxy istio não está em execução durante os contentores de inicialização. O contentor istio init configura regras de iptables para
redirecionar todo o tráfego para o proxy. Uma vez que ainda não está em execução, essas regras
não redirecionam para nada, bloqueando todo o tráfego. É por isso que o contentor init tem de ser o último, para que o proxy esteja em funcionamento imediatamente após a configuração das regras iptables. Infelizmente, a ordem não é determinística, por isso, se o Istio for injetado primeiro, ocorre uma falha.
Para resolver este problema, permita o endereço IP de vault para que o tráfego
destinado ao IP do Vault não seja redirecionado para o proxy Envoy, que ainda não está pronto
e, por isso, está a bloquear a comunicação. Para o conseguir, deve adicionar uma nova anotação com o nome excludeOutboundIPRanges.
Para a malha de serviços do Google Cloud gerida, isto só é possível ao nível da implementação ou do pod 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, existe uma opção para o definir 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 as cargas de trabalho.