Cloudflare outage on June 21, 2022

Introducción

Hoy, 21 de junio de 2022, Cloudflare ha sufrido una interrupción de nuestros servicios que ha afectado al tráfico en 19 de nuestros centros de datos. Desafortunadamente, estas 19 ubicaciones son las más grandes y gestionan una proporción significativa de nuestro tráfico global. La causa de esta interrupción fue un cambio que era parte de un proyecto a largo plazo para aumentar la resistencia en nuestras ubicaciones más importantes ya que son una parte crítica de nuestra infraestructura y gestionan una parte significativa de nuestro tráfico en Cloudflare. Un cambio de la configuración de la red en esas ubicaciones provocó un corte que comenzó a las 06:27 UTC. A las 06:58 UTC, el primer centro de datos fue puesto de nuevo en servicio y a las 07:42 UTC todos los centros de datos estaban de nuevo en línea y funcionando sin problemas.

En función de en qué parte del mundo se encuentre, es posible que haya perdido la capacidad de acceder a páginas web y servicios que dependen de Cloudflare. En otras ubicaciones, Cloudflare siguió operando con normalidad.

Lamentamos mucho esta interrupción. Fue un error por nuestra parte y no el resultado de un ataque o actividad maliciosa.

Información

Durante los últimos 18 meses, Cloudflare ha trabajado en la conversión de todas nuestras ubicaciones más grandes a una arquitectura más redundante. Hasta el momento, hemos convertido 19 de nuestros centros de datos a esta nueva arquitectura, que internamente llamamos Multi-Colo PoP (MCP): Ámsterdam, Atlanta, Ashburn, Chicago, Frankfurt, Londres, Los Ángeles, Madrid, Mánchester, Miami, Milán, Bombay, Newark, Osaka, Sao Paulo, San José, Singapur, Sídney y Tokio.

Una parte esencial de esta nueva arquitectura, que está diseñada como red de Clos, es una capa añadida de enrutamiento que crea una malla de conexiones. Esta malla nos permite inhabilitar y habilitar fácilmente partes de la red interna de un centro de datos para su mantenimiento o para solucionar un problema. Podemos apreciar una representación de está capa en las espinas del siguiente diagrama.

Esta nueva arquitectura nos ha proporcionado significativas mejoras de la confiabilidad, y nos ha permitido hacer mantenimiento en estas ubicaciones sin alterar el tráfico de los clientes. Dado que estas ubicaciones también soportan una proporción significativa del tráfico de Cloudflare, cualquier problema que las afecte puede tener un impacto muy importante y desafortunadamente, eso es lo que ocurrió hoy.

Cronología (UTC) e impacto del incidente

Para contactarlas a través de Internet, las redes como Cloudflare utilizan un protocolo que se llama BGP. Como parte de este protocolo, los operadores definen políticas que deciden qué prefijos (colección de direcciones IP adyacentes) se anuncian a los iguales (las otras redes con las que se conectan) o se aceptan de los iguales.

Estas políticas tienen componentes individuales que se evalúan de manera secuencial. El resultado final es que cualquier prefijo dado se anunciará o no. Un cambio a la política puede significar que un prefijo que antes se anunciaba ya no se anuncia más, en cuyo caso se retira y esas direcciones IP ya no son accesibles por Internet.

Al implementar un cambio a nuestras políticas de anuncios de prefijos, un reordenamiento de los provocó que se retiraran un subconjunto crítico de prefijos.

Debido a esta retirada, los ingenieros de Cloudflare experimentaron un problema adicional para llegar a las ubicaciones afectadas para revertir el cambio problemático. Tenemos procedimientos de respaldo para gestionar esta situación y los aplicamos para tomar el control de las ubicaciones afectadas.

