Optimización de Rendimiento en Kubernetes: Limpieza de Recursos con Kube-Janitor y Políticas Avanzadas ✨
Este tutorial te guiará a través de la implementación de Kube-Janitor para la limpieza automática y eficiente de recursos de Kubernetes. Aprenderás a definir políticas de limpieza, configurar Kube-Janitor y asegurar que tus clusters permanezcan optimizados y libres de recursos huérfanos, mejorando la eficiencia y reduciendo costes operativos.
Introducción: La Necesidad de Limpieza en Kubernetes 🧹
En entornos de Kubernetes dinámicos, es común que se acumulen recursos que ya no son necesarios: Pods completados, Deployments antiguos, PVCs huérfanos, Services de prueba o Ingresses que quedaron atrás. Esta acumulación, conocida como resource sprawl, puede llevar a varios problemas:
- Aumento de Costes: Recursos persistentes no utilizados consumen CPU, memoria y almacenamiento, resultando en facturas más altas.
- Ineficiencia Operativa: Dificultad para identificar recursos activos entre la maraña de elementos obsoletos.
- Riesgos de Seguridad: Recursos antiguos con configuraciones potencialmente vulnerables o accesos no deseados.
- Consumo de IPs: Los Services y Ingresses consumen IPs, que son un recurso finito en muchos entornos cloud.
- Entorno Desordenado: Un cluster lleno de basura es más difícil de gestionar, depurar y auditar.
Tradicionalmente, la limpieza se realiza de forma manual, lo cual es propenso a errores y poco escalable. Aquí es donde herramientas como Kube-Janitor entran en juego, automatizando este proceso crucial y permitiendo a los equipos DevOps centrarse en tareas de mayor valor.
¿Qué es Kube-Janitor y Cómo Funciona? 🤖
Kube-Janitor es un controlador de Kubernetes de código abierto diseñado para escanear y eliminar automáticamente recursos que cumplen ciertos criterios de caducidad. Es altamente configurable, permitiendo definir políticas complejas basadas en etiquetas (labels), anotaciones (annotations) y tipos de recursos.
Su funcionamiento básico es el siguiente:
- Observación: Kube-Janitor monitorea el cluster de Kubernetes, listando los recursos de los tipos configurados.
- Evaluación de Políticas: Para cada recurso, aplica un conjunto de reglas de expiración definidas. Estas reglas pueden basarse en la antigüedad del recurso (usando
creationTimestampo una anotación personalizada) o en la presencia de etiquetas específicas. - Marcado para Eliminación (Opcional): Antes de eliminar, Kube-Janitor puede añadir una anotación al recurso indicando que ha sido marcado para eliminación. Esto da un período de gracia para que los operadores puedan intervenir si es necesario.
- Eliminación: Si un recurso cumple las políticas de expiración y, opcionalmente, ha pasado su período de gracia, Kube-Janitor procede a eliminarlo.
Kube-Janitor se ejecuta como un Pod dentro de tu cluster, lo que facilita su despliegue y gestión.
Tipos de Recursos Soportados 📂
Kube-Janitor puede gestionar la limpieza de una amplia gama de recursos de Kubernetes, incluyendo, pero no limitado a:
PodsDeploymentsReplicaSetsStatefulSetsJobsyCronJobsPersistentVolumeClaims (PVCs)ServicesIngressesConfigMapsySecrets(con precaución)Custom Resource Definitions (CRDs)y sus instancias
La flexibilidad para definir políticas por tipo de recurso es una de sus mayores fortalezas.
Preparación del Entorno 🛠️
Antes de desplegar Kube-Janitor, asegúrate de tener acceso a un cluster de Kubernetes y las herramientas básicas:
- kubectl: Para interactuar con tu cluster.
- helm (opcional): Para una instalación más sencilla de Kube-Janitor.
Creando un Namespace Dedicado 🎯
Es una buena práctica desplegar Kube-Janitor en su propio namespace.
kubectl create namespace kube-janitor
Permisos Necesarios: RBAC 🔐
Kube-Janitor necesita permisos para listar, obtener, actualizar y eliminar los recursos que va a gestionar. Esto se logra a través de ServiceAccount, ClusterRole y ClusterRoleBinding.
A continuación, se muestra un ejemplo básico de RBAC. Kube-Janitor generalmente viene con sus propios manifiestos de RBAC que puedes adaptar.
# service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-janitor-sa
namespace: kube-janitor
---
# cluster-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kube-janitor-role
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list", "watch", "delete", "update", "patch"]
---
# cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kube-janitor-binding
subjects:
- kind: ServiceAccount
name: kube-janitor-sa
namespace: kube-janitor
roleRef:
kind: ClusterRole
name: kube-janitor-role
apiGroup: rbac.authorization.k8s.io
Para aplicar estos recursos:
kubectl apply -f service-account.yaml -n kube-janitor
kubectl apply -f cluster-role.yaml
kubectl apply -f cluster-role-binding.yaml
Despliegue de Kube-Janitor 🚀
La forma más sencilla de desplegar Kube-Janitor es usando Helm.
Añadir el repositorio de Helm
helm repo add kube-janitor https://navikt.github.io/helm-charts
helm repo update
Instalar Kube-Janitor con Helm
La instalación de Kube-Janitor se realiza con el comando helm install, donde especificaremos el ServiceAccount que creamos previamente y configuraremos las políticas.
helm install kube-janitor kube-janitor/kube-janitor \
--namespace kube-janitor \
--set serviceAccount.create=false \
--set serviceAccount.name=kube-janitor-sa \
--set janitor.dryRun=true \
--set janitor.interval="5m" \
--set janitor.policies[0].apiGroup="*" \
--set janitor.policies[0].kind="Pod" \
--set janitor.policies[0].ttl="1h" \
--set janitor.policies[0].selector.matchLabels.janitor-enabled="true" \
--set janitor.policies[0].selector.matchLabels.environment!="production" \
--set janitor.policies[1].apiGroup="batch" \
--set janitor.policies[1].kind="Job" \
--set janitor.policies[1].ttl="2h" \
--set janitor.policies[1].selector.matchLabels.type="ci-job" \
--set janitor.policies[2].apiGroup="" \
--set janitor.policies[2].kind="PersistentVolumeClaim" \
--set janitor.policies[2].ttl="24h" \
--set janitor.policies[2].selector.matchLabels.status="orphan" \
--set janitor.policies[3].apiGroup="apps" \
--set janitor.policies[3].kind="Deployment" \
--set janitor.policies[3].ttl="48h" \
--set janitor.policies[3].selector.matchLabels.status="deprecated" \
--set janitor.policies[3].selector.matchExpressions[0].key="app.kubernetes.io/instance" \
--set janitor.policies[3].selector.matchExpressions[0].operator="DoesNotExist"
Analicemos los parámetros clave:
--namespace kube-janitor: Despliega Kube-Janitor en elnamespacekube-janitor.--set serviceAccount.create=false --set serviceAccount.name=kube-janitor-sa: Indica que usaremos unServiceAccountexistente.--set janitor.dryRun=true: MUY IMPORTANTE. Inicialmente, Kube-Janitor se ejecutará en modo dry-run, lo que significa que solo reportará qué recursos serían eliminados, sin ejecutar la eliminación real. Esto es crucial para probar las políticas.--set janitor.interval="5m": Define el intervalo de escaneo del cluster (en este caso, cada 5 minutos).--set janitor.policies[...]: Aquí es donde definimos nuestras reglas de limpieza. Cada índice en el arraypoliciesrepresenta una política diferente.apiGroup,kind: Especifica el tipo de recurso al que aplica la política (e.g.,kind: PodsinapiGrouppara recursos core,apiGroup: batch,kind: Job).ttl: Time To Live, el tiempo después del cual el recurso es elegible para eliminación (e.g.,1hpara 1 hora,24hpara 24 horas).selector: UnlabelSelectorpara filtrar los recursos. Solo se considerarán los recursos que coincidan con estos selectores.matchLabels: Coincidencia exacta de etiquetas (e.g.,janitor-enabled: "true"). También se pueden usar negaciones comoenvironment!= "production".matchExpressions: Coincidencia más compleja, con operadores comoIn,NotIn,Exists,DoesNotExist.
Políticas de Ejemplo Explicadas
- Pods de desarrollo o testing: Eliminar
Podsque tengan la etiquetajanitor-enabled: "true"y que no sean del entorno deproduction, después de 1 hora de su creación. - Jobs de CI: Eliminar
Jobscon la etiquetatype: "ci-job"después de 2 horas. - PVCs huérfanas: Eliminar
PersistentVolumeClaimsmarcadas constatus: "orphan"después de 24 horas. (Esto requeriría un proceso externo que marque las PVCs huérfanas). - Deployments obsoletos: Eliminar
Deploymentscon la etiquetastatus: "deprecated"y que no tengan la etiquetaapp.kubernetes.io/instance(indicando que no son parte de una aplicación Helm activa, por ejemplo) después de 48 horas.
# values.yaml (ejemplo de configuración de políticas)
janitor:
dryRun: true
interval: "10m"
policies:
- apiGroup: ""
kind: "Pod"
ttl: "30m"
selector:
matchLabels:
temp-resource: "true"
- apiGroup: "batch"
kind: "Job"
ttl: "1h"
selector:
matchExpressions:
- key: "job-type"
operator: "In"
values:
- "cleanup"
- "test"
Verificación del Despliegue ✅
Comprueba que el Pod de Kube-Janitor se ha desplegado correctamente y está corriendo:
kubectl get pods -n kube-janitor
Deberías ver un output similar a:
NAME READY STATUS RESTARTS AGE
kube-janitor-xxxxxxxxx-yyyyy 1/1 Running 0 5m
También puedes ver los logs para observar las acciones que Kube-Janitor estaría realizando en modo dryRun:
kubectl logs -f -n kube-janitor <nombre-del-pod-de-kube-janitor>
Busca mensajes que indiquen qué recursos serían eliminados (Would delete resource...).
Creando Recursos para la Limpieza 🧪
Para probar nuestras políticas, crearemos algunos recursos temporales.
Pod Temporal con janitor-enabled y environment: development
# temp-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-temp-dev-pod
labels:
janitor-enabled: "true"
environment: "development"
spec:
containers:
- name: busybox
image: busybox
command: ["sh", "-c", "sleep 3600"]
restartPolicy: Never
kubectl apply -f temp-pod.yaml
Después de aplicar, Kube-Janitor debería detectar este Pod y, si ha pasado el ttl (1 hora en nuestro ejemplo de Helm), reportaría su eliminación en los logs (en modo dry-run).
Job de CI con type: ci-job
# temp-ci-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: my-ci-cleanup-job
labels:
type: "ci-job"
spec:
template:
spec:
containers:
- name: cleaner
image: alpine/git
command: ["sh", "-c", "echo 'Cleaning up CI artifacts...' && sleep 60"]
restartPolicy: OnFailure
backoffLimit: 4
kubectl apply -f temp-ci-job.yaml
Este Job debería ser candidato para eliminación después de 2 horas.
Deployment con status: deprecated (sin app.kubernetes.io/instance)
# deprecated-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: old-api-gateway
labels:
status: "deprecated"
spec:
replicas: 1
selector:
matchLabels:
app: old-api-gateway
template:
metadata:
labels:
app: old-api-gateway
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
kubectl apply -f deprecated-deployment.yaml
Este Deployment debería ser eliminado después de 48 horas.
Configuración Avanzada de Políticas ✨
Las políticas de Kube-Janitor son increíblemente flexibles y permiten escenarios de limpieza muy específicos.
Usando Anotaciones para Control Fino 🏷️
Además de creationTimestamp y labels, Kube-Janitor puede utilizar anotaciones para definir la expiración. La anotación clave es janitor.kubernetes.io/ttl.
Ejemplo de un Pod con ttl definido por anotación:
apiVersion: v1
kind: Pod
metadata:
name: pod-with-custom-ttl
labels:
janitor-enabled: "true"
annotations:
janitor.kubernetes.io/ttl: "15m"
spec:
containers:
- name: busybox
image: busybox
command: ["sh", "-c", "sleep 3600"]
restartPolicy: Never
Si Kube-Janitor está configurado para buscar la anotación janitor.kubernetes.io/ttl, este Pod será elegible para eliminación después de 15 minutos, independientemente de la política ttl definida en la configuración general para Pods.
Períodos de Gracia y Marcado de Recursos ⏳
Kube-Janitor puede ser configurado para marcar un recurso antes de eliminarlo, dándole un gracePeriod. Esto se hace añadiendo la anotación janitor.kubernetes.io/expires-at con una marca de tiempo UTC en formato ISO 8601.
Puedes configurar Kube-Janitor para que primero añada esta anotación y solo elimine los recursos que ya tienen la anotación janitor.kubernetes.io/expires-at y cuya fecha/hora haya pasado.
janitor:
... (otras configuraciones)
addExpiresAt: true # Kube-Janitor añadirá la anotación janitor.kubernetes.io/expires-at
gracePeriod: "1h" # Período de gracia de 1 hora después de marcarlo
Con esta configuración, Kube-Janitor haría lo siguiente:
- Identifica un recurso que cumple una política de limpieza.
- Añade la anotación
janitor.kubernetes.io/expires-atal recurso, con la fecha actual +gracePeriod. - En un ciclo posterior, si la fecha de
janitor.kubernetes.io/expires-atha pasado, elimina el recurso.
Esto proporciona una capa de seguridad adicional, permitiendo la intervención manual si un recurso marcado no debería ser eliminado.
Excluyendo Recursos Específicos 🚫
Incluso con políticas bien definidas, puede que necesites excluir ciertos recursos de la limpieza. Kube-Janitor permite esto a través de anotaciones o etiquetas.
La anotación janitor.kubernetes.io/do-not-sweep: "true" o janitor.kubernetes.io/do-not-sweep-until: "YYYY-MM-DDTHH:MM:SSZ" impedirá que Kube-Janitor elimine el recurso.
Ejemplo:
apiVersion: v1
kind: Pod
metadata:
name: important-long-running-pod
labels:
janitor-enabled: "true"
environment: "development"
annotations:
janitor.kubernetes.io/do-not-sweep: "true" # Este Pod nunca será eliminado por Kube-Janitor
spec:
containers:
- name: long-runner
image: busybox
command: ["sh", "-c", "sleep 86400"]
restartPolicy: Never
También puedes usar janitor.kubernetes.io/do-not-sweep-until para posponer la limpieza hasta una fecha específica.
Monitoreo y Alertas 📊
Para garantizar que Kube-Janitor funciona como se espera y para detectar problemas (como eliminaciones inesperadas o políticas que no funcionan), es crucial integrarlo con tu sistema de monitoreo.
Kube-Janitor expone métricas Prometheus. Puedes configurarlo para que estas métricas sean recolectadas por Prometheus y visualizadas en Grafana.
Métricas Clave a Monitorear:
kubejanitor_scanned_resources_total: Número total de recursos escaneados por tipo.kubejanitor_deleted_resources_total: Número total de recursos eliminados por tipo y política.kubejanitor_dryrun_deleted_resources_total: Número de recursos que serían eliminados en modo dry-run.kubejanitor_resource_errors_total: Errores encontrados al procesar recursos.
Ejemplo de Alerta Prometheus/Alertmanager
# alertmanager.yaml
alertmanager:
... (configuración existente)
rules:
- alert:
name: KubeJanitorTooManyDeletions
expr: increase(kubejanitor_deleted_resources_total[5m]) > 100
for: 5m
labels:
severity: warning
annotations:
summary: "Kube-Janitor está eliminando una gran cantidad de recursos en un corto período."
description: "Kube-Janitor ha eliminado más de 100 recursos en los últimos 5 minutos. Esto podría indicar una configuración incorrecta de las políticas."
- alert:
name: KubeJanitorDryRunReportUnexpected
expr: (increase(kubejanitor_dryrun_deleted_resources_total{kind="Pod", policy="pods-dev"}[1h]) > 0) and on() (kube_pod_info{pod=~"my-important-prod-pod.*", namespace="production"} == 1)
for: 15m
labels:
severity: critical
annotations:
summary: "Kube-Janitor en dry-run reporta eliminación de un recurso de producción."
description: "Kube-Janitor, incluso en modo dry-run, ha identificado un recurso de producción crucial para eliminación. ¡Revisa las políticas URGENTE!"
Paneles de Grafana 📈
Un panel de Grafana te permitiría visualizar:
- Recursos eliminados a lo largo del tiempo, agrupados por tipo.
- Recursos que serían eliminados en modo dry-run.
- Errores de Kube-Janitor.
- Tendencias de limpieza y su impacto en el consumo de recursos.
Mejores Prácticas y Consideraciones 🤔
1. Empieza con dryRun=true
Siempre, siempre despliega Kube-Janitor con dryRun=true en tu entorno de producción hasta que estés 100% seguro de que las políticas son correctas. Monitorea los logs y las métricas de dryrun_deleted_resources_total.
2. Políticas Granulares y Específicas
Evita políticas genéricas (kind: "*"). Sé muy específico con los kind y utiliza labels y annotations para acotar los recursos a limpiar. Las políticas deben ser explícitas para evitar eliminaciones accidentales.
3. Uso de Etiquetas y Anotaciones para el Ciclo de Vida
Define un conjunto de etiquetas estándar en tu organización para indicar el ciclo de vida o la naturaleza temporal de un recurso (e.g., environment: dev, temp-resource: true, owner: team-x). Esto facilita la creación de políticas de Kube-Janitor.
4. Exclusiones Explícitas para Recursos Críticos
Usa janitor.kubernetes.io/do-not-sweep: "true" o janitor.kubernetes.io/do-not-sweep-until para proteger explícitamente recursos que NUNCA deben ser eliminados, incluso si accidentalmente coinciden con una política.
5. Monitoreo y Alertas
Configura alertas para eliminaciones inesperadamente altas o para cuando Kube-Janitor detecte recursos críticos que serían eliminados en dryRun.
6. Comunicación con los Desarrolladores
Asegúrate de que los equipos de desarrollo estén al tanto de las políticas de limpieza. Explica cómo etiquetar sus recursos temporales para que sean limpiados y cómo excluir los persistentes.
7. Consideraciones sobre el Tiempo de Vida (TTL)
Establece TTLs razonables. No quieres eliminar recursos demasiado pronto, pero tampoco quieres que persistan indefinidamente. Considera la frecuencia de uso de los entornos de desarrollo/pruebas.
8. Limpieza de Recursos Externos (Opcional)
Kube-Janitor se enfoca en recursos de Kubernetes. Si tienes recursos externos (bases de datos en la nube, buckets S3) que deben limpiarse junto con los recursos de Kubernetes, necesitarás una solución complementaria (como scripts o herramientas de IaC).
Tabla Comparativa: Limpieza Manual vs. Kube-Janitor
| Característica | Limpieza Manual | Kube-Janitor |
|---|---|---|
| --- | --- | --- |
| Eficiencia | Baja, consume tiempo y es repetitiva | Alta, proceso automatizado |
| Precisión | Propensa a errores humanos | Basada en políticas, alta precisión |
| --- | --- | --- |
| Escalabilidad | Muy baja, no escala bien | Alta, gestiona clusters grandes |
| Consistencia | Variada, depende del operador | Alta, políticas aplicadas uniformemente |
| --- | --- | --- |
| Detección de Huérfanos | Difícil de identificar | Excelente, basado en reglas de TTL |
| Curva de Aprendizaje | Baja, comandos básicos | Moderada, configuración de políticas |
| --- | --- | --- |
| Impacto en Costes | Reducción lenta | Reducción proactiva y continua |
Conclusión ✅
Kube-Janitor es una herramienta poderosa y esencial para mantener la higiene y optimización de tus clusters de Kubernetes. Al automatizar la identificación y eliminación de recursos no utilizados, no solo reduces costes y liberas espacio, sino que también mejoras la eficiencia operativa y la seguridad de tu infraestructura.
La clave del éxito con Kube-Janitor radica en una planificación cuidadosa de tus políticas, un despliegue gradual comenzando con dryRun, y una integración robusta con tus herramientas de monitoreo y alerta. Invertir tiempo en configurar Kube-Janitor correctamente te ahorrará innumerables horas de trabajo manual y problemas futuros.
¡Anímate a implementar Kube-Janitor y transforma la gestión de tus recursos de Kubernetes!
Tutoriales relacionados
- Gestión de Redes en Kubernetes: Servicios, Ingress y Network Policies 🌐intermediate15 min
- Automatización de Tareas Administrativas en Kubernetes con Kube-scheduler Personalizado 🛠️advanced20 min
- Optimización de Recursos en Kubernetes: Limitando y Solicitando CPU/Memoria para tus Contenedores 🚀intermediate15 min
- Despliegues Azules/Verdes en Kubernetes: Estrategias de Actualización sin Interrupciones 🔄intermediate20 min
- Observabilidad Integral en Kubernetes: Monitorización, Logs y Tracing con Prometheus, Grafana y Jaeger 📊intermediate20 min
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero!