Esta página mostra como resolver problemas de conetividade no seu cluster do Google Kubernetes Engine (GKE).
Problemas de conetividade relacionados com a captura de pacotes de rede no GKE
Esta secção descreve como resolver problemas de conetividade relacionados com a captura de pacotes de rede, incluindo sintomas como tempos limite de ligação, erros de ligação recusada ou comportamento inesperado da aplicação. Estes problemas de conetividade podem ocorrer ao nível do nó ou ao nível do pod.
Os problemas de conetividade na rede do cluster enquadram-se frequentemente nas seguintes categorias:
- Pods não acessíveis: um Pod pode não estar acessível a partir do interior ou exterior do cluster devido a configurações incorretas da rede.
- Interrupções do serviço: um serviço pode estar a sofrer interrupções ou atrasos.
- Problemas de comunicação entre pods: os pods podem não conseguir comunicar entre si de forma eficaz.
Os problemas de conetividade no cluster do GKE podem ter várias causas, incluindo as seguintes:
- Configurações incorretas da rede: políticas de rede, regras de firewall ou tabelas de encaminhamento incorretas.
- Erros da aplicação: erros no código da aplicação que afetam as interações de rede.
- Problemas de infraestrutura: congestão da rede, falhas de hardware ou limitações de recursos.
A secção seguinte mostra como resolver o problema nos nós ou nos pods problemáticos.
Identifique o nó no qual o pod problemático está a ser executado através do seguinte comando:
kubectl get pods POD_NAME -o=wide -n NAMESPACE
Substitua o seguinte:
POD_NAME
com o nome do agrupamento.NAMESPACE
com o espaço de nomes do Kubernetes.
Estabeleça ligação ao nó:
gcloud compute ssh NODE_NAME \ --zone=ZONE
Substitua o seguinte:
NODE_NAME
: nome do seu nó.ZONE
: nome da zona em que o nó é executado.
Para depurar um pod específico, identifique a interface
veth
associada ao pod:ip route | grep POD_IP
Substitua
POD_IP
pelo endereço IP do pod.Execute os comandos da caixa de ferramentas.
toolbox
comandos
toolbox
é um utilitário que fornece um ambiente em contentores nos seus nós do GKE para depuração e resolução de problemas. Esta secção descreve como instalar o utilitário toolbox
e usá-lo para resolver problemas do nó.
Com o nó ligado, inicie a ferramenta
toolbox
:toolbox
Esta ação transfere os ficheiros que facilitam a utilidade
toolbox
.Na linha de comandos de
toolbox
root, instale otcpdump
:Para clusters com endereços IP externos ou o Cloud NAT:
apt update -y && apt install -y tcpdump
Para clusters privados sem o Cloud NAT:
Se tiver um cluster privado sem o Cloud NAT, não pode instalar o
tcpdump
com oapt
. Em alternativa, transfira os ficheiroslibpcap
etcpdump
de lançamento do repositório oficial e copie os ficheiros para a VM através dogcloud compute scp
ou dogcloud storage cp
. Em seguida, instale as bibliotecas manualmente através dos seguintes passos:# Copy the downloaded packages to a staging area cp /media/root/home/USER_NAME/tcpdump-VERSION.tar.gz /usr/sbin/ cp /media/root/home/USER_NAME/libpcap-VERSION.tar.gz /usr/sbin/ cd /usr/sbin/ # Extract the archives tar -xvzf tcpdump-VERSION.tar.gz tar -xvzf libpcap-VERSION.tar.gz # Build and install libpcap (a dependency for tcpdump) cd libpcap-VERSION ./configure ; make ; make install # Build and install tcpdump cd ../tcpdump-VERSION ./configure ; make ; make install # Verify tcpdump installation tcpdump --version
Substitua o seguinte:
USER_NAME
: o seu nome de utilizador no sistema onde os ficheiros estão localizados.VERSION
: o número da versão específico dos pacotestcpdump
elibpcap
.
Inicie a captura de pacotes:
tcpdump -i eth0 -s 100 "port PORT" \ -w /media/root/mnt/stateful_partition/CAPTURE_FILE_NAME
Substitua o seguinte:
PORT
: nome do número de portabilidade.CAPTURE_FILE_NAME
: nome do ficheiro de captura.
Pare a captura de pacotes e interrompa o
tcpdump
.Saia da caixa de ferramentas escrevendo
exit
.Liste o ficheiro de captura de pacotes e verifique o respetivo tamanho:
ls -ltr /mnt/stateful_partition/CAPTURE_FILE_NAME
Copie a captura de pacotes do nó para o diretório de trabalho atual no seu computador:
gcloud compute scp NODE_NAME:/mnt/stateful_partition/CAPTURE_FILE_NAME \ --zone=ZONE
Substitua o seguinte:
NODE_NAME
: nome do seu nó.CAPTURE_FILE_NAME
: nome do ficheiro de captura.ZONE
: nome da sua zona.
Comandos alternativos
Também pode usar as seguintes formas para resolver problemas de conetividade nos Pods problemáticos:
Carga de trabalho de depuração efémera associada ao contentor do pod.
Execute uma shell diretamente no pod de destino com
kubectl exec
e, em seguida, instale e inicie o comandotcpdump
.
Problemas de conetividade de rede do pod
Conforme mencionado na discussão sobre a vista geral da rede, é importante compreender como os pods estão ligados dos respetivos espaços de nomes de rede ao espaço de nomes raiz no nó para resolver problemas de forma eficaz. Para a discussão seguinte, salvo indicação em contrário, partimos do princípio de que o cluster usa o CNI nativo do GKE em vez do CNI do Calico. Ou seja, não foi aplicada nenhuma política de rede.
Os pods em determinados nós não têm disponibilidade
Se os pods em determinados nós não tiverem conetividade de rede, certifique-se de que a ponte Linux está ativa:
ip address show cbr0
Se a ponte Linux estiver inativa, ative-a:
sudo ip link set cbr0 up
Certifique-se de que o nó está a aprender os endereços MAC dos pods anexados a cbr0:
arp -an
Os pods em determinados nós têm conetividade mínima
Se os pods em determinados nós tiverem uma conetividade mínima, deve confirmar primeiro se existem pacotes perdidos executando tcpdump
no contentor da caixa de ferramentas:
sudo toolbox bash
Instale a app tcpdump
na caixa de ferramentas, se ainda não o tiver feito:
apt install -y tcpdump
Executar tcpdump
contra cbr0:
tcpdump -ni cbr0 host HOSTNAME and port PORT_NUMBER and [TCP|UDP|ICMP]
Se parecer que os pacotes grandes estão a ser ignorados a jusante da ponte (por exemplo, a negociação TCP é concluída, mas não são recebidos SSL hellos), certifique-se de que a MTU para cada interface do pod Linux está corretamente definida para a MTU da rede da VPC do cluster.
ip address show cbr0
Quando são usadas sobreposições (por exemplo, Weave ou Flannel), esta MTU tem de ser ainda mais reduzida para acomodar a sobrecarga de encapsulamento na sobreposição.
MTU do GKE
A MTU selecionada para uma interface de pod depende da interface de rede do contentor (CNI) usada pelos nós do cluster e da definição de MTU da VPC subjacente. Para mais informações, consulte o artigo Pods.
O valor MTU da interface do pod é 1460
ou herdado da interface principal do nó.
CNI | MTU | GKE Standard |
---|---|---|
kubenet | 1460 | Predefinição |
kubenet (GKE versão 1.26.1 e posterior) |
Herdado | Predefinição |
Calico | 1460 |
Ativada através da utilização da funcionalidade Para ver detalhes, consulte o artigo Controle a comunicação entre Pods e serviços através de políticas de rede. |
netd | Herdado | Ativada através de qualquer uma das seguintes opções: |
GKE Dataplane V2 | Herdado |
Ativada através da utilização da funcionalidade Para obter detalhes, consulte o artigo Usar o GKE Dataplane V2. |
Falhas de ligação intermitentes
As ligações de e para os pods são encaminhadas por iptables. Os fluxos são monitorizados como entradas na tabela conntrack e, quando existem muitas cargas de trabalho por nó, o esgotamento da tabela conntrack pode manifestar-se como uma falha. Estes podem ser registados na consola série do nó, por exemplo:
nf_conntrack: table full, dropping packet
Se conseguir determinar que os problemas intermitentes são causados pelo esgotamento do conntrack, pode aumentar o tamanho do cluster (reduzindo assim o número de cargas de trabalho e fluxos por nó) ou aumentar nf_conntrack_max
:
new_ct_max=$(awk '$1 == "MemTotal:" { printf "%d\n", $2/32; exit; }' /proc/meminfo)
sysctl -w net.netfilter.nf_conntrack_max="${new_ct_max:?}" \
&& echo "net.netfilter.nf_conntrack_max=${new_ct_max:?}" >> /etc/sysctl.conf
Também pode usar o NodeLocal DNSCache para reduzir as entradas de acompanhamento de ligações.
"bind: Address already in use " comunicado para um contentor
Não é possível iniciar um contentor num pod porque, de acordo com os registos do contentor, a porta à qual a aplicação está a tentar associar-se já está reservada. O contentor está num ciclo de falhas. Por exemplo, no Cloud Logging:
resource.type="container"
textPayload:"bind: Address already in use"
resource.labels.container_name="redis"
2018-10-16 07:06:47.000 CEST 16 Oct 05:06:47.533 # Creating Server TCP listening socket *:60250: bind: Address already in use
2018-10-16 07:07:35.000 CEST 16 Oct 05:07:35.753 # Creating Server TCP listening socket *:60250: bind: Address already in use
Quando o Docker falha, por vezes, um contentor em execução fica para trás e fica obsoleto. O processo continua a ser executado no espaço de nomes de rede atribuído ao pod e a detetar na respetiva porta. Uma vez que o Docker e o kubelet não têm informações sobre o contentor obsoleto, tentam iniciar um novo contentor com um novo processo, que não consegue estabelecer ligação na porta, uma vez que é adicionado ao espaço de nomes de rede já associado ao Pod.
Para diagnosticar este problema:
Precisa do UUID do Pod no campo
.metadata.uuid
:kubectl get pod -o custom-columns="name:.metadata.name,UUID:.metadata.uid" ubuntu-6948dd5657-4gsgg name UUID ubuntu-6948dd5657-4gsgg db9ed086-edba-11e8-bdd6-42010a800164
Obtenha o resultado dos seguintes comandos a partir do nó:
docker ps -a ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep [Pod UUID]
Verifique os processos em execução a partir deste pod. Uma vez que o UUID dos espaços de nomes cgroup contém o UUID do pod, pode usar o comando grep para o UUID do pod no resultado de
ps
. Procure também a linha anterior para ter osdocker-containerd-shim
processos com o ID do contentor no argumento também. Corte o resto da coluna cgroup para obter um resultado mais simples:# ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep -B 1 db9ed086-edba-11e8-bdd6-42010a800164 | sed s/'blkio:.*'/''/ 1283089 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim 276e173b0846e24b704d4 12: 1283107 1283089 Ss sys_pause 4026532393 pause /pause 12: 1283150 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim ab4c7762f5abf40951770 12: 1283169 1283150 Ss do_wait 4026532393 sh /bin/sh -c echo hello && sleep 6000000 12: 1283185 1283169 S hrtimer_nanosleep 4026532393 sleep sleep 6000000 12: 1283244 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim 44e76e50e5ef4156fd5d3 12: 1283263 1283244 Ss sigsuspend 4026532393 nginx nginx: master process nginx -g daemon off; 12: 1283282 1283263 S ep_poll 4026532393 nginx nginx: worker process
Nesta lista, pode ver os IDs dos contentores, que também devem estar visíveis em
docker ps
.Neste caso:
docker-containerd-shim 276e173b0846e24b704d4
para pausardocker-containerd-shim ab4c7762f5abf40951770
para sh com sono (sleep-ctr)docker-containerd-shim 44e76e50e5ef4156fd5d3
para nginx (echoserver-ctr)
Verifique os seguintes elementos no resultado
docker ps
:# docker ps --no-trunc | egrep '276e173b0846e24b704d4|ab4c7762f5abf40951770|44e76e50e5ef4156fd5d3' 44e76e50e5ef4156fd5d383744fa6a5f14460582d0b16855177cbed89a3cbd1f gcr.io/google_containers/echoserver@sha256:3e7b182372b398d97b747bbe6cb7595e5ffaaae9a62506c725656966d36643cc "nginx -g 'daemon off;'" 14 hours ago Up 14 hours k8s_echoserver-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0 ab4c7762f5abf40951770d3e247fa2559a2d1f8c8834e5412bdcec7df37f8475 ubuntu@sha256:acd85db6e4b18aafa7fcde5480872909bd8e6d5fbd4e5e790ecc09acc06a8b78 "/bin/sh -c 'echo hello && sleep 6000000'" 14 hours ago Up 14 hours k8s_sleep-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0 276e173b0846e24b704d41cf4fbb950bfa5d0f59c304827349f4cf5091be3327 registry.k8s.io/pause-amd64:3.1
Em casos normais, vê todos os IDs de contentores de
ps
apresentados emdocker ps
. Se não vir nenhum, significa que é um contentor obsoleto e, provavelmente, verá um processo secundário dodocker-containerd-shim process
a ouvir na porta TCP que está a comunicar que já está em utilização.Para validar esta situação, execute
netstat
no espaço de nomes de rede do contentor. Obtenha o pid de qualquer processo de contentor (por isso, NÃOdocker-containerd-shim
) para o pod.Do exemplo anterior:
- 1283107 - pause
- 1283169 - sh
- 1283185 - sleep
- 1283263 – nginx master
- 1283282 – nginx worker
# nsenter -t 1283107 --net netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast gke-zonal-110-default-pool-fe00befa-n2hx ~ # nsenter -t 1283169 --net netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast
Também pode executar
netstat
usandoip netns
, mas tem de associar o espaço de nomes da rede do processo manualmente, uma vez que o Docker não está a fazer a associação:# ln -s /proc/1283169/ns/net /var/run/netns/1283169 gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns list 1283169 (id: 2) gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns exec 1283169 netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast gke-zonal-110-default-pool-fe00befa-n2hx ~ # rm /var/run/netns/1283169
Mitigação:
A mitigação a curto prazo consiste em identificar processos desatualizados através do método descrito anteriormente e terminar os processos com o comando kill [PID]
.
A mitigação a longo prazo envolve identificar o motivo pelo qual o Docker está a falhar e corrigi-lo. Os motivos possíveis incluem:
- Processos zombie a acumular-se, o que faz com que os espaços de nomes PID se esgotem
- Erro no Docker
- Pressão de recursos / OOM
O que se segue?
Para obter informações gerais sobre o diagnóstico de problemas de DNS do Kubernetes, consulte o artigo Depurar a resolução de DNS.
Se não conseguir encontrar uma solução para o seu problema na documentação, consulte a secção Obtenha apoio técnico para receber mais ajuda, incluindo aconselhamento sobre os seguintes tópicos:
- Abrindo um registo de apoio ao cliente através do contacto com o Cloud Customer Care.
- Receber apoio técnico da comunidade fazendo perguntas no StackOverflow e usando a etiqueta
google-kubernetes-engine
para pesquisar problemas semelhantes. Também pode juntar-se ao#kubernetes-engine
canal do Slack para receber mais apoio técnico da comunidade. - Abrir erros ou pedidos de funcionalidades através do rastreador de problemas público.