RBAC role-based access control

RBAC (Role-Based Access Control) es un sistema de control de acceso en Kubernetes que permite a los administradores gestionar el acceso a los recursos del clúster de forma granular, basada en roles. Con RBAC, puedes definir quién puede hacer qué en el clúster, estableciendo permisos específicos para diferentes usuarios, aplicaciones y servicios.

Aquí tienes una introducción a los conceptos principales de RBAC en Kubernetes:

Conceptos Básicos de RBAC en Kubernetes

  1. Roles y RoleBindings:

    • Role: Define un conjunto de permisos (acciones permitidas) en un solo namespace. Un Role especifica las acciones que se pueden realizar sobre ciertos recursos (por ejemplo, pods, servicios) dentro de ese namespace.
    • RoleBinding: Asocia un Role a un usuario, grupo o cuenta de servicio específico dentro de un namespace. Esto permite que los sujetos vinculados realicen las acciones definidas en el Role en ese namespace.
  2. ClusterRoles y ClusterRoleBindings:

    • ClusterRole: Define permisos a nivel de clúster o permisos que pueden aplicarse a recursos no específicos de un namespace. A diferencia de Role, un ClusterRole puede otorgar acceso a todos los namespaces o a recursos globales del clúster.
    • ClusterRoleBinding: Asocia un ClusterRole a un usuario, grupo o cuenta de servicio a nivel de clúster. Esto permite que los sujetos vinculados realicen las acciones definidas en el ClusterRole en todo el clúster.
  3. Subjects (Sujetos):

    • Los sujetos son los usuarios, grupos o cuentas de servicio a los que se les otorgan permisos mediante RoleBindings o ClusterRoleBindings.
  4. Permisos (Verbs):

    • Los permisos en RBAC se expresan mediante verbos que representan las acciones que se pueden realizar en los recursos. Los verbos comunes son:
      • get: Obtener información de un recurso.
      • list: Listar recursos.
      • create: Crear nuevos recursos.
      • update: Actualizar recursos existentes.
      • delete: Eliminar recursos.
      • watch: Observar cambios en los recursos.

Roles y RoleBinding en Kubernetes (Ejercicio)

Este tutorial explica cómo crear un rol y asignarlo a un usuario para que tenga permisos limitados dentro de un clúster de Kubernetes. También describe el proceso de generación y aprobación de certificados para la autenticación de usuarios, indicando qué pasos debe realizar el usuario y cuáles el administrador del clúster.

Crear un Rol y Asignarlo a un Usuario

Paso 1: Definir un Rol (Administrador)

Para otorgar permisos específicos, el administrador crea un rol con los permisos necesarios. En este caso, el rol permitirá ver (listar y observar) los pods en el namespace “ventas”.

role.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: ventas
  name: operador
rules:
- apiGroups: [""] 
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
kubectl apply -f role.yaml

Vemos que se haya creado:

kubectl get roles -n ventas

Veremos el rol operador ,para mayor detalle hacemos:

kubectl describe role operador -n ventas

Antes que nada creemos un pod en el namespace ventas:

kubectl run httpd --image=httpd -n ventas

Paso 2: Crear una Solicitud de Firma de Certificado (Usuario)

Para autenticarse en el clúster, el usuario necesita un certificado. Comienza creando un archivo de configuración para la solicitud de firma de certificado (CSR) llamada desa1.csr.cnf:

desa1.csr.cnf:

