Module 4 · Gouvernance du cluster¶
Objectifs
- RBAC : qui a le droit de faire quoi.
- Ressources & quotas : requests/limits, LimitRange, ResourceQuota.
- Placement : nodeSelector, taints/tolerations, DaemonSet.
- Durée : ~1 h · Pré-requis : Module 3.
RBAC - Role Based Access Control¶
Quatre objets, deux niveaux de portée :
graph LR
SA[ServiceAccount / User] --> RB[RoleBinding]
RB --> R[Role]
R --> V[Verbes sur ressources]
SA --> CRB[ClusterRoleBinding]
CRB --> CR[ClusterRole]
| Objet | Portée | Rôle |
|---|---|---|
Role |
Un namespace | Liste de permissions (verbes × ressources) |
ClusterRole |
Tout le cluster | Idem, à l'échelle cluster |
RoleBinding |
Un namespace | Attribue un Role à un sujet (user/SA/group) |
ClusterRoleBinding |
Cluster | Idem à l'échelle cluster |
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: lecteur-pods
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: dev
name: antoine-lecteur
subjects:
- kind: ServiceAccount
name: antoine
namespace: dev
roleRef:
kind: Role
name: lecteur-pods
apiGroup: rbac.authorization.k8s.io
kubectl auth can-i get pods --as system:serviceaccount:dev:antoine -n dev # yes
kubectl auth can-i delete pods --as system:serviceaccount:dev:antoine -n dev # no
Tu vis dedans depuis le module 0
Le RBAC n'est pas une théorie : ta sandbox elle-même repose dessus - demande au mentor de te montrer comment. La pratique du moindre privilège est approfondie au module Sécurité.
Ressources : requests, limits, quotas¶
resources:
requests: # ce que le scheduler réserve
cpu: "100m"
memory: "128Mi"
limits: # plafond ; au-delà → throttle (CPU) ou OOMKill (mémoire)
cpu: "500m"
memory: "256Mi"
- requests = garanti, sert au scheduling.
- limits = plafond. Dépasser la mémoire → le pod est OOMKilled.
Selon ce que tu déclares, Kubernetes classe le pod dans une classe QoS - visible dans
le describe (ligne QoS Class) : Guaranteed (requests = limits partout),
Burstable (des requests, des limits différentes) ou BestEffort (rien déclaré -
premier sacrifié quand un nœud manque de mémoire). Un pod sans requests/limits, popeye
te le reprochera aussi.
Les garde-fous du namespace¶
Sur un cluster partagé, on n'attend pas que chacun déclare bien ses ressources - on l'impose au namespace :
ResourceQuotaplafonne la somme (CPU, mémoire, nb d'objets) de tout le namespace ;LimitRangeinjecte des défauts (requests/limits) dans tout conteneur qui n'en déclare pas - et peut borner les valeurs permises.
kubectl get resourcequota # k9s : :quota - la somme autorisée vs utilisée
kubectl describe quota # le détail used / hard
kubectl get limitrange # les défauts injectés dans les pods sans déclaration
Tu vis dessous depuis le module 0
Ta sandbox tourne sous quota (posé un cran au-dessus, sur le cluster hôte). Tu en
vois la trace sur chacun de tes pods : dans un describe, l'annotation
LimitRanger plugin set: cpu, memory request… montre le LimitRange en action -
ton pod a reçu des requests par défaut que tu n'as jamais écrites.
Exercice - OOMKill
Déploie un pod avec limits.memory: 32Mi qui alloue 100 Mo. Observe dans k9s l'état
OOMKilled et retrouve-le dans le describe.
Contrôler le placement - nodeSelector, taints & tolerations¶
Les requests décident si un pod peut être placé ; deux mécanismes décident où :
nodeSelector(côté pod) : « je veux un nœud portant ce label » -nodeSelector: { disktype: ssd }.- Taints & tolerations (côté nœud) : un nœud taché
(
kubectl taint nodes n1 gpu=true:NoSchedule) repousse tous les pods… sauf ceux qui portent la toleration correspondante. C'est le miroir du nodeSelector : ici c'est le nœud qui filtre.
Le cordon d'un nœud (module 2b) n'en est qu'un cas particulier : il
pose une taint spéciale qui interdit toute nouvelle planification sur le nœud. (Pour des
règles plus fines, le champ affinity généralise tout ça - hors socle.)
Le placement poussé au maximum : DaemonSet
Un DaemonSet demande « un pod sur chaque nœud » - pas de replicas, le nombre
suit le cluster (un nœud arrive → son pod arrive). C'est l'objet des agents :
collecte de logs, métriques, réseau (le CNI lui-même tourne comme ça). Dans k9s :
:ds. Tu n'en écriras probablement jamais, mais tu en croiseras dans tout cluster
réel - savoir le reconnaître évite de chercher un Deployment qui n'existe pas.
Pratique¶
Le TP de ce module, dans le terminal de ta sandbox - une fois la lecture faite :
tp start 03-scheduling # un pod Pending faute de mémoire : requests = réservation, pas usage
tp start ancrage-4 # en autonomie ensuite : garde-fous posés AVANT que ça coince
fais la manip puis tp check (ou tp watch pour l'auto-validation) · tp hint / tp solution si tu bloques.
Ce qu'il faut retenir¶
- RBAC = verbes × ressources × sujet × portée.
auth can-ipour vérifier. - requests/limits pilotent scheduling et stabilité (OOMKill) ; nodeSelector et taints/tolerations pilotent le placement.
ResourceQuotaplafonne la somme d'un namespace,LimitRangeimpose des défauts.
Quiz éclair¶
Teste-toi : réponds de tête, puis déplie.
1. Comment vérifier qu'un ServiceAccount a (ou non) le droit de faire une action ?
kubectl auth can-i <verbe> <ressource> --as system:serviceaccount:<ns>:<nom> -n <ns>
(répond yes/no). auth can-i --list montre tous ses droits.
2. Différence entre requests et limits ?
requests = ressources réservées (servent au scheduling). limits =
plafond : dépasser la mémoire → le pod est OOMKilled, dépasser le CPU → throttling.
3. Un nœud doit n'accueillir que certains pods. Quel mécanisme ?
Une taint sur le nœud (NoSchedule) le repousse par défaut ; seuls les pods
portant la toleration correspondante y sont planifiés. nodeSelector fait l'inverse
(le pod choisit un nœud par label).
➡️ Suite : Module 4r - Exposer une app : le chemin d'une requête