
kube-score analyse statiquement vos manifests Kubernetes et liste les défauts de fiabilité et de sécurité, avant tout déploiement. Un kubectl apply accepte un manifest sans ressources, sans probes ni securityContext ; kube-score, lui, les signale. Ce guide montre comment l'installer, interpréter ses recommandations sur de vraies sorties, l'intégrer en CI/CD, et le situer face à Polaris, KubeLinter et Trivy. Pour utilisateurs Kubernetes intermédiaires. Outil open source (MIT, Go) ; sorties d'un lab réel avec kube-score 1.20.0.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Scanner un manifest avec kube-score
- Interpréter les checks de fiabilité et de sécurité
- Corriger un manifest et gérer les faux positifs
- Bloquer un déploiement non conforme en CI/CD
Prérequis
Section intitulée « Prérequis »- Des manifests Kubernetes (Deployment, Service...) à analyser
- Docker ou un binaire kube-score (aucun accès cluster requis)
Ce qu'est kube-score
Section intitulée « Ce qu'est kube-score »kube-score fait de l'analyse statique : il lit du YAML (un fichier, un dossier, ou l'entrée standard) et n'a pas besoin d'accès au cluster. Pour chaque objet, il applique une série de checks et attribue un verdict par recommandation : [OK], [WARNING], [CRITICAL] ou [SKIPPED].
Sa valeur est de viser deux dimensions à la fois : la fiabilité (ressources, probes, réplicas, PodDisruptionBudget, anti-affinité) et la sécurité (tag d'image fixe, securityContext, NetworkPolicy). Il couvre 39 checks dans la version 1.20.0, dont une partie optionnelle.
Installer kube-score
Section intitulée « Installer kube-score »docker run --rm -v "$(pwd):/project" zegl/kube-score:latest score /project/deploy.yaml# via krew (plugin kubectl)kubectl krew install scorekubectl score --helpbrew install kube-scorekube-score versionPremier scan : analyser un manifest
Section intitulée « Premier scan : analyser un manifest »Prenons un Deployment minimal, du genre qu'on écrit vite pour tester. Il passe kubectl apply sans broncher :
apiVersion: apps/v1kind: Deploymentmetadata: name: webspec: replicas: 1 selector: matchLabels: { app: web } template: metadata: labels: { app: web } spec: containers: - name: web image: nginx:latestOn le passe à kube-score via l'entrée standard (-) :
kube-score score - < deploy.yamlapps/v1/Deployment web [CRITICAL] Container Image Tag · web -> Image with latest tag Using a fixed tag is recommended to avoid accidental upgrades [CRITICAL] Container Resources · web -> CPU/Memory request and limit is not set [CRITICAL] Container Security Context User Group ID [CRITICAL] Container Security Context ReadOnlyRootFilesystem [CRITICAL] Container Ephemeral Storage Request and Limit [CRITICAL] Pod NetworkPolicy · The pod does not have a matching NetworkPolicySix recommandations [CRITICAL], et surtout : le programme sort avec le code 1. C'est le point clé pour la CI. Chaque ligne dit quoi corriger : tag d'image figé, ressources, contexte de sécurité, NetworkPolicy.
Comprendre les checks clés
Section intitulée « Comprendre les checks clés »kube-score regroupe ses 39 checks autour de quelques intentions. Les plus fréquents :
| Check (ID) | Ce qu'il vérifie | Dimension |
|---|---|---|
container-image-tag | un tag fixe, jamais :latest | sécurité / repro |
container-resources | requests et limits CPU/mémoire définis | fiabilité |
container-security-context-* | runAsNonRoot, readOnlyRootFilesystem, non privileged | sécurité |
pod-probes | probes readiness et liveness présentes et différentes | fiabilité |
deployment-replicas | au moins 2 réplicas (seuil configurable) | fiabilité |
pod-networkpolicy | une NetworkPolicy cible le pod | sécurité |
deployment-has-poddisruptionbudget | un PDB protège le Deployment | fiabilité |
Corriger et re-scanner
Section intitulée « Corriger et re-scanner »Améliorons le manifest avec tout ce qu'un Deployment sérieux devrait avoir : tag fixe, ressources, securityContext, probes distinctes, deux réplicas.
spec: replicas: 2 template: spec: securityContext: runAsNonRoot: true containers: - name: web image: nginx:1.27.3-alpine imagePullPolicy: IfNotPresent resources: requests: { cpu: "100m", memory: "64Mi" } limits: { cpu: "200m", memory: "128Mi" } securityContext: readOnlyRootFilesystem: true privileged: false readinessProbe: httpGet: { path: /, port: 80 } livenessProbe: httpGet: { path: /healthz, port: 80 }Re-scannons. Le verdict s'améliore nettement, mais kube-score reste exigeant :
[CRITICAL] Ephemeral Storage request/limit is not set[CRITICAL] The pod does not have a matching NetworkPolicy[CRITICAL] The container is running with a low user ID (< 10000)[CRITICAL] ImagePullPolicy is not set to Always[CRITICAL] No matching PodDisruptionBudget was found[WARNING] Deployment does not have a host podAntiAffinity setC'est volontaire : kube-score pousse les standards de production (PDB, NetworkPolicy, anti-affinité, stockage éphémère borné, UID élevé). À vous de décider lesquels sont pertinents dans votre contexte, ce qui mène à la section suivante.
Gérer les faux positifs
Section intitulée « Gérer les faux positifs »Certains checks sont opinionated et ne collent pas à tous les contextes. L'exemple classique : pod-networkpolicy exige une NetworkPolicy même si votre CNI ne les applique pas. kube-score offre deux leviers pour ne pas crouler sous le bruit.
Au niveau de la commande, ignorer un check globalement :
kube-score score deploy.yaml --ignore-test pod-networkpolicyAu niveau d'un objet précis, via une annotation dans le manifest :
metadata: annotations: kube-score/ignore: pod-networkpolicy,container-image-pull-policyFormats de sortie et codes retour
Section intitulée « Formats de sortie et codes retour »Le format se choisit avec --output-format : human (défaut, lisible), ci (une ligne par résultat, idéal pour les logs), json (structuré), sarif (pour le code scanning GitHub).
kube-score score deploy.yaml --output-format ci[OK] web apps/v1/Deployment[CRITICAL] web apps/v1/Deployment: The pod does not have a matching NetworkPolicy[SKIPPED] web apps/v1/Deployment: Skipped because container-cpu-requests-equal-limits is ignoredCôté code retour : kube-score sort avec 1 dès qu'un [CRITICAL] est présent. Pour échouer aussi sur les warnings, ajoutez --exit-one-on-warning. C'est ce comportement qui permet de bloquer un pipeline.
Intégrer kube-score en CI/CD
Section intitulée « Intégrer kube-score en CI/CD »Le principe : laisser kube-score échouer le job par son code retour. Helm et Kustomize ne produisant pas de YAML statique, on les rend d'abord (helm template), puis on pipe vers kube-score.
Voici un workflow GitHub Actions qui scanne les manifests et remonte les résultats dans l'onglet Security (format SARIF), avec les actions épinglées par commit (SHA) comme l'exige la sécurité de la chaîne d'approvisionnement :
name: kube-scoreon: pull_request: paths: ['manifests/**']
permissions: {}
jobs: scan: runs-on: ubuntu-latest permissions: contents: read security-events: write # upload SARIF steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: persist-credentials: false
- name: Analyser les manifests run: | docker run --rm -v "$PWD:/project" zegl/kube-score:latest \ score /project/manifests/*.yaml \ --output-format sarif > results.sarif continue-on-error: true
- name: Publier dans le code scanning uses: github/codeql-action/upload-sarif@dd903d2e4f5405488e5ef1422510ee31c8b32357 # v3 with: sarif_file: results.sarifkube-score face aux alternatives
Section intitulée « kube-score face aux alternatives »kube-score n'est pas seul. Le choix dépend de ce que vous cherchez.
| Outil | Périmètre | Se distingue par |
|---|---|---|
| kube-score | fiabilité + sécurité des manifests | simple, sans cluster, pédagogique |
| KubeLinter (Red Hat) | lint statique, production-readiness | checks custom (templates) |
| Polaris (Fairwinds) | policy engine | dashboard + admission controller |
| kubesec | sécurité uniquement | score numérique + API |
| Trivy (Aqua) | vulnérabilités + config + secrets | suite large, cluster live |
En clair : kube-score est le bon point de départ, focalisé et lisible. Passez à KubeLinter ou Polaris si vous voulez des règles maison ou un contrôle à l'admission, et à Trivy pour couvrir aussi les vulnérabilités d'images. Les trois sont complémentaires de kube-score, pas redondants.
- Analyse statique : kube-score ne voit pas l'état réel du cluster (un Polaris en admission ou
trivy k8sle complètent). - YAML statique seulement : Helm/Kustomize doivent être rendus avant (
helm template | kube-score score -). - Checks opinionated : certains (NetworkPolicy,
imagePullPolicy: Always, pas deNodePort) peuvent générer des faux positifs selon le contexte, d'où--ignore-test. - Pas de règles personnalisées : on active/désactive les checks fournis, on n'en écrit pas (contrairement à KubeLinter/Polaris).
À retenir
Section intitulée « À retenir »- kube-score analyse les manifests sans cluster et vise fiabilité + sécurité (39 checks en 1.20).
- Verdicts
[OK]/[WARNING]/[CRITICAL]; il sort en code 1 dès un[CRITICAL], d'où son usage en CI. - Les checks clés : tag fixe, resources, securityContext, probes, réplicas, NetworkPolicy, PDB.
- Les checks opinionated se filtrent avec
--ignore-testou l'annotationkube-score/ignore, en documentant pourquoi. - En CI :
docker run zegl/kube-score+ format SARIF vers le code scanning, actions épinglées par SHA. - C'est un point de départ : KubeLinter/Polaris pour les règles custom, Trivy pour les vulnérabilités.