Creare un utente read-only in Kubernetes
In questo post riassumo le operazioni per creare uno user Kubernetes con accesso in sola lettura utilizzando certificati client x509 e RBAC.
La procedura è valida per qualsiasi cluster Kubernetes
Obiettivo
Lo user read-only potrà eseguire operazioni di:
get,list,watch- usare
kubectl get,describe,logs
Non potrà:
- creare / modificare / cancellare risorse
- usare
kubectl apply,delete,exec
Concetti chiave
Kubernetes nativamente non gestisce utenti interni.
L’accesso è possibile grazie a due componenti:
- Autenticazione → certificato client
- Autorizzazione → RBAC (Role / ClusterRole)
Creazione della chiave privata
Per comodità tutte le operazioni che seguono verranno eseguite da shell su un nodo control-plane del vostro cluster Kubernetes
openssl genrsa -out user-readonly.key 2048
Creazione della CSR
Il CN diventerà lo username visto da Kubernetes.
openssl req -new \
-key user-readonly.key \
-out user-readonly.csr \
-subj "/CN=user-readonly/O=readonly"
Firma del certificato con la CA del cluster
openssl x509 -req \
-in user-readonly.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial \
-out user-readonly.crt \
-days 365
Creazione della ClusterRole read-only
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: readonly-cluster
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list", "watch"]
kubectl apply -f readonly-clusterrole.yaml
Binding dello user alla ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: readonly-user-binding
subjects:
- kind: User
name: user-readonly
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: readonly-cluster
apiGroup: rbac.authorization.k8s.io
kubectl apply -f readonly-binding.yaml
Creazione del kubeconfig dedicato (metodo base64)
Ora che abbiamo tutto pronto ci manca solo il file di configurazione da utilizzare con kubectl, il kubeconfig appunto. Per crearlo utilizziamo il metodo con i certificati codificati in Base64 direttamente nel kubeconfig.
- Converti i certificati in Base64:
base64 -w0 user-readonly.crt > user-readonly.crt.base64
base64 -w0 user-readonly.key > user-readonly.key.base64
base64 -w0 /etc/kubernetes/pki/ca.crt > ca.crt.base64
- Crea il kubeconfig:
apiVersion: v1
kind: Config
clusters:
- name: kubernetes
cluster:
server: https://IP-API-SERVER:6443
certificate-authority-data: <contenuto di ca.crt.base64>
users:
- name: user-readonly
user:
client-certificate-data: <contenuto di user-readonly.crt.base64>
client-key-data: <contenuto di user-readonly.key.base64>
contexts:
- name: readonly-context
context:
cluster: kubernetes
user: user-readonly
current-context: readonly-context
Sostituisci <contenuto di ...> con i rispettivi file Base64 generati.
Test dell’accesso
KUBECONFIG=./kubeconfig-readonly kubectl get nodes
Che ci mostrerà:
NAME STATUS ROLES AGE VERSION
kubespray-master-01 Ready control-plane 21d v1.34.2
kubespray-master-02 Ready control-plane 21d v1.34.2
kubespray-master-03 Ready control-plane 21d v1.34.2
kubespray-worker-01 Ready <none> 21d v1.34.2
kubespray-worker-02 Ready <none> 21d v1.34.2
kubespray-worker-03 Ready <none> 21d v1.34.2
Test di un’operazione vietata:
KUBECONFIG=./kubeconfig-readonly kubectl delete pod test -n default
Se tutto è andato per il verso giusto ci darà errore:
Error from server (Forbidden): pods "test" is forbidden: User "user-readonly" cannot delete resource "pods" in API group "" in the namespace "default"
Ulteriore verifica tramite RBAC
kubectl auth can-i get pods --as=user-readonly
kubectl auth can-i delete pods --as=user-readonly
Conclusione
Questa soluzione fornisce un accesso minimale, sicuro e nativo a Kubernetes, ideale da condividere con i colleghi DEV e permettergli di consultare tutti gli oggetti presenti nel cluster, con la certezza però che non vengano combinati dei guai “non tocchis nudda” :D
Happy kubectl! 🚀
