Certificados en Kubernetes

Certificados en Kubernetes

En un entorno de clusters dinámicos como Kubernetes, la seguridad de las comunicaciones es fundamental. Los certificados digitales son clave a la hora de garantizar la autenticación y el cifrado de las comunicaciones entre los distintos componentes del cluster (como el API Server, etcd, kubelet, etc.) y entre las aplicaciones que se ejecutan sobre él. A continuación profundizaré en cómo funcionan los certificados en Kubernetes, cómo se gestionan y se renuevan, e incluiré ejemplos prácticos de implementación.


1. Introducción y relevancia de los certificados en Kubernetes

¿Por qué son necesarios los certificados?

Los certificados TLS aseguran que los datos transmitidos entre componentes o aplicaciones estén cifrados, protegiéndolos de posibles ataques de intermediarios (Man-in-the-Middle). Asimismo, permiten verificar la identidad de los servidores y clientes, de modo que cada parte se asegure de estar comunicándose con entidades legítimas (autenticidad). Además, garantizan que la información no ha sido alterada durante la transmisión (integridad).

En Kubernetes, estos certificados se utilizan tanto para la comunicación interna entre los componentes del clúster como para la exposición segura de aplicaciones a usuarios finales (por ejemplo, en Ingress Controllers).

2. Componentes de Kubernetes que utilizan certificados

2.1 Componentes internos

En un clúster de Kubernetes, numerosos componentes internos utilizan certificados para asegurar la autenticidad, integridad y confidencialidad de las comunicaciones. A continuación se describen los principales componentes, junto con detalles sobre la ubicación de sus certificados en una instalación típica basada en kubeadm y consideraciones adicionales:

kube-apiserver

El kube-apiserver es el punto central de entrada al clúster. Es el responsable de exponer la API de Kubernetes y se encarga de cifrar las comunicaciones con clientes, kubelets y otros componentes. En una instalación estándar con kubeadm, los certificados del API server se encuentran en la carpeta /etc/kubernetes/pki. Por ejemplo, el certificado principal suele estar en /etc/kubernetes/pki/apiserver.crt y su clave privada en /etc/kubernetes/pki/apiserver.key. Además, el archivo /etc/kubernetes/pki/apiserver-kubelet-client.crt se utiliza para autenticar las conexiones del kubelet hacia el API server.

etcd

El almacén de datos distribuido etcd guarda la configuración y el estado del clúster, siendo crítico proteger su acceso. Para ello, etcd se configura con certificados TLS que aseguran que solo componentes autorizados puedan comunicarse con él. En una instalación gestionada con kubeadm, los certificados de etcd se ubican en el directorio /etc/kubernetes/pki/etcd. Aquí se pueden encontrar archivos como server.crt, peer.crt y healthcheck-client.crt, cada uno con su correspondiente clave privada, que protegen las comunicaciones tanto entre nodos del clúster etcd como las conexiones desde el API server.

kubelet

Cada nodo del clúster ejecuta un kubelet, que es el agente responsable de la ejecución de pods y de la comunicación con el API server. El kubelet utiliza certificados para autenticarse ante el API server. En instalaciones basadas en kubeadm, el certificado de cliente del kubelet generalmente se encuentra en /var/lib/kubelet/pki/kubelet-client-current.pem. Además, el kubelet puede generar certificados autofirmados para la comunicación interna, y en entornos configurados para rotación automática, estos certificados se actualizan de forma periódica.

kube-controller-manager

El kube-controller-manager es el componente que se encarga de ejecutar los controladores que gestionan el estado del clúster. Para comunicarse de forma segura con el API server, utiliza certificados que, en una instalación kubeadm, se ubican en /etc/kubernetes/pki/controller-manager.crt (y su clave privada en controller-manager.key). Este certificado se utiliza para autenticar las solicitudes que el controller-manager realiza al API server, garantizando que solo un componente autorizado pueda modificar el estado del clúster.

kube-scheduler

El kube-scheduler asigna los pods a los nodos disponibles según las políticas y la carga de trabajo. Al igual que otros componentes, el scheduler necesita autenticarse ante el API server utilizando un certificado. En instalaciones estándar, el certificado del scheduler se encuentra en /etc/kubernetes/pki/scheduler.crt. Este certificado garantiza que las decisiones de asignación de pods se realicen de manera segura y que la comunicación entre el scheduler y el API server esté cifrada.

kube-proxy

El kube-proxy se encarga de implementar las reglas de red en cada nodo para permitir la comunicación entre pods y servicios. Aunque su comunicación se gestiona principalmente mediante el uso de un kubeconfig, dicho archivo incluye referencias a certificados para la autenticación. Por lo general, en instalaciones basadas en kubeadm, estos certificados se almacenan en ubicaciones definidas en el kubeconfig (a menudo en /var/lib/kube-proxy o referenciados desde /etc/kubernetes/pki), permitiendo que el kube-proxy se comunique de forma segura con el API server y garantizando que solo entidades autorizadas puedan influir en el tráfico de red.

cloud-controller-manager

El cloud-controller-manager integra el clúster con el proveedor de nube subyacente en caso de existir. Este componente utiliza certificados para autenticar las conexiones tanto con el API server como con las API del proveedor de servicios en la nube. Dependiendo de la configuración y del entorno, los certificados utilizados por el cloud-controller-manager pueden almacenarse en rutas similares a las de los otros componentes del plano de control, por ejemplo, en /etc/kubernetes/pki, o en rutas definidas por la configuración específica del proveedor.

Otros componentes y consideraciones adicionales

Además de los componentes mencionados, otros elementos como los webhook de admisión (tanto mutating como validating) pueden requerir certificados propios para establecer conexiones seguras. Estos certificados suelen estar configurados en las definiciones de recursos personalizados y se almacenan en objetos Secret o en rutas definidas por el administrador. Del mismo modo, componentes adicionales que integren servicios externos o que sean parte de extensiones (como el aggregator para extender la API de Kubernetes) también requieren el uso de certificados, cuya ubicación y manejo dependerán de la configuración específica del clúster y de la herramienta utilizada para su despliegue.

2.2 Componentes expuestos externamente

Ingress Controllers

Cuando se desea exponer aplicaciones al exterior, los Ingress Controllers juegan un papel fundamental. Estos controladores actúan como puertas de enlace que permiten redirigir el tráfico de Internet a los servicios internos del clúster, garantizando al mismo tiempo que la comunicación se realice de forma segura a través de HTTPS. Para ello, se instalan certificados en el Ingress Controller, lo que posibilita el cifrado de las conexiones entrantes. En una configuración típica, un Ingress Controller basado en NGINX o Traefik utiliza un objeto Ingress para definir las reglas de enrutamiento y especificar el Secret que contiene el certificado y la clave privada. Por ejemplo, cuando se configura un Ingress para un dominio personalizado, se incluye en el manifiesto la referencia al ClusterIssuer que automatiza la solicitud del certificado mediante herramientas como cert-manager. Esto permite que, en un entorno de producción, el Ingress presente un certificado válido y confiable, ya sea emitido por una CA reconocida como Let's Encrypt o por una CA privada. Además, es común que estos controladores tengan mecanismos de rotación y actualización automática de certificados, de modo que, si un certificado se acerca a su fecha de expiración, se solicite uno nuevo sin interrumpir el servicio.

Aplicaciones y servicios

En cuanto a las aplicaciones y servicios, es frecuente que requieran la utilización de certificados no solo para exponer endpoints a clientes externos, sino también para asegurar la comunicación interna entre distintos microservicios. En un escenario de mTLS (mutual TLS), cada servicio dispone de su propio certificado, lo que garantiza que tanto el cliente como el servidor se autentiquen mutuamente antes de establecer la conexión. Esta estrategia es especialmente útil en arquitecturas de microservicios, donde la seguridad de la comunicación entre aplicaciones es esencial para prevenir accesos no autorizados y garantizar la integridad de los datos. La implementación de mTLS se puede llevar a cabo utilizando herramientas que gestionen automáticamente la emisión y renovación de certificados, integrándose de forma nativa con el entorno de Kubernetes a través de recursos como Issuer o ClusterIssuer. Por ejemplo, un servicio A que se comunica con un servicio B validará el certificado presentado por B y, a su vez, B comprobará el de A, asegurando así una comunicación bidireccional cifrada y autenticada.

3. Gestión y ciclo de vida de certificados en Kubernetes

Gestión interna con kubeadm

Cuando se crea un clúster con kubeadm, este se encarga de generar certificados autofirmados para los distintos componentes. Además, kubeadm incluye funcionalidades de rotación automática de certificados, lo que garantiza que los certificados se renueven antes de expirar.

Uso de la API CSR (CertificateSigningRequest)

Kubernetes provee una API nativa para gestionar solicitudes de firma de certificados (CSR).
Ejemplo de uso:

# Solicitar la aprobación de un CSR creado
kubectl certificate approve <nombre-del-csr>

Con este mecanismo, administradores o procesos automatizados pueden revisar y aprobar solicitudes de certificados emitidos por clientes o componentes internos.

Automatización con cert-manager

Para aplicaciones y cargas de trabajo que requieren certificados TLS, una herramienta muy utilizada es cert-manager. Este operador automatiza:

  • La solicitud y emisión de certificados (por ejemplo, a través de Let's Encrypt).
  • La distribución de certificados en forma de objetos Secret dentro del clúster.
  • La renovación automática de los certificados antes de que expiren.

Con cert-manager se pueden definir recursos personalizados como Issuer o ClusterIssuer y Certificate para gestionar de forma declarativa el ciclo de vida de los certificados.

4. Ejemplos prácticos con cert-manager

A continuación se muestran ejemplos de configuración para automatizar la emisión de certificados usando cert-manager.

4.1. Creación de un ClusterIssuer para Let's Encrypt

El objeto ClusterIssuer es un recurso de ámbito global que permite emitir certificados para cualquier namespace. En este ejemplo se utiliza el servidor ACME en modo staging para pruebas.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: tu-email@dominio.com
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
    - http01:
        ingress:
          class: nginx
Nota importante: Para producción, se debe utilizar el servidor de Let's Encrypt en producción (https://acme-v02.api.letsencrypt.org/directory).

4.2. Definición de un recurso Certificate

Una vez creado el ClusterIssuer, se puede definir un objeto Certificate que especifica el dominio para el que se requiere el certificado y el Secret donde se almacenará.

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: ssl-cert-production
  namespace: default
spec:
  secretName: ssl-cert-production
  issuerRef:
    name: letsencrypt-production  # O 'letsencrypt-staging' para pruebas
    kind: ClusterIssuer
  commonName: "tudominio.nip.io"
  dnsNames:
  - "tudominio.nip.io"

Una vez aplicado este manifiesto con kubectl apply -f certificate-production.yaml, cert-manager se encargará de solicitar el certificado a Let's Encrypt y guardarlo en el Secret ssl-cert-production.

4.3. Integración con Ingress

Para que una aplicación expuesta a través de un Ingress utilice el certificado emitido, se debe configurar el recurso Ingress de la siguiente manera:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: default
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-production
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - "tudominio.nip.io"
    secretName: ssl-cert-production
  rules:
  - host: "tudominio.nip.io"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80

Al aplicar este manifiesto, cert-manager vinculará el certificado al Ingress. Cuando un cliente acceda a "https://tudominio.nip.io", se establecerá una conexión segura utilizando el certificado emitido.

5. Buenas prácticas y consideraciones de seguridad

La seguridad en la gestión de certificados dentro de Kubernetes va más allá de la simple emisión o renovación; implica una serie de medidas integrales que aseguran tanto la autenticidad como la confidencialidad de las comunicaciones. Es fundamental comprender que cada paso del proceso, desde la rotación de los certificados hasta la auditoría de los accesos, debe abordarse con un enfoque sistemático y preventivo para evitar interrupciones en el servicio y posibles vulnerabilidades.

En primer lugar, resulta esencial contar con un mecanismo automatizado para la rotación y renovación de certificados. Dado que cada certificado posee un período de validez limitado, su renovación oportuna es crucial para evitar interrupciones que puedan afectar la disponibilidad de las aplicaciones. Herramientas como kubeadm y cert-manager ofrecen soluciones automáticas que permiten programar la renovación de certificados de forma anticipada. Además, se recomienda implementar mecanismos de monitoreo que alerten a los administradores cuando un certificado esté próximo a expirar, permitiendo actuar de forma preventiva y evitar que los servicios queden expuestos a conexiones no seguras.

Ejemplo con kubeadm

Si tu clúster fue creado y se gestiona mediante kubeadm, puedes utilizar comandos integrados para revisar el estado de los certificados y renovarlos de manera automática.

Para verificar la fecha de expiración de los certificados, ejecuta:

kubeadm certs check-expiration

Este comando mostrará información similar a la siguiente, indicando la fecha de expiración y el tiempo residual para cada certificado:

CERTIFICATE                EXPIRES              RESIDUAL TIME
admin.conf                 2025-06-01T00:00:00Z  10d
apiserver                  2025-06-01T00:00:00Z  10d
apiserver-kubelet-client   2025-06-01T00:00:00Z  10d
...

Si observas que algún certificado está próximo a expirar, puedes renovar todos los certificados ejecutando:

kubeadm certs renew all

Una vez renovados, recuerda reiniciar los componentes afectados (como el kube-apiserver o los kubelets) si es necesario para que se apliquen los nuevos certificados.

Ejemplo con cert-manager

En entornos donde se gestionan certificados para aplicaciones expuestas a través de Ingress o para servicios internos, cert-manager automatiza la solicitud y renovación de certificados. Por ejemplo, supongamos que has definido un objeto Certificate que solicita un certificado a través de un ClusterIssuer para un dominio específico.

Podrías tener un manifiesto similar a este:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: ssl-cert-production
  namespace: default
spec:
  secretName: ssl-cert-production
  issuerRef:
    name: letsencrypt-production  # Se refiere a un ClusterIssuer previamente configurado
    kind: ClusterIssuer
  commonName: "tudominio.nip.io"
  dnsNames:
  - "tudominio.nip.io"
  renewBefore: 240h  # Inicia la renovación 10 días antes de la expiración

En este caso, cert-manager se encargará de solicitar automáticamente el certificado a Let's Encrypt y lo almacenará en el Secret ssl-cert-production. La clave aquí es el campo renewBefore, que indica que la renovación se debe iniciar 10 días (240 horas) antes de la expiración, permitiendo así actuar de forma preventiva.

Para verificar el estado del certificado y conocer detalles de su proceso de renovación, puedes usar:

kubectl describe certificate ssl-cert-production -n default

Este comando mostrará información sobre el estado actual, eventos y condiciones del certificado, lo que te ayudará a confirmar que la renovación se ha iniciado o se ha completado correctamente.

Ejemplo de Monitorización con Prometheus

Para evitar que los servicios queden expuestos debido a certificados expirados, es recomendable implementar alertas. Si utilizas Prometheus para la monitorización, podrías configurar una regla de alerta. Por ejemplo:

groups:
- name: cert-manager-alerts
  rules:
  - alert: CertificateExpiringSoon
    expr: certmanager_certificate_not_after_seconds{namespace="default"} - time() < 86400 * 10
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "El certificado {{ $labels.name }} en el namespace {{ $labels.namespace }} expira pronto"
      description: "El certificado expira en menos de 10 días. Por favor, revisa la renovación y toma las acciones necesarias."

Esta regla alerta cuando el tiempo restante para la expiración del certificado es inferior a 10 días. De esta forma, los administradores pueden recibir notificaciones y actuar de forma preventiva antes de que se produzca cualquier interrupción en el servicio.

Otras consideraciones

Otro aspecto vital es la forma en que se almacenan y protegen los certificados y, en particular, las claves privadas asociadas. Dado que estas claves son el elemento central que permite la autenticación de los componentes del clúster, es imperativo que se almacenen de manera segura. En Kubernetes, esta información se guarda en objetos de tipo Secret, pero la seguridad de estos objetos depende en gran medida de una correcta configuración de los controles de acceso. Es necesario aplicar políticas de Control de Acceso Basado en Roles (RBAC), de modo que únicamente los componentes y usuarios autorizados tengan la posibilidad de leer o modificar estos secretos. Además, se recomienda que los secretos se almacenen cifrados en reposo, especialmente en la base de datos etcd, de manera que si se llegara a acceder a ella de forma no autorizada, la información sensible permanezca protegida.

La elección de la Autoridad de Certificación (CA) es también especialmente relevante en la seguridad de las comunicaciones. Mientras que los certificados autofirmados pueden resultar adecuados en entornos de desarrollo o pruebas, en entornos productivos es preferible utilizar una CA reconocida o, en su defecto, implementar una CA privada interna que cumpla con los estándares de seguridad requeridos. La integración con servicios externos como Let's Encrypt, AWS Private CA u otras soluciones de CA permite no solo la emisión automatizada de certificados, sino también la garantía de que estos cumplen con los requisitos normativos que muchas industrias exigen. Es importante evaluar y validar que la CA seleccionada se alinee con las políticas internas y con las normativas de seguridad vigentes en el entorno operativo.

La monitorización constante de los certificados y el seguimiento de sus estados constituye otra práctica esencial para mantener la seguridad del clúster. Es conveniente disponer de herramientas que permitan la visualización en tiempo real del estado de todos los certificados, ya sean internos o aquellos utilizados para exponer servicios a usuarios externos. La revisión periódica de los eventos asociados a los objetos Certificate, Issuer o Ingress ayuda a identificar posibles problemas en la emisión o en la renovación de certificados. Asimismo, la implementación de un sistema centralizado de registros y auditorías, que almacene el historial de cambios y accesos a los secretos, resulta invaluable para detectar actividades inusuales y para realizar análisis forenses en caso de incidentes.

En cuanto a la exposición de aplicaciones mediante Ingress Controllers, es fundamental que la configuración del Ingress se realice de forma cuidadosa y que se vincule de manera adecuada el certificado emitido. Esto implica definir en el manifiesto del Ingress tanto el nombre del ClusterIssuer utilizado como el nombre del Secret en el que se almacena el certificado. De esta forma, se garantiza que cuando un usuario externo acceda a la aplicación mediante HTTPS, el certificado presentado sea el correcto y esté respaldado por una cadena de confianza completa. Para corroborar que la configuración es la adecuada, se recomienda realizar pruebas de conectividad utilizando herramientas como curl o el modo de inspección de los navegadores, verificando que la conexión establecida utiliza el certificado esperado y que la autenticación se realiza correctamente.

Finalmente, la seguridad en la gestión de certificados debe integrarse en el ciclo de vida completo de las aplicaciones, desde el desarrollo hasta la operación. Es importante que los equipos de desarrollo, operaciones y seguridad trabajen de forma conjunta para incorporar controles de seguridad en cada etapa del proceso. La integración de validaciones de seguridad en los pipelines de CI/CD permite detectar configuraciones inseguras antes de que los cambios se propaguen a entornos productivos. Del mismo modo, la realización de auditorías periódicas y la capacitación continua del personal contribuyen a mantener una cultura de seguridad robusta, donde cada miembro del equipo es consciente de la importancia de proteger la infraestructura y las comunicaciones.

Read more