03:56: implementamos el cambio a nuestra primera ubicación. Ninguna de nuestras ubicaciones se vio afectada por el cambio ya que estas utilizan nuestra arquitectura anterior.
06:17: el cambio se implementa en nuestras ubicaciones más grandes, pero no en las ubicaciones con la arquitectura nueva.
06:27: la implementación llega a nuestras ubicaciones más grandes con la arquitectura nueva y el cambio se implementa en estas espinas. Aquí es cuando comenzó el incidente ya que esto desconectó rápidamente a estas 19 ubicaciones.
06:32: se declara el incidente interno de Cloudflare.
06:51: se hace el primer cambio a un enrutador para verificar la posibilidad de la causa de raíz.
06:58: se encontró y comprendió la causa de raíz. Comienza el trabajo para revertir el cambio problemático.
07:42: se completó la última reversión. Esto se retrasó ya que los ingenieros de redes repasaron los cambios de los demás, invirtiendo las reversiones anteriores, provocando que el problema reapareciese esporádicamente.
08:00: incidente cerrado.

La criticalidad de estos centros de datos pueden verse claramente por la cantidad de solicitudes correctas que hemos devuelto globalmente:

Aunque estas ubicaciones suponen únicamente un pequeño porcentaje de nuestra red total(el 4%), impactamos el 50% de nuestras solicitudes totales. Lo mismo puede verse en nuestro ancho de banda de salida:

Descripción técnica del error y como ocurrió

Como parte de nuestros esfuerzos continuos de estandarización de la configuración de nuestra infraestructura, estamos implementando un cambio para estabilizar las comunidades de BGP que adjuntamos a un subconjunto de los prefijos que anunciamos. Específicamente, añadimos comunidades informativas a nuestros prefijos locales de ubicación. Estos prefijos permiten a nuestros nodos de computación comunicarse entre sí y también conectarse a los orígenes de los clientes. Como parte del procedimiento de cambio en Cloudflare, se creó un ticket de solicitud de cambio (CR), que incluye una ejecución en seco del cambio, así como un procedimiento de implementación por etapas. Antes de que se le permitiera salir, también se revisó entre compañeros por parte de múltiples ingenieros. Desafortunadamente, en este caso las etapas no fueron lo suficientemente pequeñas para detectar el error antes de que afectara a todas nuestras espinas.

El cambio tenía este aspecto en uno de los enrutadores:

[edit policy-options policy-statement 4-COGENT-TRANSIT-OUT term ADV-SITELOCAL then]
+      community add STATIC-ROUTE;
+      community add SITE-LOCAL-ROUTE;
+      community add TLL01;
+      community add EUROPE;
[edit policy-options policy-statement 4-PUBLIC-PEER-ANYCAST-OUT term ADV-SITELOCAL then]
+      community add STATIC-ROUTE;
+      community add SITE-LOCAL-ROUTE;
+      community add TLL01;
+      community add EUROPE;
[edit policy-options policy-statement 6-COGENT-TRANSIT-OUT term ADV-SITELOCAL then]
+      community add STATIC-ROUTE;
+      community add SITE-LOCAL-ROUTE;
+      community add TLL01;
+      community add EUROPE;
[edit policy-options policy-statement 6-PUBLIC-PEER-ANYCAST-OUT term ADV-SITELOCAL then]
+      community add STATIC-ROUTE;
+      community add SITE-LOCAL-ROUTE;
+      community add TLL01;
+      community add EUROPE;

Esto no era perjudicial y solamente añadía algo de información adicional a estos anuncios de prefijos. El cambio a las espinas fue el siguiente:

[edit policy-options policy-statement AGGREGATES-OUT]
term 6-DISABLED_PREFIXES { ... }
!    term 6-ADV-TRAFFIC-PREDICTOR { ... }
!    term 4-ADV-TRAFFIC-PREDICTOR { ... }
!    term ADV-FREE { ... }
!    term ADV-PRO { ... }
!    term ADV-BIZ { ... }
!    term ADV-ENT { ... }
!    term ADV-DNS { ... }
!    term REJECT-THE-REST { ... }
!    term 4-ADV-SITE-LOCALS { ... }
!    term 6-ADV-SITE-LOCALS { ... }
[edit policy-options policy-statement AGGREGATES-OUT term 4-ADV-SITE-LOCALS then]
community delete NO-EXPORT { ... }
+      community add STATIC-ROUTE;
+      community add SITE-LOCAL-ROUTE;
+      community add AMS07;
+      community add EUROPE;
[edit policy-options policy-statement AGGREGATES-OUT term 6-ADV-SITE-LOCALS then]
community delete NO-EXPORT { ... }
+      community add STATIC-ROUTE;
+      community add SITE-LOCAL-ROUTE;
+      community add AMS07;
+      community add EUROPE;

