Capitulo 8: Namespaces y RBAC

Por: Artiko
k3skubernetesnamespacesrbacseguridad

Capitulo 8: Namespaces y RBAC

< Volver al Indice del Tutorial

Namespaces

Los Namespaces son divisiones logicas dentro de un cluster. Permiten aislar recursos, aplicar politicas de seguridad y organizar equipos o entornos.

Namespaces por Defecto

K3s crea estos namespaces automaticamente:

NamespaceProposito
defaultDonde se crean recursos si no especificas namespace
kube-systemComponentes del sistema (CoreDNS, ServiceLB, Traefik)
kube-publicRecursos accesibles publicamente (rara vez usado)
kube-node-leaseHeartbeats de nodos para detectar fallos
kubectl get namespaces

Crear Namespaces

# Imperativo
kubectl create namespace staging
kubectl create namespace produccion

# Declarativo
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: staging
  labels:
    entorno: staging
EOF

Trabajar con el Flag -n

Por defecto, kubectl opera en el namespace default. Usa -n para especificar otro:

# Crear un pod en staging
kubectl run nginx --image=nginx:1.27-alpine -n staging

# Listar pods en staging
kubectl get pods -n staging

# Listar pods en todos los namespaces
kubectl get pods -A

Cambiar el Namespace por Defecto

Para evitar escribir -n staging en cada comando:

# Ver contexto actual
kubectl config current-context

# Cambiar namespace por defecto
kubectl config set-context --current --namespace=staging

# Verificar
kubectl config view --minify | grep namespace

A partir de este punto, todos los comandos operan en staging sin necesidad de -n.

Eliminar Namespaces

kubectl delete namespace staging

Esto elimina todos los recursos dentro del namespace. Usa con precaucion.

RBAC: Control de Acceso Basado en Roles

RBAC (Role-Based Access Control) controla quien puede hacer que en el cluster. K3s trae RBAC habilitado por defecto.

Conceptos Fundamentales

Usuario/ServiceAccount --> RoleBinding --> Role --> Permisos
                           (vincula)       (define)
ConceptoAmbitoDescripcion
RoleNamespacePermisos dentro de un namespace
ClusterRoleClusterPermisos en todo el cluster
RoleBindingNamespaceVincula Role a usuario/SA en un namespace
ClusterRoleBindingClusterVincula ClusterRole a usuario/SA en todo el cluster
ServiceAccountNamespaceIdentidad para pods y procesos

ServiceAccounts

Cada namespace tiene un ServiceAccount default. Los pods lo usan automaticamente para autenticarse con la API de Kubernetes.

# Ver ServiceAccounts
kubectl get serviceaccounts
kubectl get sa

# Crear un ServiceAccount
kubectl create serviceaccount ci-deployer -n staging

En YAML:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: ci-deployer
  namespace: staging

Crear un Role

Un Role define permisos especificos dentro de un namespace. Los permisos se definen con:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deployer-role
  namespace: staging
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "configmaps"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]

Este Role permite:

kubectl apply -f deployer-role.yaml
kubectl get roles -n staging

RoleBinding

Vincula un Role a un ServiceAccount (o usuario):

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: deployer-binding
  namespace: staging
subjects:
  - kind: ServiceAccount
    name: ci-deployer
    namespace: staging
roleRef:
  kind: Role
  name: deployer-role
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f deployer-binding.yaml
kubectl get rolebindings -n staging

Verificar permisos

# Puede el ServiceAccount listar pods en staging?
kubectl auth can-i list pods \
  --as=system:serviceaccount:staging:ci-deployer \
  -n staging
# yes

# Puede eliminar pods?
kubectl auth can-i delete pods \
  --as=system:serviceaccount:staging:ci-deployer \
  -n staging
# no

# Puede ver pods en produccion?
kubectl auth can-i list pods \
  --as=system:serviceaccount:staging:ci-deployer \
  -n produccion
# no

ClusterRole y ClusterRoleBinding

Para permisos que aplican a todo el cluster (no limitados a un namespace).

ClusterRole

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: readonly-global
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "namespaces", "nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch"]

ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: readonly-global-binding
subjects:
  - kind: ServiceAccount
    name: monitor-sa
    namespace: default
roleRef:
  kind: ClusterRole
  name: readonly-global
  apiGroup: rbac.authorization.k8s.io

Un ClusterRole tambien puede vincularse con un RoleBinding normal. En ese caso, los permisos se limitan al namespace del binding. Es util para reutilizar un ClusterRole en multiples namespaces.

Ejemplo: ServiceAccount para CI/CD

Crearemos un ServiceAccount con permisos limitados para que un pipeline de CI/CD pueda desplegar en el namespace produccion.

1. Crear el namespace y ServiceAccount

kubectl create namespace produccion
kubectl create serviceaccount ci-pipeline -n produccion

2. Definir los permisos

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ci-deploy-role
  namespace: produccion
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["services", "configmaps"]
    verbs: ["get", "list", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]

3. Vincular Role al ServiceAccount

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ci-deploy-binding
  namespace: produccion
subjects:
  - kind: ServiceAccount
    name: ci-pipeline
    namespace: produccion
roleRef:
  kind: Role
  name: ci-deploy-role
  apiGroup: rbac.authorization.k8s.io

4. Generar token para uso externo

kubectl create token ci-pipeline -n produccion --duration=87600h

Este token se configura en el sistema de CI/CD (GitLab CI, GitHub Actions, etc.) como variable de entorno. El pipeline usa este token para autenticarse con el cluster y desplegar solo en el namespace produccion.

5. Verificar permisos del ServiceAccount

# Puede desplegar?
kubectl auth can-i create deployments \
  --as=system:serviceaccount:produccion:ci-pipeline \
  -n produccion
# yes

# Puede eliminar deployments? (no tiene el verb "delete")
kubectl auth can-i delete deployments \
  --as=system:serviceaccount:produccion:ci-pipeline \
  -n produccion
# no

# Puede operar en otro namespace?
kubectl auth can-i list pods \
  --as=system:serviceaccount:produccion:ci-pipeline \
  -n default
# no

El ServiceAccount ci-pipeline solo puede crear y actualizar deployments, services y configmaps en produccion. No puede eliminar recursos ni operar en otros namespaces. Esto sigue el principio de minimo privilegio.


Siguiente: Capitulo 9: Ingress con Traefik —>