Sécurité des pods
Version anglaise : en/pod-security.md.
Contexte appliqué par le chart
Tous les pods du chart (control plane, worker, migration, portail, LiteLLM, vLLM, workers multimodaux) utilisent les helpers eai.podSecurityContext et eai.containerSecurityContext :
runAsNonRoot: true,runAsUser: 10001,runAsGroup: 10001,fsGroup: 10001;seccompProfile: RuntimeDefault;readOnlyRootFilesystem: true, avec unemptyDirmonté sur/tmp;allowPrivilegeEscalation: false;capabilities.drop: [ALL],NET_RAWcompris : un pod compromis ne peut pas forger de paquets ARP ou DNS pour usurper un voisin ;hostNetwork,hostPID,hostIPCexplicitement àfalse, aucun volumehostPath, aucunhostPort;- requêtes et limites CPU et mémoire sur chaque conteneur ;
enableServiceLinks: false(pas de variables d'environnement révélant les autres Services).
automountServiceAccountToken: false sur tous les pods et ServiceAccounts, sauf le Deployment du control plane : il crée les pods du bac à sable et leurs NetworkPolicies et a donc besoin de son jeton. C'est aussi le seul pod autorisé à joindre l'API Kubernetes (eai-deny-kube-apiserver).
Exceptions GPU documentées
| Exception | Charge | Justification |
|---|---|---|
emptyDir medium: Memory sur /dev/shm | vLLM | NCCL et le parallélisme tensoriel échangent par mémoire partagée ; la taille est bornée (sizeLimit) |
| PVC de cache des modèles | vLLM | poids préchargés, HF_HUB_OFFLINE=1, aucun téléchargement à l'exécution |
namespace eai-gpu en baseline | images GPU tierces | certaines images de fournisseurs (serveurs de modèles, images CUDA comme dcgm-exporter) tournent en UID 0 et ne peuvent pas déclarer runAsNonRoot, ce que restricted refuse. baseline interdit toujours les conteneurs privilégiés, hostPath, les namespaces de l'hôte, hostPort et l'ajout de capacités dangereuses. audit et warn restent en restricted |
namespace gpu-operator en privileged | opérateur NVIDIA | le pilote, le toolkit et le device plugin installent le module noyau et exposent /dev/nvidia* ; ce namespace n'exécute aucun code de la plateforme |
Les pods vLLM et workers du chart gardent eux le contexte restricted complet ; le test test_platform_security_manifests.py refuse toute autre exception.
Pod Security Admission
deploy/cilium/namespaces.yaml (synchronisé par Argo CD avec deploy/cilium) étiquette les namespaces : pod-security.kubernetes.io/enforce=restricted pour enterprise-ai, eai-data, eai-security, openbao, apisix ; le namespace du bac à sable (eai-sandbox) est créé par le chart en restricted.
Politiques Kyverno
deploy/policies/kyverno/pod-network-security.yaml, en mode Enforce :
| Politique | Règles |
|---|---|
eai-pod-security | drop-all-capabilities, disallow-added-capabilities (NET_RAW jamais, seul NET_BIND_SERVICE toléré), require-seccomp, disallow-privileged, disallow-host-namespaces, disallow-host-path, disallow-host-ports |
eai-service-account-tokens | un pod sur le ServiceAccount default doit déclarer automountServiceAccountToken: false |
eai-image-provenance | hors projets Harbor eai et mirror (vérifiés par cosign dans cluster-policies.yaml et épinglés par mutateDigest), une image doit être référencée par digest |
eai-restrict-service-exposure | pas d'externalIPs (CVE-2020-8554), pas de NodePort hors ingress et apisix |
Ces politiques complètent cluster-policies.yaml (signatures, non root, système de fichiers en lecture seule, limites, étiquettes). Les cas de test sont dans deploy/policies/kyverno/tests :
kyverno test deploy/policies/kyverno/tests
helm template eai deploy/helm/enterprise-ai -f deploy/helm/enterprise-ai/values-onprem-gpu.yaml > /tmp/r.yaml
kyverno apply deploy/policies/kyverno/pod-network-security.yaml --resource /tmp/r.yaml