/etc/resolv.conf для Kubernetes pods, опция ndots:5, как это может негативно сказаться на производительности приложения

/etc/resolv.conf для Kubernetes pods, опция ndots:5, как это может негативно сказаться на производительности приложения

No hace mucho tiempo lanzamos Kubernetes 1.9 en AWS utilizando Kops. Ayer, durante el rollout suave de nuevo tráfico en uno de nuestros clústeres de Kubernetes más grandes, comencé a notar errores inusuales de resolución de nombres DNS registrados por nuestra aplicación.

En GitHub se ha hablado de esto durante bastante tiempo, así que decidí inspeccionarlo también.Al final entendí que en nuestro caso esto se debe a una carga incrementada en kube-dns y dnsmasq. Lo más interesante y novedoso para mí fue la misma razón del aumento significativo en el tráfico de consultas DNS. De esto y de qué hacer al respecto, trata mi publicación.

La resolución de DNS dentro de un contenedor, al igual que en cualquier sistema Linux, se determina por un archivo de configuración /etc/resolv.conf. Por defecto, Kubernetes dnsPolicy este ClusterFirst, lo que significa que cualquier consulta DNS se redirigirá a dnsmasq, que se ejecuta en un pod kube-dns dentro del clúster, que a su vez redirigirá la consulta a la aplicación kube-dns, si el nombre termina con el sufijo del clúster, o de lo contrario, al servidor DNS de nivel superior.

Archivo /etc/resolv.conf Dentro de cada contenedor por defecto se verá así:

nameserver 100.64.0.10
search namespace.svc.cluster.local svc.cluster.local cluster.local 
eu-west-1.compute.internal
options ndots:5

Como se puede observar, hay tres directivas:

  1. El servidor de nombres es la IP del servicio, kube-dns
  2. Se especifican 4 dominios de búsqueda locales, search
  3. Hay una opción ndots:5

Una parte interesante de esta configuración es cómo los dominios de búsqueda locales y las configuraciones ndots:5 conviven. Para entender esto, es necesario desentrañar cómo funciona la resolución DNS para nombres incompletos.

¿Qué es un nombre completo?

Un nombre completamente definido es aquel para el cual no se realizará una búsqueda local, y su nombre se considerará absoluto durante la resolución de nombres. Por convención, el software DNS considera que un nombre está completamente definido si termina con un punto (.), y no completamente definido de lo contrario. Es decir, google.com. está completamente definido, mientras que google.com no lo está.

¿Cómo se maneja un nombre incompleto?

Cuando una aplicación se conecta a un host remoto especificado en el nombre, la resolución de nombres DNS generalmente se realiza mediante una llamada al sistema, como getaddrinfo(). Sin embargo, si el nombre es incompleto (no termina en .), resulta interesante si la llamada al sistema intentará resolver el nombre como absoluto primero, o si pasará primero por los dominios de búsqueda locales. Esto depende de la opción ndots.

Según el manual de resolv.conf:

ndots:n

establece el umbral para la cantidad de puntos que deben aparecer en el nombre antes de que se realice la primera consulta absoluta. El valor predeterminado para n es 1, lo que significa que si el nombre tiene algún punto, el nombre se probará primero como un nombre absoluto antes de que se le agreguen elementos de la lista de búsqueda.

Esto significa que si ndots se establece en 5 y el nombre contiene menos de 5 puntos, la llamada del sistema intentará resolverlo secuencialmente, pasando primero por todos los dominios de búsqueda locales y, en caso de falla, finalmente lo resolverá como un nombre absoluto.

¿Por qué podría ndots:5 afectar negativamente el rendimiento de la aplicación?

Como comprenderás, si tu aplicación utiliza mucho tráfico externo, por cada conexión TCP establecida (o, más precisamente, por cada nombre resuelto) generará 5 consultas DNS antes de que el nombre se resuelva correctamente, ya que primero pasará por 4 dominios de búsqueda locales y al final realizará una consulta de resolución del nombre absoluto.

En el siguiente gráfico se muestra el tráfico total en nuestros 3 módulos kube-dns antes y después de que cambiamos varios nombres de host configurados en nuestra aplicación a nombres completamente calificados.

/etc/resolv.conf для Kubernetes pods, опция ndots:5, как это может негативно сказаться на производительности приложения

En el siguiente gráfico se muestra la latencia de la aplicación antes y después de que cambiamos varios nombres de host configurados en nuestra aplicación a nombres completos (la línea azul vertical indica el despliegue):

/etc/resolv.conf для Kubernetes pods, опция ndots:5, как это может негативно сказаться на производительности приложения

Solución #1: usar nombres completamente calificados

Si tienes pocos nombres estáticos externos (es decir, definidos en la configuración de la aplicación) a los que realizas un gran número de conexiones, posiblemente la solución más sencilla sea cambiar a nombres completamente calificados, simplemente añadiendo. al final.

No es una solución definitiva, pero ayuda a mejorar la situación rápidamente, aunque no de manera limpia. Este parche lo aplicamos para resolver nuestro problema, cuyos resultados se mostraron en las capturas de pantalla anteriores.

Solución #2: personalización ndots en dnsConfig

En Kubernetes 1.9 se introdujo en modo alfa una funcionalidad (versión beta v1.10) que permite un mejor control de los parámetros DNS a través de la propiedad del pod en dnsConfig. Entre otras cosas, permite configurar el valor ndots para un pod específico, es decir.

apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: dns-example
spec:
  containers:
    - name: test
      image: nginx
  dnsConfig:
    options:
      - name: ndots
        value: "1"

Fuentes

También lee otros artículos en nuestro blog:

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster