Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Kubernetes y gestión de secretos en la nube: Parte 2

By Alexei LedenevMay 7, 20205 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

1 2vmdytkvuqf4gosqpgyjka

Almacena API keys, contraseñas, certificados y otros datos sensibles en servicios nativos de la nube para gestionar secretos y accede a ellos desde tus clusters de K8s.

Introducción

Los secretos son fundamentales para el funcionamiento de muchos sistemas en producción. Su exposición involuntaria es uno de los principales riesgos que hay que atender. Los desarrolladores deben hacer todo lo posible por proteger los secretos de sus aplicaciones.

El problema se complica aún más cuando una empresa migra a una arquitectura de microservicios y varios servicios necesitan acceder a distintos secretos para funcionar correctamente. De ahí surgen nuevos retos: ¿cómo distribuir, gestionar, monitorear y rotar los secretos de las aplicaciones sin exponerlos por accidente?

En el post anterior ( Parte I), mostré una forma de integrar los servicios de gestión de secretos de AWS y Google Cloud ( AWS Secrets Manager, AWS SSM Parameter Store y Google Cloud Secret Manager) con Kubernetes, mediante el initContainer doitintl/secrets-init agregado manualmente al Pod de destino.

En este post voy a presentar un enfoque Kubernetes-native para integrar los servicios de gestión de secretos en la nube mencionados.

Inyección automática de secretos en la nube

Aunque es posible modificar manualmente los archivos YAML de Deployment de Kubernetes para usar secret-init como sistema init del contenedor, lo ideal sería que alguien lo hiciera por ti, y solo en aquellos Pods de Kubernetes que referencian secretos en la nube. Por suerte, Kubernetes nos permite inspeccionar y modificar cualquier Pod antes de que se cree el contenedor mediante un mecanismo conocido como mutating admission webhook.

doitintl/kube-secrets-init es un proyecto open-source de DoiT International que implementa un mutating admission webhook de Kubernetes para inyectar secretos en la nube, con soporte tanto para secretos gestionados de AWS como de Google Cloud.

kube-secrets-init monitorea los clusters de Kubernetes en busca de Pods recién creados o actualizados y agrega un initContainer con la utilidad doitintl/secrets-init a aquellos Pods que referencian secretos en la nube de forma directa (mediante variables de entorno) o indirecta (mediante Secret y ConfigMap de Kubernetes).

0 hvfcvwhqc bmz8jd

Integración con AWS Secrets Manager

Puedes usar una referencia ARN de un secreto de AWS como valor de una variable de entorno. secrets-init resolverá ese valor, a partir del ARN especificado, al valor del secreto referenciado.

https://gist.github.com/930c9ea733557f9715f976df042bf361

Integración con AWS Systems Manager Parameter Store

Puedes usar AWS Systems Manager Parameter Store para almacenar parámetros y secretos de la aplicación.

Coloca una referencia ARN de AWS Parameter Store como variable de entorno. secrets-init resolverá ese valor, a partir del ARN especificado, al valor del parámetro referenciado.

https://gist.github.com/f7d9a81d5e239cdd734989a689d46f82

Integración con Google Secret Manager

Puedes usar el nombre de un Google Secret (con el prefijo gcp:secretmanager:) como valor de una variable de entorno. secrets-init resolverá ese valor, a partir del nombre especificado, al valor del secreto referenciado. El nombre puede incluir una versión específica para apuntar a una versión concreta del secreto.

https://gist.github.com/d121cce3a9d4664a876deb95f18493d7

Requisitos

AWS

Para resolver secretos desde AWS Secrets Manager y Parameter Store, la aplicación secrets-init debe ejecutarse bajo un AWS IAM Role con alguna de las siguientes políticas IAM asociadas.

Para AWS Secrets Manager:

https://gist.github.com/7348301b4882a564cbd9644d6697c3eb

Para AWS Systems Manager Parameter Store:

https://gist.github.com/3f3dd3d015a4c000341491c18ac2c4b7

Si lo ejecutas en un cluster de EKS, lo recomendable es usar AWS IAM Roles for Service Account. También se puede asignar un IAM Role a la instancia EC2 donde corre el contenedor, aunque esta opción se considera menos segura.

Google Cloud

Para resolver secretos desde Google Secret Manager, la aplicación secrets-init debe ejecutarse bajo un IAM role con permisos suficientes para acceder a los secretos deseados. Por ejemplo, puedes asignar estos dos roles IAM predefinidos de Google a una Google Service Account: Secret Manager Viewer y Secret Manager Secret Accessor.

En un cluster de GKE puedes asignar un IAM Role a un Pod de Kubernetes mediante Workload Identity. También es posible asignarlo a la instancia GCE donde corre el contenedor, aunque esta opción se considera menos segura.

Descomenta el flag --provider=google en el archivo deployment.yaml.

Despliegue del Webhook

  1. Para desplegar el servidor del webhook kube-secrets-init hay que crear un servicio de webhook y un deployment en nuestro cluster de Kubernetes. Es bastante sencillo, salvo por un detalle: la configuración TLS del servidor. Si revisas el archivo deployment.yaml, verás que el certificado y la llave privada correspondiente se leen desde argumentos de línea de comandos, y que la ruta de esos archivos proviene de un volume mount que apunta a un secreto de Kubernetes:

https://gist.github.com/b861984a2be2f2f63596f089f417cefc

Lo más importante es recordar que hay que configurar el certificado CA correspondiente más adelante en la configuración del webhook, para que el apiserver lo acepte. Por ahora vamos a reutilizar el script escrito originalmente por el equipo de Istio para generar una solicitud de firma de certificado. Después enviaremos la solicitud a la Kubernetes API, obtendremos el certificado y crearemos el secreto requerido con el resultado.

Primero, ejecuta el script webhook-create-signed-cert.sh y verifica que se haya creado el secreto que contiene el certificado y la llave:

https://gist.github.com/43135c6af29328bcd74a37b0df5188f8

Una vez creado el secreto, ya podemos crear el deployment y el servicio. Son recursos estándar de deployment y servicio de Kubernetes. Hasta este punto solo tenemos un servidor HTTP que acepta solicitudes a través del servicio en el puerto 443:

https://gist.github.com/3971cf1f46f5a57d11d922ed84b0543f

Configurar el Mutating Admission Webhook

Ahora que el servidor del webhook está en marcha, puede aceptar solicitudes del apiserver. Sin embargo, antes hay que crear algunos recursos de configuración en Kubernetes. Empecemos por el validating webhook y más adelante configuramos el mutating webhook. Si revisas la configuración del webhook, notarás que contiene un placeholder para CA_BUNDLE:

https://gist.github.com/fcafa7ed3b3c3b951b7fad3c0d5fbdb6

Existe un script breve que reemplaza el placeholder CA_BUNDLE en la configuración por este CA. Ejecuta este comando antes de crear la configuración del validating webhook:

https://gist.github.com/6d5bb7724cef04e9e6a2af12da917a21

Crea una configuración de mutating webhook:

https://gist.github.com/f946d6046cc1a76a21526c346ca403c1

Configurar RBAC para secrets-init-webhook

Crea una Service Account de Kubernetes para usarla con secrets-init-webhook:

https://gist.github.com/0cda887b586609cbdbb700f7412e70ad

Define los permisos RBAC de la service account del webhook:

https://gist.github.com/1205f1a5d2f449cc3340a404ea474b77

Resumen

Espero que este post te resulte útil. Quedo atento a tus comentarios y cualquier duda que tengas.

Te invitamos también a contribuir (Issues, Features, PRs) al proyecto de GitHub doitintl/kube-secrets-init.

¿Quieres leer más de Alexei? Visita nuestro blog o síguelo en Twitter.