Protección del acceso a Kubernetes con RBAC

KubernetesBeginner
Practicar Ahora

Introducción

La autenticación de Kubernetes identifica a quien realiza una solicitud; la autorización determina qué puede hacer esa identidad. RBAC expresa los permisos como verbos aplicados a recursos de la API y los asigna a usuarios, grupos o ServiceAccounts.

Crearás un lector limitado a un espacio de nombres, vincularás su identidad con los permisos correspondientes y comprobarás, mediante suplantación de identidad, tanto las acciones permitidas como los límites de acceso denegados.

RBAC resulta más fácil de entender si se analiza mediante tres preguntas: ¿Quién? (ServiceAccount), ¿Qué puede hacer? (Role) y ¿Quién recibe esos permisos? (RoleBinding). Crear solo uno o dos de estos objetos no completa la cadena de autorización.

Crear una identidad ServiceAccount

En este paso, crearás una ServiceAccount asociada a un espacio de nombres para un componente de la aplicación.

Una ServiceAccount es una identidad de la API de Kubernetes destinada a cargas de trabajo y procesos automatizados. No es un usuario de Linux dentro del contenedor. Asignar a este ejemplo una identidad propia evita que herede la ServiceAccount default del espacio de nombres.

cd /home/labex/project/rbac-access
kubectl create serviceaccount inventory-reader -n practice-rbac
kubectl get serviceaccount inventory-reader -n practice-rbac -o yaml

Su identidad completa es system:serviceaccount:practice-rbac:inventory-reader. Crear una identidad por sí solo no concede permisos sobre la aplicación.

En la salida YAML, los metadatos confirman el espacio de nombres y el nombre. No esperes que aparezca automáticamente un Secret de token de larga duración; las versiones modernas de Kubernetes proyectan tokens de corta duración en los Pods cuando son necesarios.

El objeto devuelto contiene el nombre y el espacio de nombres asignados, pero ningún Secret de token generado automáticamente:

kind: ServiceAccount
metadata:
  name: inventory-reader
  namespace: practice-rbac

Definir permisos limitados al espacio de nombres

En este paso, crearás un Role que permita leer Pods y ConfigMaps únicamente en practice-rbac.

Cada regla combina grupos de API, recursos y verbos. Para recursos principales, como Pods y ConfigMaps, apiGroups: [""] utiliza una cadena vacía. Los verbos get, list y watch representan, respectivamente, lecturas individuales, lecturas de colecciones y seguimiento de cambios.

cd /home/labex/project/rbac-access
cat <<'EOF' > inventory-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: {name: inventory-reader, namespace: practice-rbac}
rules:
  - apiGroups: [""]
    resources: [pods, configmaps]
    verbs: [get, list, watch]
EOF

Aplica el Role y consulta sus detalles. describe muestra las reglas de la política en una tabla, más fácil de revisar que el YAML sin procesar:

kubectl apply -f inventory-role.yaml
kubectl describe role inventory-reader -n practice-rbac

El grupo de API vacío selecciona los recursos principales. Un Role nunca concede acceso fuera de su espacio de nombres.

Observa también lo que no aparece: no se incluyen create, update, patch ni delete. El principio de privilegios mínimos se define tanto por los permisos omitidos como por los concedidos.

Resources   Non-Resource URLs  Resource Names  Verbs
---------   -----------------  --------------  -----
configmaps  []                 []              [get list watch]
pods        []                 []              [get list watch]

La tabla desglosa la regla combinada del YAML en una fila por recurso. Ambas filas tienen los mismos tres verbos de solo lectura.

Vincular el Role con la identidad

En este paso, conectarás el Role con la ServiceAccount mediante un RoleBinding.

El comando imperativo es breve porque ambos objetos ya existen. --role indica el origen de los permisos, mientras que --serviceaccount utiliza el formato namespace:name para identificar al sujeto.

cd /home/labex/project/rbac-access
kubectl create rolebinding inventory-reader -n practice-rbac --role=inventory-reader --serviceaccount=practice-rbac:inventory-reader
kubectl get rolebinding inventory-reader -n practice-rbac -o yaml

roleRef identifica los permisos; subjects identifica las identidades que los reciben. En este caso, ambos elementos permanecen limitados al espacio de nombres.

Aunque un Role y una ServiceAccount tengan el mismo nombre, siguen siendo objetos independientes hasta que existe este vínculo. Los nombres están pensados para facilitar la gestión humana; el RoleBinding es la conexión de autorización efectiva.

En el YAML, sigue la conexión desde roleRef.name: inventory-reader hasta el sujeto cuyo tipo es ServiceAccount, cuyo nombre es inventory-reader y cuyo espacio de nombres es practice-rbac.

Probar acciones permitidas y denegadas

En este paso, utilizarás kubectl auth can-i con --as para suplantar la identidad de la ServiceAccount.

Las pruebas de autorización deben incluir casos positivos y negativos. Un resultado yes demuestra que el trabajo necesario es posible, mientras que un resultado no confirma que no se concedieron accidentalmente permisos destructivos ni acceso entre espacios de nombres.

cd /home/labex/project/rbac-access
IDENTITY=system:serviceaccount:practice-rbac:inventory-reader
kubectl auth can-i list pods -n practice-rbac --as="$IDENTITY"
kubectl auth can-i get configmaps -n practice-rbac --as="$IDENTITY"
kubectl auth can-i delete pods -n practice-rbac --as="$IDENTITY" || true
kubectl auth can-i list pods -n default --as="$IDENTITY" || true

Las dos primeras respuestas deben ser yes; la eliminación y la consulta de Pods en otro espacio de nombres deben devolver no. La suplantación permite probar la autorización sin exponer ni crear un token.

kubectl auth can-i devuelve un estado distinto de cero en el shell junto con la respuesta no. Los dos sufijos || true permiten que la prueba deliberada de denegación continúe; no modifican la decisión de autorización.

yes
yes
no
no

Interpreta estos resultados como dos capacidades necesarias seguidas de dos límites de protección. Una prueba que solo contuviera respuestas yes no demostraría la aplicación del principio de privilegios mínimos.

El usuario actual del laboratorio tiene permiso para suplantar esta ServiceAccount con fines de prueba. --as cambia la identidad que el servidor de la API evalúa para ese comando; no cambia el usuario de tu shell ni sustituye permanentemente las credenciales de kubectl.

Resumen

Has creado una ServiceAccount, definido permisos de solo lectura limitados al espacio de nombres mediante un Role, asignado esos permisos con un RoleBinding y comprobado, mediante suplantación de identidad, tanto las acciones permitidas como las denegadas.