Kubernetes Role Base Access Control

Kubernetes Role Base Access Control

Pocas veces se tiene la oportunidad de diseñar un clúster productivo y dentro de las muchas tareas que hay que realizar está la correcta configuración de la autenticación y autorización de los diferentes usuarios del clúster.

En este artículo veremos el flujo por donde pasa una petición de un usuario al invocar un comando usando el CLI de kubectl y cómo logra ésta pasar por los principales mecanismos de seguridad tanto de AWS como de Kubernetes para, finalmente, ejecutarse de manera correcta.

Antes de comenzar, vamos a definir breve e informalmente algunos términos que usaremos.

Autenticación: Es el proceso para saber que el usuario es quien dice ser.

Autorización: Es el proceso para saber si una acción está permitida.

En un futuro artículo hablaremos más sobre estos dos conceptos, pero por ahora con estas definiciones tenemos suficiente para poder seguir el proceso entre AWS y Kubernetes.

Kubernetes

Kubernetes es una plataforma que administra u orquesta de manera semiautomática contenedores tipo Docker para que un servicio esté siempre disponible. Los usuarios interactúan con esta plataforma principalmente a través de 2 formas:

  • La API de Kubernetes
  • El CLI kubectl

Como toda plataforma de administración de recursos, es importante tener un mecanismo de seguridad que nos indique quién puede realizar determinadas acciones y quién no.

Kubernetes está diseñado para ejecutarse en la nube, es decir, dentro de plataformas que proveen infraestructura y herramientas para configurarla. Por esta razón Kubernetes no tiene un sistema de autenticación, sino que delega el proceso de autenticación de un usuario a la plataforma donde vive un clúster. Por otro lado, tiene un gran listado de acciones que puede realizar sobre recursos internos de un clúster. Como estas acciones y recursos son internos de un clúster, le toca a Kubernetes tener un modelo para saber quién puede ejecutar cierta acción sobre algún recurso. El modelo que por defecto usa Kubernetes es el RBAC (Role Based Access Control) el cual usa roles que a su vez se le asignan a los usuarios para determinar el conjunto de acciones permitidas para ese usuario.

Amazon Web Services

Existen varios proveedores de servicios en la nube aunque al día de hoy los más famosos son AWS, GCP y Azure. Por lo regular usamos alguno de éstos para crear nuestro clúster, pero la idea fundamental será la misma sin importar el proveedor de la nube que escojamos.

En este artículo nos centraremos en AWS cuyo servicio de Kubernetes se llama EKS.

Autenticación de un usuario

Para poder entender cómo interactúan el proceso de autenticación y de autorización, veamos el flujo con un ejemplo sencillo. En el siguiente diagrama observamos lo que sucede internamente cuando queremos ejecutar una acción usando el CLI de kubectl:

Para que este flujo pueda ejecutarse correctamente deben existir ciertos requisitos:

  1. Primero hay que configurar correctamente el usuario de AWS. Para esto deben tener las siguientes políticas:
"Action": [
    "eks:AccessKubernetesAPI",
    "eks:DescribeCluster",
    "eks:ListCluster",
],
"Effect": "Allow",
"Resource": [
    "arn:aws:..."
]

Con estos permisos le decimos a AWS que todo aquel que asuma el rol, podrá realizar las acciones listadas en estas reglas.

💡
En el campo Resource debemos insertar el ARN de nuestro clúster.

2. Ahora hay que configurar nuestro CLI kubectl para que pueda comunicarse con nuestro clúster. En este caso como AWS es quien hace la autenticación del usuario, necesitamos hacer que kubectl primero obtenga la información necesaria para acceder al clúster. Afortunadamente, el CLI de AWS nos facilita la tarea enormemente.

Primero hay que asegurarnos de que el CLI esté configurado para asumir el role que estamos usando. Esto va a depender de qué tipo de login hagamos. Normalmente con el siguiente comando debería ser suficiente:

aws configure

Después hay que ejecutar el siguiente comando:

aws eks list-cluster

Esto va a listar los clusters a los que tenemos acceso. Es por eso que necesitamos el permiso de ListClusters en nuestro rol de AWS. Ya que tengamos el nombre del clúster al que nos queremos conectar, hay que configurar kubectl con el siguiente comando:

aws eks update-kubeconfig --name <nombre_del_cluster>
💡
Recuerda cambiar <nombre_del_cluster> por el nombre del clúster que estas usando

Este comando crea una entrada en el archivo ~/.kube/config que indica que para acceder al clúster, se debe obtener un token usando el CLI de AWS. Todo eso pasa de manera automática por lo que no debemos preocuparnos.

Con estos pasos previos, kubectl estará listo para poder comunicarse con nuestro clúster en EKS.

Flujo de autorización

Con el proceso anterior resuelto podemos asegurarnos de que nuestro comando llega al plano de control de nuestro clúster de Kubernetes, pero aún falta que el clúster nos autorice la acción, que en este ejemplo es get pods.

Nuestra petición ya pasó ahora al dominio de Kubernetes que en el caso de AWS se llama EKS.

EKS a través del plano de control primero necesita saber qué permisos tiene el usuario y para lograrlo EKS utiliza un ConfigMap específico llamado aws-auth que contiene una lista de asociaciones entre roles de AWS y usuario o grupos.

apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: <ARN del role>
      username: <usuario_del_cluster>
      groups:
        - <lista_de_grupos>

Los detalles que debemos a tomar en cuenta a la hora de editar este config map:

  • El ARN del role debe tener un formato específico: arn:aws:iam::<cuenta>:role/mi role
  • En username  normalmente indicamos un nombre de usuario para que en logs o registros identifiquemos las acciones que realice dicho usuario.
  • En groups creamos una lista de nombres de grupos. Estos nombre de grupos más tarde los utilizaremos para poder asociar un rol al usuario.

En resumen, lo que hace este ConfigMap es asociar un usuario interno y/o uno o más grupos al usuario cuyo rol de AWS es el especificado en el campo rolearn.

Después, el clúster verifica los RoleBindings registrados para encontrar si alguno está asociando ya sea un usuario o un grupo a un rol.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: mi-rolebinding
  namespace: default
subjects:
- kind: Group
  name: monitoreo
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: role-solo-lectura
  apiGroup: rbac.authorization.k8s.io

Hay que tomar en cuenta que dentro del campo subjets podemos especificar uno o más grupos y/o usuarios y en el campo name debemos poner el nombre del grupo que usamos en el ConfigMap aws-auth .

Finalmente EKS busca el role referido en el RoleBinding ya que dentro vienen definidos los permisos que va a tener dicho rol.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: role-solo-lectura
rules:
- apiGroups: [""]
  resources: ["*"]
  verbs: ["get", "watch", "list"]
- apiGroups: ["apps"]
  resources: ["*"]
  verbs: ["get", "watch", "list"]

Este rol de ejemplo define dos reglas donde en la primera se dan los permisos para ejecutar las acciones get, watch y list para todos los recursos del apiGroup por defecto (pods principalmente). En la segunda se da el mismo permiso pero para el apiGroup apps donde normalmente encontramos los Deployments.

Cuando EKS encuentra el rol correcto asociado puede ya decidir si realizar la acción solicitada por el usuario, en este caso get pods .

💡
En los roles de Kubernetes no hay deny por lo que todas las reglas son aditivas, es decir, siempre agregan algún permiso.

Recapitulemos

  • kubectl usa el CLI de AWS para poder asumir un rol de AWS. Este es el proceso de autenticación.
  • El role de AWS debe tener permisos para poder usar EKS
  • Dentro del clúster deben existir 3 elementos que se usan para el proceso de autorización:

1. La asociación del AWS role con un grupo en el ConfigMap aws-auth.

2. Un RoleBinding que asocie un grupo o usuario con un Role.

3. Un Role que contenga los permisos que queremos que un grupo o usuario tenga.

Hay que recordar que dentro de Kubernetes los Roles y RoleBindings aplican a un namespace particular. Sin embargo, también existen los ClusterRoles y ClusterRoleBindings que, a diferencia de los anteriores, aplican las reglas de autorización a nivel de clúster.

¡Hasta la próxima!

⚠️
Las opiniones y comentarios emitidos en este artículo son propiedad única de su autor y no necesariamente representan el punto de vista de Revelo.

Revelo Content Network da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.