Revisión de Service Accounts
Es una cuenta de usuario que está destinada a ser utilizada por procesos dentro de pods, en lugar de por usuarios humanos. Estas cuentas proporcionan autenticación al API de Kubernetes para los procesos que se ejecutan en los pods, permitiendo a Kubernetes que administre sus permisos y acceda a los recursos de la API de manera controlada. En la mayoría de distirbuciones de kubernetes en cada namespace existe el service account: default, el cual es utilizado por todas las cargas de trabajo, si el atributo serviceAccountName no está definido en el recurso.
Cuando un usuario ingresa al cluster ya sea mediante la Interfaz o mediante comandos (kubectl), este obtiene una identidad mediante la autenticación con ese usuario, por lo que puede acceder e interactuar con el APIServer y sus componentes. Esto mismo sucede con los Service Account, la diferencia consiste que en el caso de un Service Account se limita a ciertas acciones dentro del mismo namespace donde se está ejecutando el proceso en cuestión.
Cada Service Account puede estar asignado a una lista de permisos en específico mediante Roles que definen las acciones permitidas sobre los diferentes grupos de componentes del APIServer, como por ejemplo el grupo asociado a los Deployments con acciones de ver, listar, crear pero no modificar o eliminar.
Guías Prácticas de Laboratorio
Antes de comenzar
- Contar con el acceso al ambiente del laboratorio.
Conexión hacia cluster
-
Ingrese al cluster asignado con las credenciales proporcionadas.
-
Configure la variable
KUBECONFIG.export KUBECONFIG=~/devcluster/kube_config_cluster.yml -
Verifique el acceso mediante comandos.
kubectl get namespaces
Instalación de YQ
-
Ingrese al cluster asignado con las credenciales proporcionadas.
-
Descargue e instale el binario de YQ en el PATH requerido.
curl -Lo yq https://github.com/mikefarah/yq/releases/download/v4.24.2/yq_linux_amd64 && sudo chmod +x ./yq && sudo mv yq /usr/bin/yq -
Verifique el binario instalado.
yq -V
Guía 1: Service Account
Descripción
La presente guía muestra cómo crear, listar, modificar y eliminar Service Accounts dentro de un namespace.
Objetivos
- Crear un Service Account personalizado
- Autenticarse mediante un Token de Service Account
- Modificar los permisos del Service Account mediante Roles
- Verificar los permisos del Service Account
Inicio de laboratorio
-
Crear un nuevo namespace llamado example-sa
kubectl create ns example-sa -
Establecer el nuevo namespace por defecto con el contexto actual.
kubectl config set-context --current --namespace=example-sa -
Liste los Service Accounts del namespace actual.
kubectl get sa -
Obtenga la información del SA
default.kubectl describe sa default -
Desde Kubernetes v1.24 los secrets para los SA deben ser generados manualmente, por lo tanto crearemos el siguiente YAML.
cat > example-sa/secret.yaml <<-EOF apiVersion: v1 kind: Secret metadata: name: robot-token namespace: example-sa annotations: kubernetes.io/service-account.name: default type: kubernetes.io/service-account-token EOF -
Luego crearemos el recurso secret con lo siguiente.
kubectl apply -f example-sa/secret.yaml -
Verifique los Secrets del namespace actual
Nota: El concepto de Secret se verá en otro tópico. Un Secret es un recurso de Kubernetes que permite almacenar datos considerados como credenciales y son utilizados por Aplicaciones y Herramientas, en este caso es utilizado para almacenar elkubectl get secretstokendel ServiceAccount. -
Obtenga la información del Secret
robot-token.El Token del ServiceAccount es utilizado para comunicarse contra el APIServer, para mantener el estado y la configuración del recurso.kubectl describe secret robot-token -
Obtener los diferentes contextos que se tienen configurados en el archivo kubeconfig
Nota: Anote el nombre del contexto que está utilizando actualmentekubectl config get-contexts -
Cree una entrada de usuario para kubectl utilizando el contenido descifrado del campo
tokenpara autenticarse contra el clusterkubectl config set-credentials sa-user --token=$(kubectl get secret robot-token -o jsonpath={.data.token} | base64 -d) -
Cambie el usuario que utiliza para kubectl.
kubectl config set-context local --user=sa-user -
Verifique los usuarios que tiene para kubectl.
kubectl config get-users -
Pruebe a obtener los Pods del namespace.
Nota: Esta parte debe tirar un error de permisos.kubectl get pods -
Pruebe a obtener los Namespaces del cluster.
Nota: Esta parte debe tirar un error de permisos.kubectl get ns -
Configure nuevamente kubectl para ocupar las credenciales de su usuario.
kubectl config set-context local --user=kube-admin-local -
Cree un Service Account llamado
list-only.kubectl create sa list-only -
Cree un
Roleque permita obtener la lista de pods en el namespace actual.kubectl create role pod-reader --verb=get --verb=list --resource=pods -
Cree un
RoleBindingpara el Service Accountlist-only.kubectl create rolebinding list-pods-sa-binding --role=pod-reader --serviceaccount=example-sa:list-only -
Verifique que los recursos
RoleyRoleBindingexistan en el namespace.kubectl get roles,rolebindings -
Verifique la información del Service Account
list-only.kubectl describe sa list-only -
Cree el siguiente YAML para el Token del Service Account anterior.
cat > example-sa/secret-list-only.yaml <<-EOF apiVersion: v1 kind: Secret metadata: name: list-only-token namespace: example-sa annotations: kubernetes.io/service-account.name: list-only type: kubernetes.io/service-account-token EOF -
Luego crearemos el recurso Secret con lo siguiente.
kubectl apply -f example-sa/secret-list-only.yaml -
Obtenga el nombre del Secret a utilizar.
kubectl get secrets -
Obtener los diferentes contextos que se tienen configurados en el archivo kubeconfig
Nota: Anote el nombre del contexto que está utilizando actualmentekubectl config get-contexts -
Cree una entrada de usuario para kubectl utilizando el contenido descifrado del campo
tokenpara autenticarse contra el clusterkubectl config set-credentials sa-user-list-only --token=$(kubectl get secret list-only-token -o jsonpath={.data.token} | base64 -d) -
Cambie el usuario que utiliza para kubectl.
kubectl config set-context --current --user=sa-user-list-only -
Verifique que pueda obtener el listado de Pods
kubectl get pods -
Verifique que los demás accesos estén restringidos (debe dar error)
kubectl get nskubectl get secrets -
Configure nuevamente kubectl para ocupar las credenciales de su usuario
kubectl config set-context local --user=kube-admin-local -
Limpie el ambiente
kubectl delete ns example-sa -
Configure el namespace a utilizar por el contexto de kubectl a
defaultkubectl config set-context --current --namespace=default
Guía 2: Exploración de Token
Descripción
Por cada Namespace existe un Service Account por defecto llamado default el cual es asignado a los Pods que no especifiquen el parámetro serviceAccount o serviceAccountName. Cada SA genera un Secret que contiene el token con el cual se autentica y el certificado del CA del cluster para trust.
Podemos configurar permisos sobre los diferentes recursos tal cual se hace con una cuenta normal de Usuario, de esta forma podemos ampliar su uso a través de desarrollo propio.
Objetivos
- Crear un Service Account Token
- Validar el acceso al API de Kubernetes Utilizando el Token
- Crear Token con expiración por defecto (1 hora)
- Crear Token con expiración de (24 horas)
- Examinar Token (https://jwt.io/)
Inicio del Laboratorio
Sección 1
-
Crear un nuevo namespace llamado explore-sa
kubectl create ns explore-sa -
Establecer el nuevo namespace por defecto con el contexto actual
kubectl config set-context --current --namespace=explore-sa -
Liste los Service Accounts.
kubectl get sa - Cree un nuevo Service Account.
kubectl create sa robot - Revise la información del SA creado.
kubectl describe sa robot - Elimine el SA.
kubectl delete sa robot - Crear un nuevo namespace llamado explore-sa.
kubectl create ns explore-sa - Crearemos el siguiente directorio siguiente manera:
mkdir example-sa - Luego crearemos un archivo
sa.yamlde la siguiente manera.cat > example-sa/sa.yaml <<-EOF apiVersion: v1 kind: ServiceAccount metadata: name: robot namespace: explore-sa EOF - Cree el SA usando el archivo YAML.
kubectl apply -f example-sa/sa.yaml - Solicite un token para ese service account.
kubectl create token robot - Tome el valor de ese token y examinarlo en el sitio: https://jwt.io/.
NO REALICE ESTO CON UN TOKEN DE PRODUCCION

- Valide los campos:
| Nombre | Descripción |
|---|---|
| iat | Issued At |
| exp | Expiration Time |
Sección 2
-
Obtenga el valor de server de la configuración de su cluster de RKE.
SERVER=$(yq ".clusters[0].cluster.server" ~/devcluster/kube_config_cluster.yml) -
Valide el valor de la variable
echo $SERVER Mostrará algo similar a: https://*******:6443 -
Defina la variable de ambiente TOKEN
TOKEN='VALOR_TOKEN_OBTENIDO_EN_PASOS_ANTERIORES' -
Intente consumir el API de Kubernetes sin el token
curl -k ${SERVER}/version -
Examinar Resultado
{ "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401 } -
Note el error
401Unauthorizedpaso anterior. -
Intente consumir el API de Kubernetes utilizando el token.
curl -k -H "Authorization: Bearer ${TOKEN}" ${SERVER}/version -
Examinar Resultado
{ "major": "1", "minor": "24", "gitVersion": "v1.24.10", "gitCommit": "5c1d2d4295f9b4eb12bfbf6429fdf989f2ca8a02", "gitTreeState": "clean", "buildDate": "2023-01-18T19:08:10Z", "goVersion": "go1.19.5", "compiler": "gc", "platform": "linux/amd64" } -
Cree un pod de prueba en el namespace
explore-sa.kubectl run nginx --image=nginx kubectl get pods -
Verifique que el pod haya sido creado.
kubectl get pods -
Intente obtener los recursos tipo pods en el namespace
explore-saUtilizando el API.curl -k -H "Authorization: Bearer ${TOKEN}" ${SERVER}/api/v1/namespaces/explore-sa/pods -
Examinar Resultado:
{ "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "pods is forbidden: User \"system:serviceaccount:explore-sa:robot\" cannot list resource \"pods\" in API group \"\" in the namespace \"explore-sa\"", "reason": "Forbidden", "details": { "kind": "pods" }, "code": 403 } -
Note el error
403Forbiddenpaso anterior.
Sección 3
-
Crear un Rol a nivel de Kubernetes, que permita
get,lista los recursos tipopodsen el namespaceexplore-sa.kubectl create role get-pods-sa --verb get,list --resource=pods -
Consulte el rol creado.
kubectl describe role get-pods-sa -
Asigar el rol
get-pods-saal serviceAccountroboten el namespaceexplore-sa.kubectl create rolebinding allow-sa-pods --role get-pods-sa --serviceaccount=explore-sa:robot -
Intente obtener los recursos tipo pods en el namespace
explore-sautilizando el API.curl -k -H "Authorization: Bearer ${TOKEN}" ${SERVER}/api/v1/namespaces/explore-sa/pods -
Examinar Resultado.
Obtendra un json con la información de todos los pods de ese namespace
Sección 4
El token generado en el inicio del laboratorio tiene una duración por defecto de 1 hora.
Podemos modificar ese tiempo en la creación del token utilizando la opción --duration=TIEMPO.
Ejemplo: --duration=24h
Para crear un TOKEN para un Service Account, el cual podemos utilizar sin vencimiento, podemos crear un secret con una anotación que hace referencia a un token.
-
Crear el siguinete manifiesto.
cat <<EOF > secret-token-robot.yaml apiVersion: v1 kind: Secret type: kubernetes.io/service-account-token metadata: name: robot annotations: kubernetes.io/service-account.name: "robot" EOF -
Crear el recurso en el cluster.
kubectl create -f secret-token-robot.yaml -
Listar los recursos tipo secret.
kubectl get secrets -
Obtener token desde el secret y decodifiquelo de base64.
TOKEN2=$(kubectl get secret -o jsonpath="{.data.token}" robot|base64 --decode) -
Depliegue el valor del token.
cat $TOKEN2 -
Tome el valor de ese token y examinarlo en el sitio: https://jwt.io/.
NO REALICE ESTO CON UN TOKEN DE PRODUCCION :warning.

-
Note que no tiene vencimiento. La única forma de invalidarlo es eliminando el secret y creando uno nuevo.
-
Intente obtener los recursos tipo pods en el namespace
explore-saUtilizando el API y el nuevoTOKEN2.curl -k -H "Authorization: Bearer ${TOKEN2}" ${SERVER}/api/v1/namespaces/explore-sa/pods -
Examinar Resultado:
Obtendra un json con la información de todos los pods de ese namespace -
Elimine el Secret token
kubectl delete -f secret-token-robot.yaml -
Intente obtener los recursos tipo pods en el namespace
explore-saUtilizando el API y el nuevoTOKEN2. -
Examinar Resultado:
{ "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401 } -
Note el error
401Unauthorizedpaso anterior. -
Limpiamos el ambiente.
kubectl delete pod nginx --force --grace-period=0 kubectl delete rolebindings allow-sa-pods kubectl delete role get-pods-sa kubectl delete ns explore-sa kubectl config set-context --current --namespace=default --user=kube-admin-local
Sección 5 - Reto
Realice las adaptaciones necesarias en estas guias para realizar las consultas utilizando el proxy de Rancher para el cluster de Kubernetes
TIP: Vea un kubeconfig descargado desde Rancher Server