Aller au contenu
Conteneurs & Orchestration medium

Polaris : auditer et corriger vos manifests Kubernetes

23 min de lecture

logo polaris

Vos manifests Kubernetes passent en CI, mais une fois en production, vous découvrez des pods qui tournent en root, sans limites de mémoire, ou avec des images latest. Polaris détecte ces problèmes avant le déploiement et peut même les corriger automatiquement. Ce guide vous apprend à auditer vos YAML en une commande, intégrer Polaris dans votre CI/CD, et créer vos propres règles de conformité.

  • Auditer des manifests YAML ou des charts Helm en 2 minutes
  • Faire échouer votre pipeline CI si le score est trop bas ou si des erreurs critiques existent
  • Personnaliser les règles avec des custom checks JSON Schema
  • Déployer le dashboard et l'admission controller dans un cluster

Une équipe déploie une application e-commerce. Le manifest YAML passe tous les tests unitaires, mais personne ne remarque que :

  • Le conteneur tourne en root (risque de compromission totale du nœud)
  • Aucune limite mémoire n'est définie (un conteneur peut consommer toute la RAM du nœud)
  • L'image utilise le tag latest (impossible de savoir quelle version tourne réellement)
  • Les probes de santé sont absentes (Kubernetes ne sait pas si l'app fonctionne)

Ces erreurs passent inaperçues jusqu'à l'incident. Polaris les détecte avant que le manifest n'atteigne le cluster.

Polaris analyse vos workloads Kubernetes (Deployments, StatefulSets, DaemonSets, Jobs, CronJobs) et vérifie qu'ils respectent les bonnes pratiques. Il fonctionne de trois façons :

ModeCe qu'il faitQuand l'utiliser
CLI / auditAnalyse des fichiers YAML ou un clusterCI/CD, vérification ponctuelle
DashboardInterface web pour visualiser les problèmesTriage, visibilité équipe
Admission ControllerBloque ou alerte sur les workloads non conformesEnforcement en production

Polaris n'est pas seul sur ce terrain, et le choix se joue surtout sur la complexité des règles dont vous avez besoin. Les deux premières lignes ciblent l'hygiène des workloads ; les suivantes sont de véritables moteurs de politiques, plus puissants mais bien plus longs à mettre en place et à maintenir.

OutilSpécialitéQuand le choisir
PolarisBest practices workloads + score + remédiationHygiène de base, CI/CD simple
kube-scoreBest practices workloadsAlternative légère à Polaris
KyvernoPolicy engine complet (admission + mutation)Policies complexes, multi-cluster
OPA/GatekeeperPolicy engine (Rego)Politiques avancées, conformité entreprise
KubescapeSécurité (NSA, MITRE, CIS)Audits de conformité sécurité

En résumé : Polaris est idéal pour commencer avec les bonnes pratiques. Si vous avez besoin de politiques complexes (RBAC, NetworkPolicies, quotas), regardez Kyverno ou Gatekeeper.


L'objectif de cette section : passer d'un dossier de manifests à un rapport lisible, puis faire échouer un pipeline quand la qualité se dégrade. Le binaire Polaris est autonome : il n'a besoin ni de cluster ni de kubeconfig pour analyser des fichiers sur disque. C'est précisément ce mode hors cluster qui convient à la CI.

L'audit s'exécute sur un chemin local et produit deux choses : le détail des checks en échec et un score global sur 100.

  1. Installer Polaris

    Fenêtre de terminal
    VERSION=10.1.4
    curl -fsSLO "https://github.com/FairwindsOps/polaris/releases/download/$VERSION/polaris_linux_amd64.tar.gz"
    curl -fsSLO "https://github.com/FairwindsOps/polaris/releases/download/$VERSION/checksums.txt"
    grep " polaris_linux_amd64.tar.gz$" checksums.txt | sha256sum -c -
    sudo tar -xzf polaris_linux_amd64.tar.gz -C /usr/local/bin polaris
    polaris version
    # Polaris version:10.1.4
  2. Lancer un audit

    Fenêtre de terminal
    polaris audit --audit-path ./k8s/ --format pretty

    Sortie typique pour un manifest problématique :

    Polaris audited Path ./k8s/ at 2026-02-02T07:43:15+01:00
    Nodes: 0 | Namespaces: 0 | Controllers: 1
    Final score: 40
    Deployment webshop-api in namespace production
    deploymentMissingReplicas 😬 Warning
    Reliability - Only one replica is scheduled
    missingPodDisruptionBudget 😬 Warning
    Reliability - Should have a PodDisruptionBudget
    Container api
    tagNotSpecified ❌ Danger
    Reliability - Image tag should be specified
    runAsPrivileged ❌ Danger
    Security - Should not be running as privileged
    cpuRequestsMissing 😬 Warning
    Efficiency - CPU requests should be set
  3. Interpréter les résultats

    IcôneNiveauSignification
    🎉SuccessCheck réussi
    😬WarningProblème potentiel, à investiguer
    DangerErreur critique, à corriger

Faites échouer le pipeline si des erreurs critiques sont détectées :

Fenêtre de terminal
# Échoue (exit code 3) si au moins un "Danger" est trouvé
polaris audit --audit-path ./k8s/ --set-exit-code-on-danger --format pretty
# Échoue (exit code 4) si le score est inférieur à 80
polaris audit --audit-path ./k8s/ --set-exit-code-below-score 80 --format score
.gitlab-ci.yml
polaris:
stage: validate
image: quay.io/fairwinds/polaris:10.1.4
script:
- polaris audit --audit-path ./k8s/ --set-exit-code-on-danger --format pretty
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"

Polaris peut template un chart Helm et l'auditer :

Fenêtre de terminal
# Auditer un chart local
polaris audit --helm-chart ./my-chart/ --format pretty
# Avec des values personnalisées
polaris audit --helm-chart ./my-chart/ --helm-values values-prod.yaml --format pretty

Trois notions suffisent à lire n'importe quel rapport Polaris : la catégorie du check, qui dit de quoi il parle, sa sévérité, qui dit combien il pèse, et le score final, qui agrège le tout. Comme la sévérité de chaque check est configurable, deux équipes peuvent obtenir des scores différents sur le même manifest. Un score n'a donc de sens qu'à configuration constante.

Polaris organise ses vérifications en trois catégories :

CatégorieCe qu'elle vérifieExemples
SecurityRisques de sécuritérunAsRoot, privileged, hostNetwork, capabilities
EfficiencyUtilisation des ressourcescpuRequests, memoryLimits
ReliabilityStabilité et résilienceprobes, replicas, PDB, imageTag

Chaque check a un niveau de sévérité configurable :

NiveauImpact sur le scoreUsage
ignoreAucunDésactiver un check
warningRéduit légèrement le scoreProblème à corriger
dangerRéduit fortement le scoreProblème critique

Polaris calcule un score de 0 à 100. Chaque check échoué réduit le score selon sa sévérité.

ScoreInterprétation
90-100Excellent, prêt pour la production
70-89Correct, quelques améliorations possibles
50-69Problèmes à corriger avant production
< 50Critique, ne pas déployer

Trois modes d'installation, selon l'usage visé : le binaire pour le travail local et l'exploration, l'image de conteneur pour la CI où l'on veut une version figée, et le chart Helm pour le dashboard et l'admission controller à l'intérieur du cluster. Ces installations sont indépendantes ; rien n'oblige à déployer quoi que ce soit dans un cluster pour auditer des fichiers.

Le binaire est autonome et n'a aucune dépendance à installer. Épinglez le numéro de version : sans cela, vos scores varieront d'une machine à l'autre au fil des sorties.

Fenêtre de terminal
# Linux amd64
VERSION=10.1.4
curl -fsSLO "https://github.com/FairwindsOps/polaris/releases/download/$VERSION/polaris_linux_amd64.tar.gz"
curl -fsSLO "https://github.com/FairwindsOps/polaris/releases/download/$VERSION/checksums.txt"
grep " polaris_linux_amd64.tar.gz$" checksums.txt | sha256sum -c -
sudo tar -xzf polaris_linux_amd64.tar.gz -C /usr/local/bin polaris
# macOS (arm64)
VERSION=10.1.4
curl -fsSLO "https://github.com/FairwindsOps/polaris/releases/download/$VERSION/polaris_darwin_arm64.tar.gz"
curl -fsSLO "https://github.com/FairwindsOps/polaris/releases/download/$VERSION/checksums.txt"
grep " polaris_darwin_arm64.tar.gz$" checksums.txt | sha256sum -c -
sudo tar -xzf polaris_darwin_arm64.tar.gz -C /usr/local/bin polaris
# Vérifier
polaris version

L'image officielle est publiée sur quay.io. Le montage -v rend vos manifests visibles depuis le conteneur, et le chemin passé à --audit-path est celui vu de l'intérieur du conteneur, pas celui de votre poste.

Fenêtre de terminal
docker run --rm -v $(pwd):/audit quay.io/fairwinds/polaris:10.1.4 \
polaris audit --audit-path /audit/k8s/ --format pretty

Le chart installe le dashboard et le webhook d'admission. Les deux s'activent séparément, et il est prudent de commencer par le dashboard seul : le webhook intervient dans le chemin critique des déploiements.

Fenêtre de terminal
# Ajouter le repo Fairwinds
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm repo update
# Installer dashboard + webhook
helm install polaris fairwinds-stable/polaris \
--namespace polaris \
--create-namespace \
--set webhook.enable=true \
--set dashboard.enable=true
# Accéder au dashboard
kubectl port-forward -n polaris svc/polaris-dashboard 8080:80
# Ouvrir http://localhost:8080

Polaris se décline en quatre usages qui ne visent pas le même public : audit pour la CI, fix pour la correction assistée, le dashboard pour la visibilité d'équipe, et l'admission controller pour appliquer les règles au moment du déploiement. Rien n'oblige à les adopter tous, et l'ordre ci-dessous suit celui d'une adoption progressive.

Sans --audit-path, Polaris audite le cluster pointé par votre kubeconfig au lieu de fichiers locaux. Les options se combinent librement pour restreindre la sortie.

Fenêtre de terminal
# Auditer un fichier ou dossier
polaris audit --audit-path ./deployment.yaml --format pretty
# Auditer un cluster (nécessite kubeconfig)
polaris audit --format pretty
# Auditer un namespace spécifique
polaris audit --namespace production --format pretty
# N'afficher que les échecs
polaris audit --audit-path ./k8s/ --only-show-failed-tests --format pretty
# Filtrer par sévérité (danger uniquement)
polaris audit --audit-path ./k8s/ --severity danger --only-show-failed-tests --format pretty

Formats de sortie :

FormatUsage
prettyLisible pour humains (CI logs)
jsonIntégration avec d'autres outils
yamlMême chose en YAML
scoreRetourne uniquement le score (0-100)

Polaris peut corriger automatiquement certains problèmes :

Fenêtre de terminal
polaris fix --files-path ./deployment.yaml --checks all

Ce que fix peut corriger :

  • Ajouter securityContext (runAsNonRoot, readOnlyRootFilesystem, etc.)
  • Ajouter des resources (requests/limits) avec des valeurs par défaut
  • Ajouter des probes (liveness/readiness) avec des placeholders
  • Définir imagePullPolicy: Always
  • Ajouter replicas: 3

Exemple avant/après :

apiVersion: apps/v1
kind: Deployment
metadata:
name: webshop-api
spec:
replicas: 1
template:
spec:
containers:
- name: api
image: mycompany/webshop-api:latest
securityContext:
privileged: true

Le dashboard donne une vue d'ensemble du cluster :

  • Score global par namespace
  • Top des problèmes (les plus fréquents)
  • Détail par workload (Deployment, StatefulSet, etc.)
  • Historique (si configuré avec Fairwinds Insights)

Utile pour :

  • Identifier les namespaces les plus problématiques
  • Prioriser les corrections
  • Montrer l'évolution à l'équipe

L'admission controller intercepte les requêtes kubectl apply et peut :

  • Bloquer les workloads non conformes (mode reject)
  • Alerter sans bloquer (mode warn)

La configuration par défaut convient rarement telle quelle : certains checks ne s'appliquent pas à votre contexte, d'autres méritent au contraire d'être durcis. Trois leviers existent, du plus simple au plus puissant : ajuster la sévérité d'un check existant, exempter un workload précis, ou écrire un custom check en JSON Schema. Tout tient dans un seul fichier de configuration, à versionner avec le code qu'il contrôle.

Créez un fichier polaris-config.yaml :

polaris-config.yaml
checks:
# Désactiver des checks
cpuLimitsMissing: ignore
priorityClassNotSet: ignore
# Changer la sévérité
tagNotSpecified: danger # par défaut: danger
runAsRootAllowed: danger # par défaut: warning
memoryLimitsMissing: warning # par défaut: warning

Utilisez-le avec --config :

Fenêtre de terminal
polaris audit --config polaris-config.yaml --audit-path ./k8s/ --format pretty

Vous pouvez exempter des namespaces ou des workloads spécifiques :

polaris-config.yaml
exemptions:
# Exempter tout kube-system
- namespace: kube-system
rules:
- runAsRootAllowed
- runAsPrivileged
# Exempter un workload spécifique
- namespace: monitoring
controllerNames:
- prometheus-server
rules:
- hostNetworkSet

Vous pouvez aussi ajouter une annotation directement sur le workload :

metadata:
annotations:
polaris.fairwinds.com/exempt: "true"
# ou exempter un check spécifique
polaris.fairwinds.com/runAsRootAllowed-exempt: "true"

Polaris permet de créer vos propres règles avec JSON Schema. C'est la fonctionnalité la plus puissante pour adapter Polaris à vos besoins.

Exemple : interdire les images de quay.io

polaris-config.yaml
checks:
imageRegistry: warning
customChecks:
imageRegistry:
successMessage: Image comes from allowed registries
failureMessage: Image should not be from quay.io
category: Security
target: Container
schema:
'$schema': https://json-schema.org/draft/2019-09/schema
type: object
properties:
image:
type: string
not:
pattern: ^quay.io

Test :

Fenêtre de terminal
polaris audit --config polaris-config.yaml --audit-path ./deployment-quay.yaml --format pretty

Résultat :

Container app
imageRegistry 😬 Warning
Security - Image should not be from quay.io

Options disponibles pour les custom checks :

OptionDescription
targetCible : Container, PodSpec, PodTemplate, Controller, ou apps/Deployment
categorySecurity, Efficiency, ou Reliability
controllers.includeLimiter à certains types (ex: [Deployment, StatefulSet])
containers.excludeExclure initContainer ou container
schemaJSON Schema à valider

Exemple avancé : vérifier les limites de ressources

polaris-config.yaml
checks:
resourceLimits: warning
customChecks:
resourceLimits:
successMessage: Resource limits are within range
failureMessage: Memory should be between 128Mi and 4Gi
category: Efficiency
target: Container
containers:
exclude:
- initContainer
schema:
'$schema': https://json-schema.org/draft/2019-09/schema
type: object
required:
- resources
properties:
resources:
type: object
required:
- limits
properties:
limits:
type: object
required:
- memory
properties:
memory:
type: string
resourceMinimum: 128Mi
resourceMaximum: 4Gi

Ces quatre pratiques évitent les deux échecs classiques d'une adoption de Polaris : un score qui varie sans raison apparente d'un run à l'autre, et un blocage brutal de tous les pipelines dès le premier jour.

Séparer les configurations par environnement permet d'appliquer des seuils différents en développement et en production, et de suivre leur évolution dans Git au même titre que les manifests.

mon-projet/
├── k8s/
│ ├── deployment.yaml
│ └── service.yaml
├── polaris/
│ ├── config-base.yaml # Règles communes
│ ├── config-dev.yaml # Seuils relâchés pour dev
│ └── config-prod.yaml # Seuils stricts pour prod
└── .gitlab-ci.yml

Cette montée en exigence s'étale sur plusieurs mois. Ne passez à la phase suivante qu'une fois la précédente stabilisée : un seuil imposé trop tôt apprend aux équipes à contourner l'outil plutôt qu'à corriger les manifests.

PhaseScore minimumSévérité bloquanteDurée
1. ObservationAucun (rapport seul)Aucune2 semaines
2. Warning50Danger uniquement1 mois
3. Strict70Warning + DangerProduction
4. Optimal85ToutLong terme

Une exemption ciblée garde la trace du workload concerné et de la règle levée. Un check désactivé globalement, lui, ne laisse aucune indication sur la raison de sa désactivation ni sur son périmètre réel.

# ❌ Mauvais : désactiver globalement
checks:
runAsRootAllowed: ignore
# ✅ Bon : exempter uniquement ce qui doit l'être
exemptions:
- namespace: kube-system
controllerNames:
- kube-proxy
rules:
- runAsRootAllowed

En CI, seuls les échecs présentent un intérêt : cette option retire du rapport tous les checks réussis et rend les logs réellement lisibles.

Fenêtre de terminal
# Moins verbeux, plus lisible dans les logs CI
polaris audit --audit-path ./k8s/ \
--set-exit-code-on-danger \
--only-show-failed-tests \
--format pretty

La plupart des surprises viennent d'un écart de configuration ou de version entre le poste du développeur et le pipeline. Épingler les deux élimine la majorité des cas avant même de chercher plus loin.

SymptômeCauseSolution
Score différent d'un run à l'autreConfiguration différenteToujours passer --config explicitement
Passe en local mais échoue en CIVersion Polaris différenteÉpingler la version dans le CI
Check ne s'applique pastarget mal configuréVérifier target: Container vs target: PodSpec
Webhook bloque tropMode reject trop strictPasser en mode warn puis corriger progressivement
Exemption ignoréeMauvais namespace/controllerNameVérifier l'orthographe exacte
Custom check ne match pasJSON Schema incorrectTester avec un outil JSON Schema validator

La sortie json expose le résultat de chaque check, y compris ceux qui réussissent, là où le format pretty les masque.

Fenêtre de terminal
# Voir les checks actifs
polaris audit --config ./config.yaml --audit-path ./deploy.yaml --format json | jq '.Results[].PodResult.ContainerResults[].Results'

ConceptCe qu'il faut retenir
polaris auditAudite YAML, cluster ou Helm chart
--set-exit-code-on-dangerFait échouer le CI sur erreurs critiques
--set-exit-code-below-scoreFait échouer le CI sous un seuil
polaris fixCorrige automatiquement (à relire !)
Custom checksJSON Schema pour vos règles métier
ExemptionsPar namespace, workload ou annotation
Score0-100, visez > 70 pour la prod

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn