Aller au contenu principal

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 un emptyDir monté sur /tmp ;
  • allowPrivilegeEscalation: false ;
  • capabilities.drop: [ALL], NET_RAW compris : un pod compromis ne peut pas forger de paquets ARP ou DNS pour usurper un voisin ;
  • hostNetwork, hostPID, hostIPC explicitement à false, aucun volume hostPath, aucun hostPort ;
  • 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​

ExceptionChargeJustification
emptyDir medium: Memory sur /dev/shmvLLMNCCL et le parallélisme tensoriel échangent par mémoire partagée ; la taille est bornée (sizeLimit)
PVC de cache des modèlesvLLMpoids préchargés, HF_HUB_OFFLINE=1, aucun téléchargement à l'exécution
namespace eai-gpu en baselineimages GPU tiercescertaines 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 privilegedopérateur NVIDIAle 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 :

PolitiqueRègles
eai-pod-securitydrop-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-tokensun pod sur le ServiceAccount default doit déclarer automountServiceAccountToken: false
eai-image-provenancehors 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-exposurepas 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