Skip to main content

Por qué necesitas un controlador de admisión de Kubernetes

Escrito por
Headshot of Chris Laux

Chris Laux

Kubernetes Blog

25 de abril de 2022

0 minutos de lectura

Si no tienes experiencia como operador o administrador de Kubernetes, es posible que los controladores de admisión sean una novedad para ti. Estos controladores funcionan principalmente en segundo plano y muchos están disponibles como complementos compilados en el sistema, pero pueden contribuir de manera significativa a la seguridad de una implementación.

Los controladores de admisión interceptan las solicitudes a la API antes de que lleguen al servidor de la API, y pueden rechazarlas o modificarlas. Esto se aplica a la mayoría de los tipos de solicitudes de Kubernetes, excepto a las solicitudes de solo lectura, que los controladores no procesan. Los controladores de admisión manejan las solicitudes después de que se hayan autenticado y autorizado correctamente.

Esta publicación explica por qué conviene incluir controladores de admisión de Kubernetes. También destaca las ventajas de conocer mejor su funcionamiento.

Varios controladores de admisión están habilitados de forma predeterminada porque la mayoría de las operaciones habituales de Kubernetes depende de ellos. La mayoría forman parte del árbol de código fuente de Kubernetes y se compilan como complementos. Sin embargo, también es posible programar e implementar controladores de admisión de terceros. Más adelante veremos algunos ejemplos. Para conocer más detalles sobre cómo implementar controladores de admisión, consulta la documentación de Kubernetes.

Controladores de admisión predeterminados

Kubernetes incluye varios controladores de admisión integrados. Un ejemplo sencillo, DefaultIngressClass, asigna la clase de entrada predeterminada a los objetos de entrada que aún no tienen una clase especificada. De manera similar, DefaultStorageClass asigna la clase de almacenamiento predeterminada a los PersistentVolumeClaims que aún no tienen una. Este controlador debe estar habilitado para permitir el aprovisionamiento dinámico de almacenamiento según la clase de almacenamiento.

Los controladores de admisión pueden ser muy útiles para mantener la seguridad. Por ejemplo, pueden mitigar ataques de denegación de servicio (DoS) en clústeres multiinquilino. Considera el complemento LimitRanger, que, como su nombre indica, aplica rangos de límites. Estos rangos definen los límites obligatorios de consumo de recursos por espacio de nombres. Así se evita que los inquilinos agoten los recursos de los demás.

Otro problema es la llamada inundación de eventos, en la que el clúster se satura de eventos y no puede gestionar adecuadamente otras solicitudes legítimas. El controlador EventRateLimit es una herramienta eficaz para mitigar estas situaciones. Su diseño permite limitar la tasa de eventos por espacio de nombres o por usuario.

Además, hay dos controladores importantes que permiten a los desarrolladores ejecutar sus complementos de admisión como webhooks configurables en tiempo de ejecución. MutatingAdmissionWebhook permite que los webhooks modifiquen los recursos enviados y suele usarse para aplicar valores predeterminados personalizados. Por su parte, el controlador ValidatingAdmissionWebhook permite que los webhooks registrados decidan si un recurso validado por la API, en su estado final, continúa el proceso o se descarta por completo.

Propósito de los controladores

La forma original de ejecutar varios servicios en una máquina física consistía en tener máquinas virtuales que compartían el mismo host, con un hipervisor que separaba sus sistemas operativos. Un sistema complejo de configuraciones en la nube —por ejemplo, las que define AWS— mantenía los sistemas separados y garantizaba que los inquilinos no pudieran perjudicarse entre sí, de manera accidental o intencional.

Al principio, Kubernetes se diseñó como un sistema colaborativo que podía usar una sola organización o usuario. Además, dependía mucho más de la consideración mutua que otros sistemas en la nube. Sin embargo, a medida que Kubernetes amplía la variedad de implementaciones disponibles y su capacidad para manejar clústeres más grandes, es cada vez más importante establecer políticas que garanticen que un solo usuario no pueda interferir con el funcionamiento del sistema.

Para automatizar este proceso, las organizaciones necesitan un sistema de políticas. Kubernetes incluye ciertas funciones integradas, pero no tiene la capacidad de un motor de políticas dedicado y completo.

Motores de políticas externos

Hay dos motores de políticas de código abierto líderes para Kubernetes: Open Policy Agent (OPA) Gatekeeper y Kyverno.

Ambos motores son proyectos donados a la Cloud Native Computing Foundation (CNCF), dedicada a estandarizar y promover las tecnologías nativas de la nube. La CNCF opera bajo su organización matriz, la Linux Foundation. Cabe destacar que Kubernetes es un proyecto de la CNCF.

La principal ventaja de Kyverno es que no requiere aprender otro lenguaje. Todas sus políticas se definen como recursos de Kubernetes. En cambio, Gatekeeper aprovecha el lenguaje declarativo de OPA, Rego. Gatekeeper forma parte del ecosistema más amplio de OPA, mientras que Kyverno es un proyecto independiente para Kubernetes. En resumen, Gatekeeper es el proyecto más maduro, pero Kyverno tiene una curva de aprendizaje menor.

Tu controlador de admisión personalizado

Puedes usar webhooks para programar la lógica de un controlador de admisión personalizado en cualquier lenguaje capaz de gestionar solicitudes HTTP y devolver JavaScript Object Notation (JSON). Go, Python y Ruby, por ejemplo, son opciones válidas.

El siguiente ejemplo muestra cómo configurar un webhook para un controlador de admisión personalizado. Es similar al LimitRanger presentado anteriormente, que rechaza las solicitudes de pods que superan los límites de recursos del espacio de nombres. Ten en cuenta que este ejemplo no incluye todo el código fuente del controlador, pero puedes consultar la documentación de Kubernetes sobre servidores de webhooks de admisión para conocer el proceso en profundidad.

Primero, registra el webhook con un objeto de configuración:

apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
  name: mywebhook
webhooks:
  - name: mywebhook
    clientConfig:
      service:
        name: mywebhook
        namespace: project1
        path: "/hook"
    rules:
      - operations: ["CREATE"]
        apiVersions: ["v1"]
        apiGroups: [""]
        resources: ["pods"]

Esto informa al ValidatingWebhookController sobre el webhook. También especifica a qué servicio acceder y qué ruta consultar en el contenedor que ejecuta el servidor. Además, identifica qué reglas aplicar para decidir si se invoca el webhook. Este ejemplo se centra en la creación de pods nuevos.

En la práctica, este recurso se crearía en el clúster al final, después de crear una implementación para el servidor del webhook. La implementación incluye un servicio que coincide con la definición del archivo anterior:

apiVersion: v1
kind: Service
metadata:
  name: mywebhook
  namespace: project1
spec:
  - ports:
      name: mywebhook
      port: 80
      targetPort: 8000

A continuación, se muestra una implementación de ejemplo de un webhook, igual que la de una aplicación normal. No veremos cómo proteger las comunicaciones con seguridad de la capa de transporte (TLS), aunque se recomienda hacerlo encarecidamente.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mywebhook
  namespace: project1
spec:
  selector:
    matchLabels:
      app: mywebhook
  template:
    metadata:
      labels:
        app: mywebhook
    spec:
      containers:
        - image: webhook1:latest
          name: mywebhook

Después de que se envía a Kubernetes una solicitud para crear un pod nuevo y el ValidatingWebhook la aprueba, la información pertinente se envía como una solicitud POST a la ruta URL configurada e incluye un objeto JSON que el webhook debe procesar. Para validar la solicitud de manera afirmativa, devuelve una respuesta similar a la siguiente, junto con un código de estado 200 OK:

{
  "apiVersion": "admission.k8s.io/v1",
  "kind": "AdmissionReview",
  "response": {
    "uid": "6ce7a33c-ea67-40e5-9cc8-f710d31985dc",
    "allowed": true
  }
}

El campo uid se obtiene de la solicitud para relacionar las solicitudes con las respuestas. Para impedir que se cree el pod, el campo allowed debe establecerse en false y debe enviarse un código de error HTTP.

Un controlador de admisión personalizado puede ser tan sencillo como el de este ejemplo o mucho más complejo. Para obtener una descripción más detallada, consulta la información de la documentación de webhooks de admisión.

Conclusión

Un controlador de admisión de Kubernetes puede modificar o rechazar solicitudes al servidor de la API antes de que el objeto se guarde. Kubernetes incluye numerosos controladores versátiles, entre ellos varios complementos precompilados y dos tipos de webhooks de control de admisión. Sin embargo, programar webhooks y controladores propios puede ofrecer mayor flexibilidad y un control más preciso.

Los controladores de admisión y los webhooks permiten que los proyectos ofrezcan motores de políticas como OPA Gatekeeper y Kyverno. Además, es fácil implementar un sistema de admisión personalizado mediante webhooks habilitados para HTTP en cualquier lenguaje que pueda responder a solicitudes HTTP con una carga JSON.

En general, los controladores de admisión son solo un componente de una estrategia integral de seguridad de Kubernetes. Existen riesgos y vulnerabilidades en cada etapa del ciclo de vida del desarrollo de software, pero mitigarlos no tiene por qué interrumpir todo el flujo de trabajo. Una organización enfocada en la seguridad puede aportar información valiosa para ayudarte a encontrar el tipo de experiencia adecuado.

Seguridad de IaC diseñada para desarrolladores

Snyk protege tu infraestructura como código desde el ciclo de vida del desarrollo de software hasta el runtime en la nube con un motor unificado de políticas como código, para que todos los equipos puedan desarrollar, implementar y operar de forma segura.


Chris Laux ha desarrollado software durante más de 20 años en distintos lenguajes de programación.

Publicado en:

Leer más

Article

Versiones maliciosas de node-ipc publicadas en npm tras una presunta toma de control de la cuenta de un mantenedor

El 14 de mayo de 2026, se publicaron varias versiones maliciosas del popular paquete npm node-ipc en el registro de npm. Los informes públicos actuales identifican node...

blog feature toolkit
Blog

Publicación maliciosa del paquete elementary-data en PyPI roba credenciales en la nube de ingenieros de datos

Los atacantes aprovecharon una vulnerabilidad de inyección de scripts en GitHub Actions para publicar una versión maliciosa de la CLI de Python elementary-data (v0.23.3), que incluía una puerta trasera para robar credenciales de perfiles de dbt, claves de proveedores de nube y secretos SSH en entornos de ingeniería de datos.

Blog

Integrar la seguridad en cada commit: el futuro de Snyk Secrets

Snyk Secrets conecta el código con las credenciales mediante detección en tiempo real y de alta precisión, para mantener ocultos tus datos más confidenciales sin frenar el ritmo de tus desarrolladores.