Introducción

El primer martes que un ingeniero de guardia vio paneles blancos en Grafana no fue un martes cualquiera. Los dashboards de Hubble mostraban tráfico TCP, latencias HTTP y visibilidad de DNS sin problemas, pero Prometheus no tenía ServiceMonitors configurados para los pods de Cilium. Dos proyectos CNCF instalados correctamente —uno para networking, otro para observabilidad— eran completamente invisibles entre sí. Esto no era un bug en ninguno de los dos. Era el «impuesto de integración»: el trabajo que consume el 80% del tiempo de los equipos de plataforma, pero que nadie documenta antes de llegar a producción.

La Cloud Native Computing Foundation (CNCF) alberga alrededor de 250 proyectos. En la práctica, los clústeres de Kubernetes en producción suelen basarse en un stack de 20 a 30 herramientas: Prometheus para métricas, ArgoCD para GitOps, Cilium para networking, cert-manager para TLS, Velero para backups, Sealed Secrets para credenciales, y Kyverno para políticas. Cada una se instala con Helm, se configura con valores YAML, y se asume que funcionarán juntas. Pero los fallos aparecen en los espacios entre proyectos, no en sus repositorios de issues.

Qué ocurrió

Prometheus y Cilium: métricas que no llegan a Grafana

En un entorno con Cilium 1.16.0 y Prometheus 2.50.1, las métricas de red —como cilium_node_connectivity_duration_seconds— no aparecían en los dashboards. La razón: falta de un ServiceMonitor que apuntara al pod de cilium-agent y cilium-operator. El problema no era de Cilium (que exponía métricas en /metrics y /metrics/cilium), ni de Prometheus (que scrappeaba correctamente los endpoints), sino de la falta de definición explícita en el Helm chart de Cilium para exponer esos endpoints. Según el CNCF blog, este tipo de fallos representa el 60% de las llamadas a soporte en clústeres con más de 10 nodos.

cert-manager e ingress controllers: renovaciones de TLS que fallan en silencio

Al renovar certificados con cert-manager 1.14.4 y un ingress controller como NGINX 1.10.0 en EKS, el desafío HTTP-01 de ACME recibía un 301 Moved Permanently hacia HTTPS. El token de validación nunca llegaba al pod solver de cert-manager, y las renovaciones fallaban sin alertas. La solución fue migrar a desafíos DNS-01 usando Route53 en AWS, pero esto requirió configurar políticas de IAM específicas (por ejemplo, route53:ChangeResourceRecordSets) que ningún Helm chart de cert-manager incluye por defecto. El GitHub Blog reportó casos similares donde el 30% de los equipos que usan cert-manager en producción no lograban renovaciones automáticas por configuraciones incorrectas de challenges.

Prometheus y kubelet: timestamps duplicados que disparan alertas falsas

kubelet en Kubernetes 1.28.4 expone métricas en dos endpoints: /metrics y /metrics/probes. Ambos endpoints emiten process_start_time_seconds con el mismo valor porque son el mismo proceso. Prometheus, al scrappear ambos, detectaba muestras duplicadas y disparaba la alerta PrometheusDuplicateTimestamps. La solución fue un relabeling rule en Jsonnet para descartar uno de los endpoints:

{
  prometheusOperator:: {
    prometheus: {
      additionalScrapeConfigs: [{
        job_name: 'kubelet-custom',
        kubernetes_sd_configs: [{role: 'node'}],
        relabel_configs: [{
          source_labels: ['__address__'],
          regex: 'kubelet:10250',
          action: 'drop',
        }],
      }],
    },
  },
}

Este problema, documentado en el blog de Jeff Geerling, afectó al 25% de los clústeres en su muestra de 500 entornos.

Impacto para DevOps / Infraestructura / Cloud / Seguridad

DevOps: La deuda de integración como cuello de botella

Los equipos de DevOps dedican entre el 60% y el 80% de su tiempo a integrar proyectos CNCF, no a desarrollarlos. Según el informe de la CNCF, el 42% de los fallos en producción en clústeres multi-cloud se deben a problemas de integración entre herramientas, no a bugs en las mismas. Esto incluye:

  • Tiempo de resolución de incidentes: Un 35% más lento cuando las herramientas no están pre-integradas.
  • Costo operativo: Cada hora de ingeniería dedicada a integraciones no planificadas cuesta entre $100 y $300 por ingeniero, según datos de CNCF End User Survey 2025.
  • Fragilidad: Las configuraciones manuales (por ejemplo, reglas de relabeling en Prometheus) se pierden en incidentes, y su recuperación requiere horas de debugging.

Cloud: Bloqueo sutil en multi-cloud con CAPI

Antes de Cluster API (CAPI) 1.6.0, provisionar clústeres en AWS, GCP o Azure requería usar herramientas específicas de cada cloud:

  • eksctl para EKS.
  • gcloud container clusters create para GKE.
  • az aks create para AKS.

Cada herramienta tenía su propio modelo de upgrades, recovery y políticas de seguridad. CAPI cambió el paradigma al estandarizar la creación de clústeres como recursos Kubernetes (Cluster, MachineDeployment, MachinePool). Sin embargo, la integración con herramientas como Prometheus o Cilium sigue siendo específica de cloud. Por ejemplo, en AWS, los ServiceMonitors de Prometheus deben apuntar a endpoints con IAM roles específicos (arn:aws:iam::123456789012:role/prometheus-scrape), mientras que en GCP se usan Workload Identity con serviceAccount y políticas de IAM. El CNCF blog destaca que el 70% de los equipos que usan CAPI reportan problemas de permisos al integrar herramientas de observabilidad.

Seguridad: Políticas que se documentan después del incidente

Las políticas de red (Cilium NetworkPolicy) y de cumplimiento (Kyverno, Kubescape) suelen definirse en runbooks post-deploy. Esto genera:

  • Drift de políticas: El 50% de los clústeres sufren cambios no documentados en sus políticas de red, según datos de Kubescape 2025.
  • Auditorías incompletas: Las políticas de TLS, RBAC y red no pueden auditarse desde Git, sino desde estados efímeros del clúster.
  • Exposición a vulnerabilidades: El 30% de los clústeres con políticas definidas en runbooks tienen puertos abiertos innecesarios, según escaneos de Trivy.

Detalles técnicos

Fallas de integración específicas por versión

ComponenteVersión afectadaProblema detectadoVector de ataque / Causa raíz
Cilium1.16.0Métricas de red no scrapeadas por PrometheusFalta de *ServiceMonitor* en Helm chart. Cilium expone métricas en BLOCK35.
Prometheus2.50.1Alertas falsas por BLOCK36kubelet expone métricas duplicadas en BLOCK37 y BLOCK38.
cert-manager1.14.4Renovaciones de certificados fallidas con desafío HTTP-01Ingress controllers redirigen HTTP a HTTPS antes de llegar al pod solver.
cert-manager1.14.4Desafíos DNS-01 requieren configuraciones específicas de IAM en cada cloudRoute53 en AWS necesita permisos BLOCK39.
NGINX Ingress1.10.0Redirige desafíos ACME a HTTPS, rompiendo validaciones HTTP-01Configuración por defecto de BLOCK40.
Cluster API (CAPI)1.6.0Permisos insuficientes para integrar Prometheus con IAM en multi-cloudRoles de IAM no mapeados en BLOCK41 y BLOCK42 CRDs.
### Comandos y configuraciones problemáticas
  1. Falta de ServiceMonitor para Cilium:
   # Este comando no existe en el Helm chart de Cilium 1.16.0 por defecto.
   # Requiere configuración manual en values.yaml:
   cilium:
     prometheus:
       enabled: true
       serviceMonitor:
         enabled: true
   
  1. Renovaciones de certificados fallidas con desafío HTTP-01:
   # values.yaml de cert-manager en EKS
   cert-manager:
     ingressShim:
       defaultIssuerName: letsencrypt-prod
       defaultIssuerKind: ClusterIssuer
       # Esto falla si el ingress controller redirige HTTP a HTTPS:
       defaultACMEChallengeType: http01
   
  1. Relabeling rules para métricas duplicadas de kubelet:
   // En el Jsonnet de Prometheus Operator:
   {
     prometheusOperator:: {
       prometheus: {
         additionalScrapeConfigs: [{
           job_name: 'kubelet-custom',
           kubernetes_sd_configs: [{role: 'node'}],
           relabel_configs: [{
             # Descartar el endpoint /metrics/probes
             source_labels: ['__address__'],
             regex: 'kubelet:10250|/metrics/probes',
             action: 'drop',
           }],
         }],
       },
     },
   }
   

Qué deberían hacer los administradores y equipos técnicos

1. Adoptar un modelo de GitOps de dos repositorios

Dividir la configuración en:

  • Repositorio de plataforma (ej: platform-charts):
– Helm charts con integraciones pre-configuradas (Cilium, Prometheus, cert-manager).

– Policies de red (Cilium NetworkPolicy) y alertas (Prometheus mixins) embebidas.

– Ejemplo de estructura:

    platform-charts/
    ├── cilium/
    │   ├── templates/
    │   │   └── networkpolicy.yaml  # Definiciones de políticas de red
    │   └── values.yaml            # ServiceMonitors para Prometheus
    ├── prometheus/
    │   ├── mixins/
    │   │   ├── velero.libsonnet  # Regla de alerta para backups
    │   │   └── kubelet.libsonnet # Relabeling rules
    │   └── Chart.yaml
    └── cert-manager/
        └── values.yaml            # Configuración de challenges DNS-01 por cloud
    
  • Repositorio de configuración (ej: env-configs):
– Solo valores específicos por clúster (nombre de dominio, IDs de proyectos, roles de IAM).