[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[ dn ]
CN = desa1
O = desarrollo
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth

Paso 3: Generar la clave privada y el CSR (Usuario)

Con el archivo de configuración, el usuario genera una clave privada y la solicitud de firma de certificado (CSR).

openssl req -new -config desa1.csr.cnf -keyout desa1.key -out desa1.csr
  • desa1.key es la clave privada del usuario. Nota: puede estar cifrada.
  • desa1.csr es la solicitud de firma de certificado que el usuario enviará al administrador.

Paso 4: Convertir CSR a Base64 (Usuario)

El usuario convierte el CSR a formato base64, ya que Kubernetes requiere que la solicitud esté en este formato para poder procesarla.

cat desa1.csr | base64 | tr -d "\n"

Paso 5: Crear el objeto CertificateSigningRequest en Kubernetes (Administrador)

El administrador crea un objeto CertificateSigningRequest en Kubernetes usando el CSR en base64 proporcionado por el usuario.

cert.yaml:

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: desa1-firma
spec:
  groups:
    - system:authenticated
  request: <base64 del CSR>
  signerName: kubernetes.io/kube-apiserver-client
  usages:
    - digital signature
    - key encipherment
    - client auth

Nota: Reemplaza <base64 del CSR> con el valor en base64 obtenido por el usuario en el paso anterior.

Luego, el administrador aplica este archivo en Kubernetes:

kubectl apply -f cert.yaml

Paso 6: Verificar y Aprobar el CSR (Administrador)

El administrador revisa y aprueba la solicitud de firma de certificado (CSR) enviada por el usuario.

Para revisar la CSR:

kubectl get csr

Para aprobar la CSR:

kubectl certificate approve desa1-firma

En caso de denegar la solicitud (opcional):

kubectl certificate deny desa1-firma

Paso 7: Generar el Certificado Firmado y Enviarlo al Usuario (Administrador)

Una vez aprobado, el administrador extrae el certificado firmado y se lo proporciona al usuario para que pueda autenticarse en el clúster.

kubectl get csr desa1-firma -o jsonpath='{.status.certificate}' | base64 -d > user.crt

Paso 8: Autenticarse en el Clúster con el Certificado (Usuario)

Con el certificado (user.crt) y la clave privada (desa1.key), el usuario ya puede autenticarse en Kubernetes. No es necesario desencriptar la clave privada si el usuario va a usarla directamente con curl o kubectl mediante las opciones --cert y --key.

El usuario puede probar la conexión de la siguiente forma:

curl https://your-api-server.com/api/v1/namespaces/default/pods \
  --cacert ca.crt \
  --cert user.crt \
  --key desa1.key

También puede probar el acceso con kubectl sin desencriptar la clave privada:

kubectl get pods \
  --server=https://your-api-server.com \
  --certificate-authority=ca.crt \
  --client-certificate=user.crt \
  --client-key=desa1.key

Nota: La desencriptación de la clave privada es solo necesaria si el usuario va a configurar el archivo kubeconfig en la misma máquina del administrador. En ese caso, el administrador o el usuario deberían desencriptar desa1.key y actualizar la configuración para incluir la clave sin cifrar.

Si el usuario necesita el archivo kubeconfig, puede copiarlo y configurarlo de la siguiente manera:

  1. Copiar el archivo config de Kubernetes en una ubicación accesible, como /home/usuario/Documents/certs/.kube/:

    cp /home/akerman/.kube/config /home/usuario/Documents/certs/.kube/
    
  2. Modificar el archivo config copiado para incluir el certificado (user.crt) y la clave privada desencriptada (desa1.key).

    Desencriptar la clave privada (Usuario)

    Si desa1.key está cifrada y se necesita en el archivo kubeconfig, el usuario debe desencriptarla con:

    openssl rsa -in /home/akerman/Documents/roles/certs/desa1.key -out /home/akerman/Documents/roles/certs/desa1-decrypted.key
    

    Luego, actualizar el archivo kubeconfig para que apunte a esta clave desencriptada:

    Ejemplo de kubeconfig:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <base64 del certificado de autoridad>
    server: https://192.168.0.13:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    namespace: ventas
    user: desa1
  name: desa1-context
current-context: desa1-context
kind: Config
preferences: {}
users:
- name: desa1
  user:
    client-certificate: /home/akerman/Documents/roles/certs/user.crt 
    client-key: /home/akerman/Documents/roles/certs/desa1-decrypted.key
  1. Verificar el acceso:

    El usuario puede probar el acceso a los pods con el siguiente comando:

    kubectl --kubeconfig=/home/akerman/Documents/roles/certs/.kube/config get pods
    

    Posible error:

    Si recibe el error:

    Error from server (Forbidden): pods is forbidden: User "desa1" cannot list resource "pods" in API group "" in the namespace "ventas"
    

    Esto indica que no tiene permisos para listar los pods, lo cual es correcto hasta que el administrador asocie un rol a su usuario.

Paso 9: Asociar el Rol al Usuario (Administrador)

Para dar permisos de ver los pods, el administrador crea un RoleBinding que asocia el rol operador con el usuario desa1.

rolebinding.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
   name: role-operador
   namespace: ventas
subjects:
- kind: User
  name: desa1 
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role 
  name: operador 
  apiGroup: rbac.authorization.k8s.io

Luego aplica el RoleBinding:

kubectl apply -f rolebinding.yaml

Podemos ver con mas detalle el rol role-operator que acabamos de crear asi :

kubectl describe rolebindings role-operator -n ventas

Paso 10: Verificar Permisos (Usuario)

Si todo salió bien, el usuario desa1 podrá ver los pods en el namespace “ventas” usando su configuración de kubeconfig:

kubectl --kubeconfig=/home/akerman/Documents/roles/certs/.kube/config get pods

Asignar un cluster role a un usuario

  1. Creamos un cluster-role:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: desarrollo
rules:
- apiGroups: [""]
  resources: ["secrets","configmaps"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["create", "watch", "list","get","edit"]
kubectl apply -f cluster-role.yaml

Vamos los detalles:

kubectl describe clusterrole  desarrollo
  1. Asociamos al usuario desa1 al cluster-role
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
   name: cluster-role-ejemplo
subjects:
- kind: User
  name: desa1 
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: desarrollo
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f cluster-bindig.yaml
kubectl describe clusterrolebindings cluster-role-ejemplo

Una vez hayamos hecho eso, el usuario desa1 tiene los permisos para crear pods en el cluster y no estara restringido por el namespace.

kubectl --kubeconfig=/home/akerman/Documents/roles/certs/.kube/config run apache --image=httpd

Si queremos evitar tener que poner todo el tiempo el --kubeconfig hacemos export KUNECONFIG=/home/akerman/Documents/roles/certs/.kube/config

Service accounts

En Kubernetes, una ServiceAccount (cuenta de servicio) es un recurso que proporciona una identidad para los procesos que se ejecutan dentro de los pods, permitiendo que interactúen con el API Server de Kubernetes con permisos específicos. A diferencia de los usuarios regulares que están asociados a personas, las ServiceAccounts están diseñadas para aplicaciones y procesos automatizados que necesitan autenticarse y acceder a los recursos de Kubernetes.

Características de las ServiceAccounts

  1. Autenticación en el API Server:

    • Cuando se crea un pod, Kubernetes puede asociarle una ServiceAccount específica.
    • Esta cuenta de servicio incluye un token que se monta en el pod, permitiendo al pod autenticarse ante el API Server.
  2. Control de Permisos con RBAC:

    • Puedes asignar permisos específicos a una ServiceAccount mediante Roles y RoleBindings, usando el sistema de Role-Based Access Control (RBAC).
    • Esto permite que solo ciertos pods puedan realizar operaciones específicas en Kubernetes, mejorando la seguridad.
  3. Token de Autenticación:

    • Cada ServiceAccount tiene asociado un token de autenticación (JWT) que Kubernetes inserta automáticamente en los pods.
    • Este token se usa para autenticar el pod ante el API Server y para acceder a los recursos que esa cuenta tiene permiso de usar.

Ejemplo de Creación y Uso de una ServiceAccount

  1. Crear una ServiceAccount:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: my-service-account
      namespace: default
    

    Aplica este archivo para crear la ServiceAccount en el namespace default:

    kubectl apply -f service-account.yaml
    
  2. Asociar la ServiceAccount a un Pod:

    Puedes especificar la ServiceAccount en la configuración de un pod o deployment para que el pod use esa identidad:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
      namespace: default
    spec:
      serviceAccountName: my-service-account
      containers:
        - name: my-container
          image: my-image
    
  3. Configurar Permisos para la ServiceAccount:

    Usa RBAC para asignar permisos a la cuenta de servicio:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "list", "watch"]
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: read-pods
      namespace: default
    subjects:
    - kind: ServiceAccount
      name: my-service-account
      namespace: default
    roleRef:
      kind: Role
      name: pod-reader
      apiGroup: rbac.authorization.k8s.io
    

Resumen

  • Las ServiceAccounts son cuentas de servicio para aplicaciones o procesos en Kubernetes.
  • Se utilizan para autenticar pods ante el API Server y pueden configurarse con permisos específicos usando RBAC.
  • Cada ServiceAccount tiene un token de autenticación que se monta en los pods asociados, permitiendo que el pod actúe con los permisos de la ServiceAccount.

En Kubernetes, cada vez que creas un pod, Kubernetes le asigna una ServiceAccount por defecto llamada default, a menos que especifiques explícitamente otra ServiceAccount en la configuración del pod. Esta cuenta de servicio predeterminada permite que el pod se autentique y se comunique con el API Server de Kubernetes, aunque tiene permisos limitados.

¿Cómo funciona la ServiceAccount por defecto?

  1. Asignación Automática:

    • Cuando creas un pod y no defines ninguna serviceAccountName en su configuración, Kubernetes asigna automáticamente la ServiceAccount default en el namespace del pod.
    • Esta cuenta de servicio es creada automáticamente por Kubernetes en cada namespace cuando el namespace se genera.
  2. Montaje del Token de la ServiceAccount:

    • La ServiceAccount default contiene un token de autenticación en forma de archivo que Kubernetes monta automáticamente en el pod.
    • Este token se encuentra en el path /var/run/secrets/kubernetes.io/serviceaccount/token dentro del pod. Es un JSON Web Token (JWT) que el pod usa para autenticarse con el API Server.
  3. Permisos Limitados por Defecto:

    • La ServiceAccount default tiene permisos mínimos. Si no configuras roles adicionales, el pod podrá autenticarse, pero no podrá realizar acciones significativas en el clúster.
    • Esto se hace para que los pods no tengan acceso automático a recursos sensibles sin autorización explícita.

Ejemplo: Pod con la ServiceAccount default

Cuando creas un pod sin especificar una ServiceAccount, se utiliza la default de este modo:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: default
spec:
  containers:
    - name: my-container
      image: nginx

Este pod usará la ServiceAccount default del namespace default y tendrá acceso solo a los permisos mínimos asociados a esa cuenta.

Especificar una ServiceAccount Diferente

Si necesitas que el pod tenga permisos específicos para interactuar con el clúster, puedes crear una nueva ServiceAccount y asignarla al pod usando el campo serviceAccountName. Por ejemplo:

  1. Crear una nueva ServiceAccount:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: my-service-account
      namespace: default
    
  2. Asignar la nueva ServiceAccount al Pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
      namespace: default
    spec:
      serviceAccountName: my-service-account
      containers:
        - name: my-container
          image: nginx
    

En este ejemplo, el pod my-pod utilizará la ServiceAccount my-service-account, y Kubernetes montará su token en el pod, permitiéndole actuar con los permisos específicos que se hayan configurado para esa ServiceAccount.

Resumen

  • ServiceAccount default: Kubernetes asigna automáticamente esta cuenta a cada pod si no se especifica otra.
  • Token de autenticación: La ServiceAccount proporciona un token montado en el pod, lo que permite que el pod se autentique en el API Server.
  • Permisos limitados: La default ServiceAccount tiene permisos mínimos a menos que se le asignen explícitamente más permisos mediante RBAC.

Esto permite a Kubernetes proporcionar autenticación básica por defecto sin comprometer la seguridad del clúster.

comprobar si el service account tiene los permisos esperados

Pasos para Comprobar el Funcionamiento de la ServiceAccount en el Pod

  1. Ingresa al Pod: Utiliza kubectl exec para acceder al pod:

    kubectl exec -it my-pod -- /bin/sh
    
  2. Verifica la Presencia del Token: La ServiceAccount asignada debería montar un token de autenticación en el pod. Puedes verificarlo comprobando el archivo del token:

    cat /var/run/secrets/kubernetes.io/serviceaccount/token
    

    Si ves un token JWT en el archivo, significa que el token de la ServiceAccount está disponible en el pod.

  3. Haz una Solicitud curl al API Server: Utiliza curl para hacer una solicitud al API Server, pasando el token para autenticar la solicitud. Por ejemplo, puedes hacer una solicitud para listar los pods en el mismo namespace.

    TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
    NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
    APISERVER=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT
    
    curl -k -H "Authorization: Bearer $TOKEN" $APISERVER/api/v1/namespaces/$NAMESPACE/pods
    

    Explicación:

    • TOKEN: Carga el token de la ServiceAccount.
    • NAMESPACE: Obtiene el namespace en el que se encuentra el pod.
    • APISERVER: La dirección del API Server, que está disponible en las variables de entorno del pod ($KUBERNETES_SERVICE_HOST y $KUBERNETES_SERVICE_PORT).
    • -k: Ignora errores de verificación de certificados (útil para pruebas, aunque en un entorno seguro deberías usar un certificado válido).

Interpreta el Resultado de curl

  • Si el token es válido y el pod tiene permisos, deberías recibir una respuesta JSON con información sobre los recursos del namespace (por ejemplo, los pods).
  • Si ves un error 403 Forbidden, significa que la ServiceAccount no tiene permisos para realizar esa operación. Esto puede ajustarse creando un Role o ClusterRole y vinculándolo a la ServiceAccount del pod mediante un RoleBinding o ClusterRoleBinding.
  • Si hay problemas de autenticación, podría ser que el token esté dañado o no montado correctamente.

Ejemplo de Respuesta Exitosa

Si todo funciona bien y el pod tiene permisos para listar otros pods en su namespace, recibirás una respuesta similar a esta:

{
  "kind": "PodList",
  "apiVersion": "v1",
  "items": [
    {
      "metadata": {
        "name": "my-pod",
        ...
      },
      ...
    },
    ...
  ]
}

Este método es una forma efectiva de comprobar que la ServiceAccount del pod está configurada correctamente y que el pod puede autenticar y acceder al API Server de Kubernetes con los permisos asignados.

En Kubernetes, las variables de entorno KUBERNETES_SERVICE_HOST y KUBERNETES_SERVICE_PORT se crean automáticamente dentro de cada pod en el clúster. Estas variables apuntan al API Server de Kubernetes y se utilizan para facilitar el acceso al API Server desde dentro de los pods.

Variables de Entorno Automáticas en Pods

  • KUBERNETES_SERVICE_HOST: Contiene la dirección IP del API Server de Kubernetes.
  • KUBERNETES_SERVICE_PORT: Contiene el puerto en el que escucha el API Server, que es típicamente 443 para HTTPS.

Estas variables se inyectan en cada pod, independientemente de la ServiceAccount que se use, y son útiles para interactuar con el API Server desde dentro del pod.

Cómo Verificar las Variables en un Pod

Para confirmar que estas variables están disponibles, puedes ejecutar el siguiente comando dentro del pod:

kubectl exec -it my-pod -- sh -c 'echo $KUBERNETES_SERVICE_HOST $KUBERNETES_SERVICE_PORT'

Este comando debería mostrar la IP y el puerto del API Server.

Creando un service account y cambios en la version 1.24

A partir de Kubernetes 1.24, cambió el manejo de los tokens de las ServiceAccounts con la introducción de los Bound ServiceAccount Tokens. En esta versión y versiones posteriores, ya no se crean Secrets automáticamente para las ServiceAccounts, a menos que lo solicites explícitamente. Esto se hace para mejorar la seguridad y la administración de tokens.

¿Qué Cambió en Kubernetes 1.24?

  1. No más Secret automático:

    • Kubernetes ya no genera automáticamente un Secret con un token para las ServiceAccounts cuando se crea una nueva ServiceAccount. Esto significa que, si un pod necesita un token, debes crear manualmente el Secret, o bien, el pod utilizará el nuevo Bound ServiceAccount Token.
  2. Bound ServiceAccount Tokens:

    • Los Bound ServiceAccount Tokens son tokens de corta duración, automáticamente administrados y rotados por Kubernetes. Se montan en el pod sin necesidad de un Secret dedicado y están diseñados para ser más seguros, ya que no son válidos indefinidamente.

Cómo Solicitar un Secret Manualmente (si lo necesitas)

Si necesitas un Secret para una ServiceAccount en versiones posteriores a 1.24, debes crear el Secret manualmente usando un TokenRequest. Aquí te explico cómo hacerlo:

  1. Solicitar un Token con un TokenRequest:

    Usa kubectl para crear un token manualmente:

    kubectl create token my-service-account
    

    Esto genera un token JWT que puedes usar de forma manual en cualquier servicio que necesite autenticarse.

  2. Crear un Secret a partir del Token (opcional):

    Si necesitas un Secret específico, puedes crear uno y colocar el token dentro:

    apiVersion: v1
    kind: Secret
    metadata:
      name: my-service-account-token
      annotations:
        kubernetes.io/service-account.name: "my-service-account"
    type: kubernetes.io/service-account-token
    

    Aplica el archivo YAML para crear el Secret:

    kubectl apply -f secret.yaml
    

Ventajas del Nuevo Modelo

El cambio a Bound ServiceAccount Tokens aporta mejoras significativas en la seguridad:

  • Tokens de corta duración: Los tokens expiran automáticamente, reduciendo el riesgo si un token queda expuesto.
  • Rotación automática: Kubernetes gestiona y rota estos tokens sin intervención manual.
  • Menos exposición de Secrets: Como ya no se crean Secrets automáticamente, se reduce la posibilidad de que queden tokens persistentes innecesarios.

Con este modelo, los pods aún pueden autenticarse ante el API Server sin necesidad de tokens persistentes. En la mayoría de los casos, el nuevo modelo funciona sin problemas adicionales para los usuarios y sin necesidad de administración manual de tokens.

En que casos usariamos un token creado manualmente?

Un token de ServiceAccount manual, o un Secret que contenga el token, podría ser útil en escenarios donde una aplicación externa o un servicio fuera del clúster de Kubernetes necesita autenticarse con el API Server. A continuación, te doy algunos casos específicos donde puede ser necesario o útil:

1. Aplicaciones Externas que Gestionan Kubernetes

Si tienes una aplicación externa o un script que administra el clúster de Kubernetes (por ejemplo, para automatizar despliegues desde una herramienta CI/CD o gestionar configuraciones desde un sistema externo), puedes necesitar un token de ServiceAccount persistente que funcione desde fuera del clúster. En este caso, puedes crear un Secret manualmente y usar el token para que la aplicación se autentique en Kubernetes.

Ejemplo:

kubectl create token my-service-account --duration=24h

Esto genera un token de 24 horas que puedes almacenar y usar en la aplicación.

2. Integración con Herramientas de Monitoreo y Logging Externas

Herramientas de monitoreo, logging o incluso paneles de administración que no estén alojados en el clúster, pueden necesitar acceso al API Server para obtener información en tiempo real sobre el estado del clúster, eventos, logs, etc. En este caso, un token manual es útil, ya que permite que estas herramientas se autentiquen de manera continua.

3. Ambientes de Desarrollo y Testing

Durante el desarrollo o las pruebas, podrías necesitar autenticación persistente con Kubernetes desde fuera del clúster para realizar pruebas de automatización, integración o despliegues. Un token manual puede permitir acceso controlado sin necesidad de montar un pod o manejar rotación automática de tokens.

4. Scripts y Automatizaciones Fuera del Clúster

Si tienes scripts o herramientas que necesitan ejecutar comandos en Kubernetes desde fuera del clúster (por ejemplo, en estaciones de trabajo de desarrolladores o en pipelines de CI/CD), puedes usar un token de ServiceAccount manual para autenticar estas herramientas.

5. Acceso Temporal con Permisos Limitados

Si necesitas proporcionar acceso temporal a un usuario o aplicación con permisos muy específicos, puedes crear un token con permisos limitados y controlados. Al especificar un período de validez (--duration), puedes asegurarte de que el token expire automáticamente después de un tiempo específico, mejorando la seguridad.

Ejemplo:

kubectl create token my-service-account --duration=1h

Esto puede ser útil para pruebas temporales o auditorías que requieran acceso limitado y por un período corto.

Consideraciones de Seguridad

Usar tokens manuales para aplicaciones o servicios fuera del clúster requiere un control cuidadoso:

  • Duración limitada: Siempre que sea posible, establece una duración limitada para que el token expire automáticamente.
  • Permisos mínimos: Usa RBAC para otorgar solo los permisos necesarios para la tarea que requiere el token.
  • Almacenamiento seguro: Guarda el token en un lugar seguro, como un sistema de gestión de secretos, para evitar exposiciones accidentales.

En resumen, los tokens manuales son útiles para acceso seguro y controlado desde fuera del clúster, cuando es necesario un acceso persistente o continuo sin rotación automática.

Paso a paso crear un sercvice account con un secret manual

Paso 1: Crear la ServiceAccount

Primero, crea una ServiceAccount en el namespace deseado. Este ejemplo usará el namespace default:

# Archivo: service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-service-account
  namespace: default

Aplica el archivo para crear la ServiceAccount:

kubectl apply -f service-account.yaml

Esto crea la ServiceAccount my-service-account en el namespace default.

Paso 2: Crear el Secret Manualmente y Asociarlo a la ServiceAccount

En Kubernetes 1.24 y posteriores, cuando se crea una ServiceAccount, ya no se genera automáticamente un Secret con el token. Para crear este Secret manualmente y asociarlo a la ServiceAccount, sigue estos pasos:

  1. Configura el Manifiesto del Secret con la anotación kubernetes.io/service-account.name, especificando el nombre de la ServiceAccount:

    # Archivo: secret.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: my-service-account-token  # Nombre del Secret
      annotations:
        kubernetes.io/service-account.name: "my-service-account"  # Nombre de la ServiceAccount a asociar
    type: kubernetes.io/service-account-token
    

    Este tipo de Secret (kubernetes.io/service-account-token) le indica a Kubernetes que debe generar automáticamente un token JWT y almacenarlo en este Secret.

  2. Aplica el archivo para crear el Secret:

    kubectl apply -f secret.yaml
    

Paso 3: Verificar la Asociación entre el Secret y la ServiceAccount

Ahora que has creado el Secret con la anotación de la ServiceAccount, Kubernetes automáticamente asocia el Secret con la ServiceAccount especificada (my-service-account).

Para verificar esto, usa el siguiente comando:

kubectl get serviceaccount my-service-account -o yaml -n default

Deberías ver el Secret my-service-account-token en la sección secrets de la ServiceAccount:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-service-account
  namespace: default
secrets:
- name: my-service-account-token

Esto confirma que el Secret está asociado correctamente con la ServiceAccount my-service-account.

Paso 4: Usar la ServiceAccount en un Pod

Ahora puedes usar esta ServiceAccount en un pod. Kubernetes montará automáticamente el token de la ServiceAccount en el pod, permitiendo que el pod se autentique en el API Server con el token del Secret.

Aquí tienes un ejemplo de configuración del pod:

# Archivo: pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: default
spec:
  serviceAccountName: my-service-account  # Asocia la ServiceAccount al pod
  containers:
  - name: my-container
    image: nginx

Aplica el manifiesto del pod:

kubectl apply -f pod.yaml

Paso 5: Verificar el Token en el Pod

Dentro del pod, puedes verificar que el token de la ServiceAccount se haya montado automáticamente. Ejecuta el siguiente comando para acceder al pod:

kubectl exec -it my-pod -- /bin/sh

Luego, verifica el token en el directorio donde Kubernetes monta los Secrets de la ServiceAccount:

cat /var/run/secrets/kubernetes.io/serviceaccount/token

Si ves un token JWT en el archivo, significa que la ServiceAccount y el Secret están funcionando correctamente y que el pod puede autenticarse en el API Server de Kubernetes.

Resumen

  1. Crear la ServiceAccount (service-account.yaml).
  2. Crear un Secret manualmente (secret.yaml) y usar la anotación kubernetes.io/service-account.name para asociarlo.
  3. Verificar la asociación en la ServiceAccount (kubectl get serviceaccount my-service-account -o yaml).
  4. Asignar la ServiceAccount al pod y verificar que el token esté montado en el pod.

Esto asegura que el pod tenga acceso a la API de Kubernetes usando la ServiceAccount y su token.