Kubernetes: Operador vs. Controller
Introducción
Durante las pasadas semanas he estado intentar comprender mejor qué es un Operador de Kubernetes y especialmente qué lo diferencia de un Kubernetes Controller. Hay diversas convenciones y bastante documentación , pero poco clara, acerca de ambos términos y supongo que habrá más de uno o una que tenga también cierta confusión. En este post intentaré resumir qué implica cada uno de estos patrones y enumeraré algunos ejemplos que los ilustran.
Controllers
La documentación de Kubernetes sobre controllers comienza dando una breve definición sobre control loop (circuito de control), esto es lo que la entrada en Wikipedia dice acerca de este término:
Un circuito de control es el componente fundamental de los sistemas de control industrial. Se refiere a todos los componentes físicos y funciones de control necesarios para ajustar automáticamente el valor de una variable de proceso medida (PV) para igualar el valor de un punto de ajuste deseado (SP).
De este modo, en el mundo de Kubernetes, un Controller básicamente monitoriza y mide el estado de un recurso en el cluster para ajustar aquellos parámetros que divergen del estado deseado.
De acuerdo con esta definición, cualquier proceso que automatice esta tarea y lleve el estado general del cluster a un estado deseado definido recae en esta categoría y se puede considerar un Controller.
Los ejemplos habituales en Kubernetes son los Controllers ReplicaSet
, StatefulSet
y DaemonSet
. En estos recursos, su spec
incluye una campo para definir el número de replicas deseado. El Controller se encarga de suministrar tantos Pods
como se hayan definido en este spec
mediante su creación o destrucción al tiempo que monitorizan los recursos Pod
del cluster.
Asimismo, se me ocurren una serie de ejemplos que no pueden parecer tan claros en un principio, pero que también ejemplifican el patrón Controller. Por ejemplo, un Controllador bastante simple que se encarge de que todos los Pod
s incluyan una anotación controlled-by: dumb
también formaría parte de esta categoría. El Controller monitoriza los Pod
s del cluster y automáticamente añade la anotación cuando se cree o modifique (para el caso en que otro proceso haya quitado la anotación) un Pod
. Así el estado deseado es que todos los Pod
s incluyan esta simple anotación.
Otro ejemplo podría ser un Controler para asegurarse de que ningún Service
es de tipo NodePort
. El Controller monitoriza los recursos Service
y elimina aquellos Service
que se hayan creado o modificado para ser de tipo NodePort
. En este caso, el estado deseado es que no haya ningún servicio expuesto como NodePort
(por ejemplo por razones de seguridad).
Operadores
El término Operador es el más confuso para mí ya que emplea la misma terminología que se utiliza para referirse a un rol humano dentro del sector de las TI. La propia documentación de Kubernetes expone lo siguiente:
El patrón de Operadores trata de capturar el propósito de un operador humano que gestiona un servicio o un conjunto de servicios.
Sin embargo, el término se acuñó originalmente por la organización CoreOS con un significado muy específico:
Un Operador es un método de empaquetado, despliegue y gestión de una aplicación Kubernetes.
Es más, la documentación de Kubernetes enuncia una serie de requisitos para que un Controller pueda caer en la categoría del patrón de Operadores.
- Los Operadores utilizan el patrón de Controllers.
- Los Operadores utilizan Custom Resources para extender la API de Kubernetes.
- Los Operadores se centran en una única aplicación y sus componentes.
En la actualidad podemos encontrar muchos Operadores disponibles públicamente para poder aprovisionar aplicaciones en tu Cluster. Por ejemplo, el Strimzi Operator proporciona una forma de ejecutar o desplegar un cluster Apache Kafka en OpenShift o Kubernetes. Este es un claro ejemplo de un Operador ya que no sólo se encarga de automatizar el proceso de instalación de un cluster Kafka, sino también de gestionar y monitorizar el cluster desplegado.
Conclusión
Mi visión personal es que los Controllers son cualquier proceso que lleva o acerca los recursos desplegados en un cluster desde un estado actual a un estado deseado. En este sentido, podríamos decir que los Operadores son Controllers que emplean Custom Resources para gestionar el estado de una única aplicación y sus componentes.
Otro de los puntos clave es que ambos conceptos representan patrones
y no requieren de soluciones específicas implementadas en un lenguaje o framework. Para implementar un Controller o un Operador es necesario que sigas una convención, pero eres libre de emplear un lenguaje o herramientas de tu elección. El uso de un framework o SDK te puede ayudar y por supuesto evitará que tengas que reescribir mucho código repetitivo, pero insisto, nada te impide implementar una solución desde cero, siempre y cuando lo hagas siguiendo la especificación del patrón y sus directrices.