Cómo usar ConfigMaps de Kubernetes de forma segura
Kuria Macharia
9 de septiembre de 2022
0 minutos de lecturaConfigMaps es un objeto de API que se usa en Kubernetes para almacenar datos en pares clave-valor. Es, básicamente, un diccionario que contiene ajustes de configuración. Algunos datos que podrías esperar encontrar en un ConfigMap incluyen nombres de host, credenciales públicas, cadenas de conexión y URL.
Un ConfigMap desacopla el código de una aplicación de sus configuraciones, lo que permite modificarlas sin afectar la aplicación. Por ejemplo, te permite establecer distintas configuraciones para los entornos de desarrollo, pruebas y producción.
Sin embargo, es importante tener en cuenta que el uso de ConfigMaps puede plantear desafíos de seguridad, ya que no cifran los datos que contienen. Por eso, debemos entender cuándo conviene usar ConfigMaps y cuándo no son lo suficientemente seguros.
Este artículo explora cómo funcionan los ConfigMaps, cómo usarlos de forma segura y algunos casos en los que debemos recurrir a otras opciones de almacenamiento de datos más seguras.
ConfigMaps en Kubernetes
Antes de ver cómo usar ConfigMaps, exploremos los detalles técnicos de su funcionamiento y el papel que desempeñan en Kubernetes.
Cómo funcionan los ConfigMaps
Los ConfigMaps almacenan pares clave-valor como datos de texto sin formato y datos binarios, a diferencia de otros objetos de Kubernetes que usan campos spec. Los ConfigMaps pueden almacenar datos binarios como cadenas codificadas en base64 y datos de texto sin formato como secuencias de bytes UTF-8.
El clúster puede acceder a los ConfigMaps de las siguientes maneras:
Montándolos como un volumen de datos.
Mediante el acceso remoto de Pods en el mismo espacio de nombres de Kubernetes.
Separándolos de los Pods y permitiendo que otros componentes del clúster de Kubernetes los usen.
Los Pods pueden usar ConfigMaps como archivos de configuración, variables de entorno o argumentos de línea de comandos.
Al trabajar con ConfigMaps, es fundamental tener en cuenta que su tamaño está limitado a 1 MB. Si tenemos conjuntos de datos más grandes, debemos considerar otras opciones de almacenamiento, como bases de datos, montajes de archivos independientes o servicios de archivos.
El papel de los ConfigMaps
El papel más importante de los ConfigMaps es hacer que las aplicaciones sean portátiles al separar el código de la aplicación de los ajustes de configuración. Esta separación permite migrar fácilmente de un entorno de desarrollo a uno de pruebas y, finalmente, a uno de producción.
Veamos un ejemplo de cómo un ConfigMap puede ayudarnos al trabajar con Kubernetes. Para esta demostración, supongamos que estamos desarrollando una aplicación localmente y que pensamos implementarla con proveedores de servicios de Kubernetes administrados.
Para acceder a la base de datos localmente, debemos establecer la variable de entorno DATABASE_HOST en localhost o 127.0.0.1. Al migrar a un entorno de producción, debemos cambiar el valor de esa variable por uno que exponga el componente de la base de datos.
Cómo usar ConfigMaps de forma segura
Antes de empezar, estos son los requisitos previos para crear un ConfigMap en un clúster local de Kubernetes:
La versión más reciente de Docker Desktop
Un editor de código, como VS Code.
En esta demostración, veremos cómo crear un ConfigMap en YAML y montarlo como volumen. Este método nos permite crearlo de la misma manera que creamos un recurso de Kubernetes.
Crea un archivo llamado mongo-config.yaml y agrega el siguiente código:
Luego, crea un ConfigMap a partir del archivo anterior con el siguiente comando:
Ahora, veamos cómo consumir el ConfigMap. En esta demostración, usaremos el ConfigMap que creamos anteriormente con variables de entorno. Para consumirlo, agrega una propiedad envFrom al YAML del Pod, como se muestra en el siguiente código:
En el fragmento de código anterior, usamos envFrom para acceder a la información del ConfigMap desde un contenedor.
El último paso es asociarlo a los Pods, que creamos ejecutando el siguiente comando:
Esto permite que los contenedores accedan al ConfigMap como una variable de entorno.
Secrets en Kubernetes
A menudo, se presentan los Secrets como alternativas seguras a los ConfigMaps, ya que tienen algunas características en común:
Usan pares clave-valor para almacenar datos.
Los Pods pueden usar ambos como archivos en un volumen.
Se pueden consumir como variables de entorno (aunque no es recomendable).
Son tipos de objetos a los que se accede mediante un servidor de API.
Ambos tienen un límite de 1 MB, por lo que no son adecuados para grandes volúmenes de datos.
Los Secrets son objetos diseñados para cifrar y almacenar datos confidenciales en Kubernetes. Algunos datos que debemos guardar en Secrets incluyen contraseñas, claves de API, tokens, cadenas de conexión a bases de datos, entre otros. Permiten separar los datos confidenciales del código de la aplicación. Esta separación reduce el riesgo de exposición de datos confidenciales que podrían poner en riesgo el clúster y la aplicación. No debes usar Secrets para almacenar variables de entorno. Como dicen Liz Rice y Michael Hausenblasbokk en su libro Kubernetes Security:
las variables de entorno suelen volcarse en los registros cuando se producen fallas o errores
kubectl describe pod muestra los valores de las variables de entorno como texto sin formato
docker inspect muestra los valores de las variables de entorno como texto sin formato
Hay varios tipos de Secrets para elegir, según el tipo de datos que queramos mantener privados. El tipo más usado es Opaque, que maneja datos arbitrarios definidos por el usuario. Para la autenticación básica, usamos el tipo basic-auth.
De forma predeterminada, los Secrets no se cifran y se almacenan en etcd, el almacenamiento del servidor de API. Cualquier persona con acceso a la API puede acceder a los Secrets y modificarlos. Para limitar el acceso, debes hacer lo siguiente:
Habilita el cifrado de los datos de los Secrets en reposo (muchos, si no todos, los proveedores de Kubernetes administrado te ofrecen esta opción al crear el clúster).
Habilita y configura reglas de RBAC para limitar la lectura y la edición.
Limita quién puede crear Secrets mediante RBAC.
ConfigMaps frente a Secrets
Aunque ConfigMaps y Secrets comparten algunas características, no son iguales y cada uno es más adecuado para ciertos casos de uso, según nuestras necesidades de seguridad.
La principal diferencia entre ConfigMaps y Secrets es la confidencialidad de los datos que contienen. Secrets oculta los datos mediante codificación base64, mientras que los datos de ConfigMaps están en texto sin formato. Ten en cuenta que también podemos almacenar texto sin formato en ConfigMaps como cadenas codificadas en base64.
Otra diferencia es que en Kubernetes hay varios tipos de Secrets. Podemos elegir el tipo de Secret según los datos confidenciales que queramos ocultar.
Cuándo usar ConfigMaps
Los ConfigMaps son muy eficaces para desacoplar los datos de la aplicación del código de configuración. Por ejemplo, supongamos que tenemos un contenedor de aplicación para datos de empleados que se conecta a una base de datos MySQL. Si codificamos directamente la configuración de conexión a la base de datos en el contenedor, habrá confusión al pasar de un entorno de desarrollo a uno de producción, porque no podemos usar la base de datos de desarrollo en producción.
Un ConfigMap facilita el traslado de nuestra aplicación al almacenar los datos de configuración en un archivo independiente, fuera del contenedor. Para cambiar de entorno, solo habría que modificar una referencia a la base de datos.
Puedes mostrar fácilmente los datos de los ConfigMaps ejecutando kubectl describe configmaps <name>. También puedes editarlos con facilidad porque aparecen como texto sin formato. Aunque estas características facilitan cambiar las configuraciones según el entorno (desarrollo, pruebas o producción), los ConfigMaps no son adecuados para manejar datos confidenciales. Los datos confidenciales deben almacenarse en Kubernetes Secrets para poder cifrarlos y limitar el acceso a ellos.
Cuándo usar Secrets
Al igual que los ConfigMaps, los Secrets desacoplan los datos del código de la aplicación. Esto nos permite evitar la exposición de datos confidenciales al crear o modificar Pods.
Ahora volvamos al ejemplo de los datos de empleados. En este caso, la aplicación necesita el host del servidor, el puerto, el nombre de la base de datos, el nombre de usuario y la contraseña para conectarse correctamente a la base de datos.
Comparemos dos fragmentos de código. El primero muestra cómo un ConfigMap maneja los datos y el segundo, cómo lo hace un Secret.
Así se ve un ConfigMap:
El archivo YAML de configMap anterior contiene los detalles no confidenciales de conexión a la base de datos: el host del servidor, el puerto del servidor y el nombre de la base de datos.
Así se vería un archivo de Secrets:
En el archivo YAML de Secret anterior, el tipo de Secret se especifica como basic-auth, que maneja credenciales de autenticación básica. stringData contiene los datos que deben mantenerse privados. En este caso, el nombre de usuario y la contraseña.
En el ejemplo hipotético anterior, Secrets nos ayudó a mantener privados el nombre de usuario y la contraseña de la base de datos. También evita que esta información quede expuesta al crear o modificar el Pod.
Seguridad de la configuración de Kubernetes
Un ConfigMap es un objeto de API de Kubernetes que se usa para almacenar datos de configuración no confidenciales en pares clave-valor. De forma predeterminada, almacena los datos como texto sin formato y permite separar el código de la aplicación de sus configuraciones. Secrets también es un objeto de API de Kubernetes que se usa para cifrar y almacenar datos de configuración confidenciales en pares clave-valor. Sin embargo, reduce el riesgo de exposición de datos confidenciales que podrían poner en riesgo el clúster y la aplicación.
Para crear un clúster de Kubernetes seguro que desacople el código de la aplicación de sus configuraciones, asegúrate de guardar los datos confidenciales en Secrets y las configuraciones no confidenciales en ConfigMaps. También es fundamental habilitar RBAC para restringir el acceso a ConfigMaps y Secrets. Esto reduce el riesgo de que alguien acceda a la configuración sin autorización o la modifique.
Protege la infraestructura desde el origen
Snyk automatiza la seguridad y el cumplimiento de IaC en los flujos de trabajo, y detecta recursos con desviaciones de configuración y recursos faltantes.
