Resolução longa de DNS no Kubernetes

Este artigo aborda os problemas de DNS no Kubernetes que nossa equipe encontrou. Como se viu, Ă s vezes o problema estĂĄ muito mais profundo do que parece inicialmente.


Introdução


Sempre chega um momento em que as circunstĂąncias intervĂȘm no trabalho jĂĄ depurado, forçando-nos a mudar alguma coisa. Portanto, nossa pequena equipe foi forçada a migrar todos os aplicativos usados ​​para o Kubernetes. Havia muitas razĂ”es, objetivas e nĂŁo muito, mas a histĂłria, de fato, nĂŁo Ă© sobre isso.


Como ninguĂ©m usou o Kubernetes antes, o cluster foi recriado vĂĄrias vezes, e Ă© por isso que nĂŁo tivemos tempo de avaliar a qualidade dos aplicativos transferidos. E assim, apĂłs a quarta transferĂȘncia, quando todos os cones principais jĂĄ estiverem cheios, todos os contĂȘineres estiverem montados e todas as implantaçÔes gravadas, vocĂȘ poderĂĄ analisar o trabalho realizado e, finalmente, seguir para outras tarefas.


11 horas, o inĂ­cio do dia Ăștil. O sistema de monitoramento nĂŁo possui parte das mensagens de um dos aplicativos.


DiagnĂłstico


O aplicativo foi recentemente transferido para um cluster e consistia em um trabalhador simples que entrava no banco de dados a cada poucos minutos, verificava se havia alteraçÔes e, se houver, enviava uma mensagem para o barramento. Antes do inĂ­cio do teste e apĂłs sua conclusĂŁo, o aplicativo grava uma mensagem no log. Sem paralelismo, sem multitarefa, a Ășnica lareira com o Ășnico recipiente.


Após uma inspeção mais detalhada, ficou claro que os logs estão no console, mas no Elastic eles não estão mais lå.


: Elasticsearch- , Kubernetes, Kibana. Elastic Serilog.Sinks.Elasticsearch, - Nginx ( , Elasticsearch , ). Nginx , .


Serilog, , Serilog selflog . , Serilog:


Serilog.Debugging.SelfLog.Enable(msg =>
{
  Serilog.Log.Logger.Error($"Serilog self log: {msg}");
});

, , . Kibana.


> Caught exception while preforming bulk operation to Elasticsearch: Elasticsearch.Net.ElasticsearchClientException: Maximum timeout reached while retrying request. Call: Status code unknown from: POST /_bulk

Elasticsearch , Elasticsearch . , HttpClient . , , .


, , . . , API Kubernetes, 5-10 100-150 . HTTP . .


– , , HTTP .


, , bash-, google.com :


while true;
do curl -w "%{time_total}\n" -o /dev/null -s "https://google.com/";
sleep 1;
done

– 5 .


imagem


, :


apiVersion: v1
kind: ConfigMap
metadata:
  name: ubuntu-test-scripts
data:
  loop.sh: |-
    apt-get update;
    apt-get install -y curl;
    while true;
    do echo $(date)'\n';
    curl -w "@/etc/script/curl.txt" -o /dev/null -s "https://google.com/";
    sleep 1;
    done
  curl.txt: |-
    lookup:        %{time_namelookup}\n
    connect:       %{time_connect}\n
    appconnect:    %{time_appconnect}\n
    pretransfer:   %{time_pretransfer}\n
    redirect:      %{time_redirect}\n
    starttransfer: %{time_starttransfer}\n
    total:         %{time_total}\n
---
apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-test
  labels:
      app: ubuntu-test
spec:
  containers:
  - name: test
    image: ubuntu
    args: [/bin/sh, /etc/script/loop.sh]
    volumeMounts:
    - name: config
      mountPath: /etc/script
      readOnly: true
  volumes:
  - name: config
    configMap:
      defaultMode: 0755
      name: ubuntu-test-scripts

– google.com curl. , /dev/null, curl.


, , . – DNS ( – ). Kubernetes 1.14, , , .


, :


imagem


, – DNS-lookup, 99% – 5 . , .



.


, — 5 seconds dns resolve kubernetes.


, :



issue weave.


, :


  1. ( , – 2017 , , , ) .
  2. DNS lookup. , 10-15 .
  3. , DNS- VIP, DNAT.
  4. .

– race conditions conntraking Linux SNAT DNAT. Tobias Klausmann 2009 , Linux 5.0 , .


, Kubernetes DNS, race condition .


glibc ( Ubuntu, Debian . .), :


  1. glibc UDP (A AAAA). UDP connectionless , connect(2) , conntrack .
  2. DNS- Kubernetes VIP DNAT iptables.
  3. DNAT , netfilter :
    a. nf_conntrack_in: conntrack hash object .
    b. nf_nat_ipv4_fn: conntrack.
    c. nf_conntrack_confirm: , .
  4. UDP . , DNS-. , . - insert_failed, .


, workaround:


  1. DNS- nameserver. LocalDNS cache
  2. Weave tc(8) - AAAA DNS
  3. single-request-reopen resolv.conf

, .


Kubernetes 1.9, pod dnsConfig, resolv.conf.


pod, glibc A AAAA , race condition.


spec:
  dnsConfig:
    options:
    - name: single-request-reopen

, — glibc (, alpine, musl), resolv.conf .


PS No nosso caso, para automatizar esse processo, foi escrito o webhook mutante mais simples, que coloca automaticamente esta seção de configuração para todos os novos pods do cluster. Infelizmente, não posso fornecer o código.


All Articles