Un vistazo inicial a esta diferencia podría dar la impresión de que este cambio es idéntico, pero desafortunadamente, no es el caso. Si nos centramos en una parte de la diferencia, podría quedar claro el porqué:

!    term REJECT-THE-REST { ... }
!    term 4-ADV-SITE-LOCALS { ... }
!    term 6-ADV-SITE-LOCALS { ... }

En este formato diff, los signos de exclamación delante de los términos indican su reordenación. En este caso, múltiples términos fueron movidos hacia arriba y dos términos se añadieron al final. Específicamente, el término 4-ADV-SITE-LOCALS se movió desde arriba hasta abajo. Este término estaba ahora detrás del otro y cómo podría quedar claro por el nombre, esto supone un rechazo explícito:

term REJECT-THE-REST {
    then reject;
} 

Ya que este término ahora está antes de los términos locales de ubicación, dejamos inmediatamente de anunciar nuestros prefijos locales de emplazamiento, quitando nuestro acceso directo a todas las ubicaciones impactadas en un abrir y cerrar de ojos, y quitando también la capacidad de nuestros servidores de llegar a los orígenes.

Además de impedir contactar con los orígenes, la eliminación de estos prefijos locales de ubicación también provocó que nuestro sistema interno de equilibrado de cargas Multimog (una variación de nuestro load balancer Unimog) deja de funcionar ya que no logra reenviar más las solicitudes entre los servidores de nuestros MCP. Esto significó que nuestros clústeres de computación más pequeños de un MCP recibieron la misma cantidad de tráfico que nuestros clústeres más importantes, lo que provocó que los más pequeños se sobrecargaran.

Pasos de mitigación y seguimiento

Este incidente tuvo un impacto generalizado y para nosotros la disponibilidad es algo muy serio. Hemos identificado varias áreas de mejora y seguiremos trabajando para descubrir cualquier otra brecha que pueda provocar una repetición.

Estos son los puntos que trabajaremos inmediatamente:

Proceso: aunque el programa de MCP fue diseñado para mejorar la disponibilidad, una brecha en el procedimiento sobre cómo actualizamos estos centros de datos impactó finalmente más ampliamente en ubicaciones de MCP específicamente. Aunque sí utilizamos un procedimiento por etapas para este cambio, la política de etapas no incluía ningún centro de datos de MCP hasta el paso final. Los procedimientos de cambio y la automatización tienen que incluir pruebas específicas de MCP e implementar procedimientos para garantizar que ninguna consecuencia no deseada tuviera lugar.  

Arquitectura: una configuración incorrecta de enrutadores evitó que se anunciaran en las rutas adecuadas en nuestro borde, impidió que fluyera el tráfico correctamente a nuestra infraestructura. Finalmente, la declaración de la política que provocó el anuncio incorrecto de enrutamiento será rediseñada para prevenir una ordenación incorrecta accidental.  

Automatización: hay varias oportunidades en nuestro conjunto de automatización que evitan parte o todo el impacto que hemos observado en este evento. Principalmente, nos concentraremos en mejoras de automatización que aplican una política mejorada por etapas para despliegues de configuración de red y ofrecen un despliegue automatizado “comprometer y confirmar”. La primera mejora habría disminuido significativamente el impacto general y la segunda habría reducido mucho el tiempo hasta la resolución durante el incidente.

Conclusión

Aunque Cloudflare ha invertido significativamente en nuestro diseño de MCP para mejorar la disponibilidad del servicio, claramente nos quedamos cortos con respecto a las expectativas de nuestros clientes con este incidente tan doloroso. Lamentamos mucho la interrupción del servicio de nuestros clientes y que los usuarios no hayan podido acceder a propiedades de Internet durante la interrupción. Ya comenzamos a trabajar en los cambios que se resumen más arriba y seguiremos con nuestros esfuerzos para garantizar que esto no ocurra de nuevo.