La primera vulnerabilidad crítica en la plataforma de orquestación de contenedores Kubernetes fue revelada a principios de este mes. Esta vulnerabilidad afecta a todas las versiones de Kubernetes superiores a la 1.0.0. También afecta a las versiones de la plataforma RedHat OpenShift superiores a la 3.0.0.
En este post veremos las causas, mitigaciones y cómo afecta esto al Operador Autónomo Couchbase.
La vulnerabilidad
Al conectarse a los pods de Kubernetes, el usuario utilizará normalmente el comando:
1 |
kubectl exec -ti mi-vaina-nombre /papelera/bash |
Para los usuarios de la suite de gestión de contenedores Docker, esto les resultará muy familiar. Esto se debe a que el comando se envía primero a la API de Kubernetes, que actúa como un proxy inverso. El proxy inverso reenvía la solicitud al agente de Kubernetes que se ejecuta en el nodo en el que reside el pod solicitado. Por último, el comando se utiliza para conectarse directamente al contenedor Docker.
La vulnerabilidad queda expuesta en el proxy inverso cuando se produce un error con el comando exec remoto. Las conexiones a los servicios aguas abajo del proxy quedan abiertas cuando se produce un error. Esto, a su vez, proporciona una forma para que los usuarios escalen sus privilegios a los de un administrador de clúster Kubernetes. Los usuarios deben estar autorizados a ejecutar el comando mediante un control de acceso basado en roles.
Con privilegios de administrador, el usuario puede conectarse a cualquier contenedor que se ejecute en el nodo Kubernetes comprometido. Esto permite el acceso a cualquier secreto (normalmente nombres de usuario, contraseñas, claves privadas TLS, etc.) y volúmenes de datos que estén montados en el contenedor. Esto es aún más preocupante si el contenedor se ejecuta con privilegios elevados (root). Además, el contenedor también puede tener el sistema de archivos host montado en modo lectura/escritura.
Una segunda variante se basa de nuevo en la misma vulnerabilidad subyacente del proxy inverso. En la primera variante, el usuario tendría que estar autenticado y tener derechos de acceso para ejecutar comandos en contenedores antes de poder realizar la escalada de privilegios. Con la segunda variante, no se requiere autenticación alguna para obtener acceso administrativo. El alcance de esta vulnerabilidad se limita a la modificación de los service brokers. Estos son servicios gestionados que pueden ser descubiertos y utilizados por una aplicación.
Mitigación
Para la primera variante de la vulnerabilidad, puede evitar la escalada de privilegios de sus usuarios eliminando los permisos para utilizar el archivo exec, adjuntar y portforward para los pods. Estos permisos se conceden por defecto en la mayoría de las instalaciones. Los comandos, sin embargo, suelen ser necesarios en la mayoría de los entornos con fines de depuración y pruebas, por lo que deshabilitar el acceso puede no ser la respuesta correcta.
Por lo tanto, el mejor método para evitar todas las vulnerabilidades es actualizar el clúster de Kubernetes a una versión que tenga la vulnerabilidad parcheada. Las versiones parcheadas comienzan en Kubernetes 1.10.11, 1.11.5 y 1.12.3.
Couchbase Autonomous Operator es compatible con las versiones 1.11.0 y posteriores de Kubernetes. Recomendamos una actualización a cualquiera de las versiones parcheadas aplicables de Kubernetes lo antes posible. El Operador Autónomo en sí no se ve afectado de ninguna manera por estas vulnerabilidades o correcciones; sin embargo, los pods de servidor Couchbase creados pueden estar sujetos a la primera vulnerabilidad, comprometiendo la integridad de los datos.
Consideraciones sobre el operador autónomo
Aunque nunca es agradable sufrir una vulnerabilidad crítica, nos preparamos para tales eventualidades. Las instrucciones completas de actualización de Kubernetes se proporcionan en el Documentación de Operator 1.1.0Sin embargo, en este artículo hablaremos de ellos con más detalle.
Como servicio con estado, hay que tener cuidado con la actualización del clúster Kubernetes para mantener la integridad de los datos de la plataforma de datos Couchbase.
Muchas aplicaciones de gestión de Kubernetes utilizan un enfoque de actualización continua estándar para actualizar cada nodo de trabajo en orden. Para actualizar un único nodo, primero se desalojan (eliminan) los pods. Si un pod forma parte de una aplicación, como un despliegue, el controlador que gestiona la aplicación volverá a crear los pods desalojados. Esto se hace para restaurar el escalado correcto. Tras el desalojo, el agente Kubernetes puede actualizarse. El host subyacente puede ser reiniciado. Este es un buen momento para aplicar los parches del sistema operativo. Finalmente el nodo puede ser añadido de nuevo al cluster.
Para un servicio sin estado, sólo se tarda unos segundos en recrear el pod y añadirlo de nuevo a su grupo de servicios. Para una aplicación con estado como el servidor Couchbase, esto puede llevar mucho más tiempo.
¿Qué ocurre durante un desahucio?
Tomemos por ejemplo un cluster Couchbase con 3 nodos. El clúster Couchbase contiene un único bucket con una única réplica.
Cuando el primer pod de Couchbase es desalojado, el Operador Autónomo detectará que está caído y esperará a que ocurra el failover. El failover restaura la disponibilidad de sus datos desde una réplica. Una vez que se ha producido el failover, el Operador Autónomo creará un nuevo pod y comenzará a reequilibrar los datos a través del cluster de Couchbase. Esto restaura el número correcto de réplicas. Es importante tener en cuenta que durante este proceso necesitarás un nodo Kubernetes adicional para acomodar el nuevo pod.
Dado que hemos perdido uno de los tres nodos, 66% de los documentos contenidos en el bucket se degradarán con una única réplica. Para ilustrarlo, la siguiente tabla muestra 6 documentos maestros (en negrita) y dónde residen sus réplicas. Si el servidor 1 fuera desalojado, los documentos A, B, D y E sólo tendrían una única réplica.
Servidor 1 | Servidor 2 | Servidor 3 |
A | A | |
B | B | |
C | C | |
D | D | |
E | E | |
F | F |
Mientras se produce el reequilibrio, no hay nada que impida que el proceso de actualización de Kubernetes desaloje otro pod de Couchbase. Si se permitiera que esto ocurriera, existe el riesgo de que hasta 33% de sus datos ahora no tengan réplicas y se pierdan. En el ejemplo anterior, el desalojo del servidor 2 provocaría que los documentos A y D fueran irrecuperables.
Por lo tanto, es fundamental controlar cómo y cuándo se desalojan los nodos Kubernetes. Una vez que un pod de servidor Couchbase es desalojado, debe permitir que el Operador Autónomo cree un pod de reemplazo y permitir que los datos sean completamente reequilibrados antes de actualizar el siguiente nodo Kubernetes.
Buenas prácticas para operadores autónomos
Recomendamos el uso de la antiafinidad de pods cuando configures tu clúster de Couchbase. Esta función garantiza que no haya dos pods de servidor Couchbase del mismo clúster de Couchbase en el mismo nodo de Kubernetes. Esto asegura que como mucho una única réplica puede perderse a la vez.
También recomendamos encarecidamente el uso de volúmenes persistentes. En nuestro último post hemos descrito cómo imponemos el uso de volúmenes persistentes para proteger contra la pérdida de datos y respaldar el producto. Una ventaja clave es que, en los ejemplos citados en la última sección, los datos no se perderían.
El Operador Autónomo puede recrear un nuevo pod y reutilizar el volumen de datos existente. Reequilibrar los datos a través de este clúster es sustancialmente más rápido, ya que sólo los documentos que han sido actualizados desde la conmutación por error necesitan ser replicados en los pods de reemplazo.
Incluso con los volúmenes persistentes activados, sigue siendo posible que varios pods sean desalojados en rápida sucesión. Esto puede provocar que ciertos documentos no estén disponibles temporalmente hasta que el Operador Autónomo pueda restaurar los datos.
Mirando al futuro
Queremos que toda la experiencia de actualización de Kubernetes sea fluida. Esto se debe precisamente a que se encontrarán errores en la plataforma Kubernetes o en el sistema operativo. Estos tendrán que ser parcheados para garantizar que sus aplicaciones sean estables y seguras.
Aunque los volúmenes persistentes son parte de la respuesta, no es una solución completa. Hay situaciones en las que los documentos pueden seguir sin estar disponibles. Para solucionar este problema, nos complace anunciar que Autonomous Operator 1.2.0 incluirá mejoras para mitigar la interrupción de sus documentos únicamente durante el periodo de conmutación por error.
Aprovechando los presupuestos de interrupción de pods de Kubernetes, podemos controlar con precisión cuántos pods permitirá desalojar el Operador Autónomo en un momento dado. Esto evita que se desalojen varias réplicas de datos a la vez.
Además de esto, las comprobaciones de disponibilidad de pods utilizadas por los presupuestos de interrupción se han mejorado para saber si los pods del servidor Couchbase están vivos y todos los datos están totalmente replicados en el clúster. Esto permite al Operador Autónomo controlar con precisión cuándo se permite que se produzca un nuevo desalojo.
Conclusión
Couchbase Autonomous Operator está diseñado no sólo como un producto para simplificar el despliegue y la gestión de la plataforma de datos Couchbase. Tenemos una visión más amplia de que operar en plataformas de nube pública gestionadas tendrá sus desafíos únicos. El equipo trabaja continuamente para proteger sus datos y proporcionar una alta disponibilidad de los mismos tanto en situaciones bajo nuestro control como fuera de él.