RousselTMLEARNING

Conteneurisation

Kubernetes : sécuriser son cluster (RBAC, ServiceAccounts, NetworkPolicies, Pod Security)

Sécuriser Kubernetes : RBAC (Role, ClusterRole, bindings), ServiceAccounts, NetworkPolicies, Pod Security Standards, securityContext, secrets, audit et vérification avec kubectl auth can-i.

1. Les couches de sécurité #

Défense en profondeur.

Panorama #

Couches de sécurité Kubernetes
Aucune couche seule ne suffit.

2. RBAC #

Roles, ClusterRoles et bindings.

Donner des droits précis #

Modèle RBAC de Kubernetes
Un ClusterRole peut être lié dans un seul namespace avec un RoleBinding.
# Un rôle en lecture seule sur les pods du namespace production
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: { name: lecteur-pods, namespace: production }
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata: { name: alice-lecteur, namespace: production }
subjects: [{ kind: User, name: alice, apiGroup: rbac.authorization.k8s.io }]
roleRef: { kind: Role, name: lecteur-pods, apiGroup: rbac.authorization.k8s.io }
kubectl auth can-i list pods -n production --as alice          # yes
kubectl auth can-i delete pods -n production --as alice        # no
kubectl auth can-i --list -n production --as alice
kubectl get clusterrolebindings -o wide | grep cluster-admin     # qui est cluster-admin ?
kubectl create rolebinding dev-edit --clusterrole=edit --user=bob -n dev
Erreur Courante : N'attribuez cluster-admin qu'à des comptes d'administration. Les wildcards (verbs: ["*"]) et l'accès à secrets doivent rester exceptionnels.

ServiceAccounts #

kubectl create serviceaccount app -n production
kubectl create role lire-config --verb=get,list --resource=configmaps -n production
kubectl create rolebinding app-lire-config --role=lire-config --serviceaccount=production:app -n production
# Dans le pod : serviceAccountName: app   et   automountServiceAccountToken: false si l'API n'est pas utilisée

3. Isoler les pods #

securityContext, Pod Security et NetworkPolicies.

Contraintes de sécurité des pods #

# Pod Security Admission : appliquer le profil "restricted" à un namespace
kubectl label namespace production pod-security.kubernetes.io/enforce=restricted pod-security.kubernetes.io/warn=restricted

# Conteneur durci
securityContext:
  runAsNonRoot: true
  runAsUser: 10001
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities: { drop: ["ALL"] }
  seccompProfile: { type: RuntimeDefault }

NetworkPolicies #

# Tout interdire par défaut, puis autoriser web -> api
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: { name: deny-all, namespace: production }
spec: { podSelector: {}, policyTypes: [Ingress, Egress] }
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: { name: web-vers-api, namespace: production }
spec:
  podSelector: { matchLabels: { app: api } }
  policyTypes: [Ingress]
  ingress:
    - from: [{ podSelector: { matchLabels: { app: web } } }]
      ports: [{ port: 8080 }]
À savoir : Les NetworkPolicies exigent un CNI qui les implémente (Calico, Cilium...). Avec un CNI sans support, elles sont acceptées mais n'ont aucun effet.

4. Secrets et audit #

Protéger et contrôler.

Bonnes pratiques #

  • Activer le chiffrement des secrets dans etcd (EncryptionConfiguration) et limiter l'accès à etcd.
  • Préférer External Secrets Operator ou le CSI Secrets Store (Vault, AWS/GCP/Azure) aux secrets versionnés.
  • Analyser les images (trivy image) et vérifier les configurations (kube-bench, kubescape).
  • Activer les journaux d'audit de l'API server et superviser les accès à secrets.
trivy image nginx:1.27
trivy k8s --report summary cluster
kubescape scan framework nsa
docker run --rm --pid=host -v /etc:/etc:ro aquasec/kube-bench:latest run --targets node

Pour aller plus loin