Saltar a contenido

Recetas de roles

Los seis roles de sistema cubren casi toda la semana de un equipo. Hay cuatro necesidades frecuentes que quedan entre ellos: un developer que escribe Secrets, un bot que despliega con Helm, los recursos personalizados de terceros y kubectl debug en un namespace con Pod Security. Aquí está el rol para cada una, lo que no da y lo que se queda en cluster-admin.

Las recetas nombran las capacidades por su identificador, que «Buscar capacidades» también encuentra en el constructor. Cómo se crea y se concede un rol está en Gestionar roles; qué permite cada capacidad y qué rechaza siempre kubelatch, en Roles. Los roles personalizados son una función Pro; donde Free tiene una salida, la receta lo dice.

Un developer que también escribe Secrets

Cuándo: alguien con developer crea o actualiza los Secrets de su aplicación (kubectl create secret, o un kubectl apply que lleva uno). developer no escribe Secrets, y secrets-reader solo los lee.

El rol: en el constructor, elige developer en «Empezar desde» y añade:

  • secrets.write, para crearlos, cambiarlos y eliminarlos;
  • secrets.read, porque kubectl apply y kubectl edit leen el objeto antes de escribirlo.

La copia conserva las capacidades que muestra developer, namespace.read incluida, pero no los CRDs etiquetados para el nivel en cada cluster (Duplicar un rol).

Deja «Namespaces» en «Dónde se aplica». El rol sale «Sensible», y «Mira dos veces» explica por qué: «Escribir Secrets permite sustituir las credenciales que usan otras cargas de trabajo.» Exige Pod Security, igual que developer.

Qué añade: poco que la persona no alcanzara ya. Quien despliega pods en un namespace puede montar sus Secrets (El namespace es la frontera). Lo nuevo es poder sobrescribir un Secret que lee otra carga de trabajo. Un viewer del namespace no ve ningún Secret, pero lee los ConfigMaps enteros, valores incluidos: una credencial va en un Secret aunque un ConfigMap fuera más cómodo de escribir.

En Free: el rol de sistema que escribe Secrets es admin.

Un bot que despliega con Helm

Cuándo: un bot de CI (Usuarios y bots, CI: reglas de confianza) ejecuta helm upgrade --install en su namespace.

Helm guarda cada release en un Secret de ese namespace, así que el bot tiene que leer y escribir Secrets además de lo que traiga el chart. Hay dos maneras:

  • admin en su namespace. El rol admin de Kubernetes cubre lo que un chart suele poner en un namespace, Roles y RoleBindings incluidos. El precio: el bot puede enlazar roles dentro del namespace. Exige Pod Security.
  • Un rol personalizado, si el chart no trae RBAC: escribir Roles y RoleBindings se rechaza siempre en un rol personalizado. Marca las capacidades de escritura de lo que lleve el chart y la de lectura que presupone cada una (el constructor ofrece añadirla):

    Escritura Lectura
    secrets.write (las releases de Helm y los Secrets del chart) secrets.read
    config.write config.read
    workloads.deploy workloads.read
    network.write network.read
    storage.write storage.read
    policy.write (PodDisruptionBudgets) namespace.read
    networkpolicies.write network.read
    autoscaling.write, si el chart trae HorizontalPodAutoscalers workloads.read

    Una ServiceAccount en el chart pide una regla avanzada: «Grupo core», serviceaccounts, «Lectura» y «Escritura» (Helm lee cada objeto antes de crearlo o actualizarlo). El rol sale «Sensible» y exige Pod Security.

HELM_DRIVER=configmap no es la solución, aunque con un chart sin Secrets cabría en developer: la release pasa a un ConfigMap, y cualquier viewer del namespace la lee, con el manifiesto renderizado y los Secrets del chart dentro.

Lo que no da ninguna de las dos: nada fuera del namespace. Un chart que instala CRDs o ClusterRoles es una instalación de plataforma. --create-namespace también falla, porque ninguno de los dos roles crea namespaces: crea el namespace antes, con su etiqueta de Pod Security, y concede el rol al bot en él.

Recursos personalizados de terceros

Cuándo: quienes despliegan en un namespace crean también los recursos de un operador instalado en el cluster: un Certificate de cert-manager, un ScaledObject de KEDA, un Rollout de Argo Rollouts. No hay capacidades para recursos personalizados. Hay dos maneras:

  • Un ClusterRole etiquetado en el cluster, que vale en Free: un ClusterRole con la etiqueta kubelatch.io/aggregate-to-developer: "true" suma sus reglas a developer en ese cluster, para todos los que lo tienen allí (Añadir CRDs a un nivel):

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: certificates-developer
      labels:
        kubelatch.io/aggregate-to-developer: "true"
    rules:
      - apiGroups: ["cert-manager.io"]
        resources: ["certificates"]
        verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
    
  • Una regla avanzada en un rol personalizado (Pro), solo para algunas personas: «Grupo de la API» cert-manager.io, «Recursos» certificates, «Verbos» «Lectura» y «Escritura». Un grupo ajeno a Kubernetes marca el rol como «Sensible». Un rol personalizado no recoge ClusterRoles etiquetados, así que la regla es la única forma de meter el recurso en él.

La salvedad: kubelatch no sabe qué hace un recurso personalizado. Crear un Workflow de Argo ejecuta código, porque su controlador crea los pods: una regla que lo escribe es un permiso para desplegar. kubelatch no puede saber que necesita Pod Security (Lo que kubelatch no puede saber), así que concédelo solo en namespaces que la apliquen. Con la etiqueta no hay problema: developer ya la exige.

kubectl debug con Pod Security

Cuándo: alguien con debugger añade un contenedor de depuración a un pod en marcha, y el namespace aplica Pod Security baseline o restricted, como debe para que se pueda conceder debugger en él (Pod Security Admission).

El rol: debugger, tal cual. Lo que falla es el contenedor de depuración: el perfil por defecto de kubectl, general, le da la capacidad SYS_PTRACE, que baseline rechaza. Pide un perfil que el namespace admita:

kubectl debug -it web-7f9c --image=busybox --target=app --profile=baseline

En un namespace restricted, usa --profile=restricted, con una imagen que no se ejecute como root.

Lo que no da: SYS_PTRACE, así que ni strace ni gdb sobre los procesos del contenedor objetivo. kubectl debug --copy-to crea un pod nuevo, y eso es developer, no debugger. Depurar un nodo (kubectl debug node/…) arranca un pod en los namespaces del nodo con su sistema de ficheros montado, y Pod Security lo rechaza en todos los namespaces donde se puede conceder debugger: se queda en cluster-admin.

Lo que se queda en cluster-admin

kubectl cordon, uncordon y drain, los taints y las etiquetas de los nodos, crear namespaces y aprobar solicitudes de certificado no tienen rol de sistema ni capacidad: actúan sobre todo el cluster, y un rol personalizado concedido a todo el cluster solo lee. Escribir namespaces y aprobar certificados se rechaza siempre. Para eso está cluster-admin, con sus 8 h y su auditoría (Conceder acceso de emergencia con cluster-admin); los namespaces, mejor que los cree lo que aprovisiona la plataforma. Leer el cluster es otra cosa: un rol personalizado concedido a todo el cluster puede llevar nodes.read y cluster.inspect.

Antes de decidir que hace falta un rol para los nodos, cuenta los rechazos que la gente se encuentra de verdad: en «Auditoría», el resultado «Denegadas» filtrado por «Verbo» y «Recurso» (nodes, por ejemplo) dice qué 403 aparecen y con qué frecuencia (Buscar peticiones a los clusters).