– Ejemplo:

    # env-configs/production/aws/values.yaml
    cilium:
      # Configuración específica de AWS
      ipam:
        operator:
          clusterPoolIPv4PodCIDR: "10.0.0.0/16"
    cert-manager:
      # Desafíos DNS-01 para AWS
      issuer:
        route53:
          region: us-east-1
          hostedZoneIDs:
            - Z1234567890ABC
    
Pasos accionables:
  1. Crear un repositorio platform-charts con integraciones probadas en staging.
  2. Configurar ArgoCD para sincronizar ambos repositorios:
   # argocd/application.yaml
   apiVersion: argoproj.io/v1alpha1
   kind: Application
   metadata:
     name: platform-charts
   spec:
     source:
       repoURL: https://github.com/org/platform-charts.git
       targetRevision: v1.2.0
       path: .
     destination:
       server: https://kubernetes.default.svc
       namespace: argocd
   
  1. Actualizar el repositorio de configuración para cada nuevo clúster.

2. Automatizar la integración de herramientas

  • Prometheus y Cilium:
– Usar el Kube Prometheus Stack con Helm, pero con un ServiceMonitor pre-configurado en el chart de Cilium:
    # En values.yaml de Cilium:
    prometheus:
      enabled: true
      serviceMonitor:
        enabled: true
        interval: 30s
        scrapeTimeout: 10s
    

– Validar con:

    kubectl get servicemonitor -n kube-system cilium-monitor
    
  • cert-manager:
– Configurar desafíos DNS-01 por defecto en cada cloud:
    # values.yaml de cert-manager
    cert-manager:
      # Para AWS:
      clusterIssuers:
        - name: letsencrypt-prod
          kind: ClusterIssuer
          spec:
            acme:
              solvers:
                - dns01:
                    route53:
                      region: us-east-1
                      accessKeyID: REFERENCE_TO_IAM_KEY
    

– Crear una Secret con las credenciales de IAM cifrada con Sealed Secrets:

    kubeseal --cert=pub-cert.pem --format yaml < cert-manager-route53-secret.yaml > sealed-secret.yaml
    

3. Validar integraciones en staging

  • Pruebas de renovación de certificados:
  # Simular renovación de un certificado en staging:
  kubectl delete secret -n production tls-cert
  kubectl apply -f certificate-staging.yaml
  # Verificar logs de cert-manager:
  kubectl logs -n cert-manager -l app=cert-manager -c cert-manager --tail=50
  
  • Verificación de métricas de Cilium:
  # Consultar métricas de Cilium:
  kubectl port-forward -n kube-system svc/cilium-monitor 9090:9090
  # Acceder a http://localhost:9090/targets y verificar que cilium-agent esté scrapeado.
  
  • Alertas de Prometheus:
– Crear una PrometheusRule para detectar métricas duplicadas:
    # prometheus-rule.yaml
    apiVersion: monitoring.coreos.com/v1
    kind: PrometheusRule
    metadata:
      name: kubelet-duplicate-metrics
    spec:
      groups:
        - name: kubelet.rules
          rules:
            - alert: KubeletDuplicateMetrics
              expr: increase(process_start_time_seconds[5m]) > 1
              for: 5m
              labels:
                severity: warning
    

4. Implementar políticas de red y seguridad como código

  • Cilium NetworkPolicy:
– Definir políticas en los Helm charts de cada aplicación:
    # En values.yaml de una app:
    networkPolicy:
      enabled: true
      egress:
        - to:
            - namespaceSelector:
                matchLabels:
                  name: kube-system
              podSelector:
                matchLabels:
                  k8s-app: kube-dns
          ports:
            - protocol: UDP
              port: 53
    
  • Kyverno:
– Aplicar políticas de recursos por defecto:
    # kyverno-policies.yaml
    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: require-resource-limits
    spec:
      validationFailureAction: enforce
      rules:
        - name: check-limits
          match:
            resources:
              kinds:
                - Pod
          validate:
            message: "Los pods deben tener límites de recursos."
            pattern:
              spec:
                containers:
                  - resources:
                      limits:
                        memory: "?*"
                        cpu: "?*"
    

Conclusión

El «impuesto de integración» no es un problema técnico puntual, sino una deuda que se acumula con cada nuevo proyecto CNCF agregado al stack. Los fallos —desde métricas que no llegan a Grafana hasta renovaciones de certificados fallidas— no aparecen en los repositorios de issues de los proyectos individuales, sino en los espacios entre ellos. La solución no es evitar las integraciones, sino estandarizarlas: usando un modelo de GitOps de dos repositorios, automatizando la configuración de herramientas (Prometheus, Cilium, cert-manager), y validando integraciones en entornos de staging antes de llegar a producción.

La clave está en tratar las integraciones como código: versionadas, auditables y reproducibles. Cuando una configuración de relabeling de Prometheus se corrige en el repositorio de plataforma, esa corrección se propaga a todos los clústeres con un solo PR, sin depender de la memoria humana ni de tickets en Jira. Esto no elimina el trabajo de integración, pero sí lo convierte en un activo mantenible en lugar de un pasivo técnico.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *