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 ECONNREFUSED
Pesquise 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_name
emresource.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-g7fvb
Tome 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
Envoy
nã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
Envoy
está 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.