Passons en mode gouvernance. Kubernetes n’est pas sécurisé par défaut : à vous de limiter les permissions, d’imposer des politiques et de tracer toutes les actions.
Table of Contents
Objectifs
- Déléguer précisément les droits grâce à RBAC et ServiceAccounts.
- Appliquer les Pod Security Standards et des NetworkPolicies strictes.
- Mettre en place des garde-fous (admission controllers, policy engines) et activer l’audit.
1. ServiceAccounts et authentification
Chaque Pod utilise un ServiceAccount (SA). Par défaut, c’est default. Créez-en un dédié :
apiVersion: v1
kind: ServiceAccount
metadata:
name: deployer
namespace: tools
Générez un token éphémère (Kubernetes 1.24+) :
kubectl create token deployer -n tools --duration=4h
2. RBAC : Roles et RoleBindings
Attribuer uniquement les verbes nécessaires :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: tools
name: deployer-role
rules:
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deployer-binding
namespace: tools
subjects:
- kind: ServiceAccount
name: deployer
namespace: tools
roleRef:
kind: Role
name: deployer-role
apiGroup: rbac.authorization.k8s.io
Testez :
kubectl auth can-i create deployments -n tools --as=system:serviceaccount:tools:deployer
3. Pod Security Standards (PSS)
Depuis la 1.25, les PodSecurityPolicies sont retirées. Kubernetes applique désormais trois profils (privileged, baseline, restricted) via des labels sur le namespace.
kubectl label namespace production pod-security.kubernetes.io/enforce=restricted
kubectl label namespace production pod-security.kubernetes.io/audit=baseline
Complétez avec un moteur de policy :
- OPA Gatekeeper : langage Rego, flexible.
- Kyverno : règles déclaratives YAML.
Exemple Kyverno – interdire les conteneurs root
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-run-as-nonroot
spec:
validationFailureAction: enforce
rules:
- name: run-as-non-root
match:
resources:
kinds:
- Pod
validate:
message: "Les conteneurs doivent tourner en utilisateur non root"
pattern:
spec:
containers:
- =(securityContext):
runAsNonRoot: true
4. NetworkPolicies avancées
Combinez règles ingress/egress :
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-egress
namespace: production
spec:
podSelector:
matchLabels:
role: api
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: data
podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
- to:
- ipBlock:
cidr: 10.10.0.0/16
ports:
- protocol: TCP
port: 443
Ne pas oublier la politique default deny :
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
5. Admission controllers et audit
- Activez l’audit logging (paramètres kube-apiserver) :
--audit-log-path,--audit-policy-file. - Déployez un webhook mutating (ex. cert-manager) pour injecter des sidecars.
- Utilisez
kubectl get --raw "/api/v1/namespaces/kube-system/configmaps/audit-policy"si votre cluster expose la policy.
Exemple minimal d’audit policy :
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
verbs: ["create", "update", "patch", "delete"]
resources:
- group: ""
resources: ["pods", "secrets"]
6. Lab guidé
- Créez les namespaces
production,frontendetdata(labelsenv=frontend,name=data). - Appliquez les labels PSS (
productionenrestricted). - Déployez une application
apidansproductionavec un ServiceAccountdeployer+ Role minimal. - Ajoutez la NetworkPolicy
deny-allpuisdb-egresspour autoriser uniquement PostgreSQL. - Installez Kyverno (
helm repo add kyverno https://kyverno.github.io/kyverno) et appliquez la policyrequire-run-as-nonroot. Testez un Pod sanssecurityContext: il doit être rejeté. - Activez l’audit logging (si cluster kubeadm) et consultez le fichier
/var/log/kubernetes/audit.log.
Solution détaillée
- RBAC
kubectl auth can-i create deployments -n tools --as=system:serviceaccount:tools:deployer→yes.
kubectl auth can-i delete secrets -n tools --as=…→no. - PSS
Créez un Pod volontairement privilégié dansproduction: il doit être rejeté avec un messageviolates PodSecurity "restricted". - Kyverno
Après installation,kubectl apply -f pod-root.yaml(pod sansrunAsNonRoot) doit renvoyerforbidden by policy require-run-as-nonroot.
kubectl get cpol require-run-as-nonrootvérifie l’état. - NetworkPolicies
Avecdeny-allen place, un Pod debackenddoit être bloqué (curl postgres→ timeout). Après application dedb-egress, seul un Pod labelrole=apipeut sortir sur le port 5432. - Audit
Sur cluster kubeadm, vérifiez/var/log/kubernetes/audit.log. Exemple d’entrée :{"verb":"create","user":{"username":"system:serviceaccount:tools:deployer"},"objectRef":{"resource":"deployments","namespace":"tools"}}
Ces contrôles attestent que la séparation des rôles et les garde-fous fonctionnent avant de passer aux modules observabilité et GitOps.
Pièges fréquents
- Attribuer un
ClusterRoleBindingplutôt qu’unRoleBinding(accès trop large). - Oublier l’ordre des webhooks mutating/validating : un mutating peut modifier l’objet avant validation.
- Déployer des NetworkPolicies sans CNI compatible (Flannel “pur” les ignore).
- Laisser le ServiceAccount
defaultavec un token auto-monté : désactivezautomountServiceAccountTokensi inutile.
Ressources
Checklist
- ✅ Vous savez créer un ServiceAccount, un Role et un RoleBinding adaptés.
- ✅ Vous avez mis en place Pod Security
restrictedet des NetworkPolicies. - ✅ Vous savez installer un moteur de policy (Kyverno) et vérifier qu’il bloque les manifestes non conformes.


