Les extensions sont les mécanismes natifs par lesquels Kubernetes permet d’étendre son propre API et son comportement. Ce sont des points d’accroche fournis par Kubernetes lui-même — les plugins s’appuient sur ces mécanismes pour fonctionner.

Règle clé :

  • Une extension = un mécanisme d’extensibilité fourni par Kubernetes
  • Un plugin = un outil tiers qui utilise ces mécanismes

Vue d’ensemble des mécanismes d’extension

kube-apiserver
├── CRD              → nouveaux types de ressources dans l'API
├── API Aggregation  → serveurs API tiers greffés sur l'API principale
├── Admission Webhooks
│   ├── Mutating     → modifier une ressource à la volée avant persistance
│   └── Validating   → accepter ou rejeter une ressource selon des règles
└── kube-scheduler   → Scheduler Plugins (filtres et scores custom)

Nœuds workers
├── CNI              → interface réseau (plugin réseau branché ici)
├── CSI              → interface stockage (driver de volumes custom)
└── Device Plugins   → exposition de matériel GPU/FPGA aux pods

1. CRD — Custom Resource Definition

Les CRDs permettent d’ajouter de nouveaux types d’objets à l’API Kubernetes, au même titre que Pod, Deployment ou Service.

Exemple : définir un CRD Database

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: databases.monoperateur.io
spec:
  group: monoperateur.io
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              engine:
                type: string
                enum: [postgres, mysql, redis]
              version:
                type: string
              replicas:
                type: integer
                minimum: 1
  scope: Namespaced
  names:
    plural: databases
    singular: database
    kind: Database
    shortNames: [db]

Une fois le CRD appliqué, on peut créer des objets Database comme n’importe quelle ressource native :

apiVersion: monoperateur.io/v1
kind: Database
metadata:
  name: ma-base-prod
spec:
  engine: postgres
  version: "16"
  replicas: 3
kubectl get databases
kubectl describe database ma-base-prod

Les CRDs sont la brique fondamentale sur laquelle reposent cert-manager, argocd, KEDA, velero et la quasi-totalité des plugins modernes.


2. Operator Pattern

Un Operator combine un CRD (nouvelle ressource) + un contrôleur (boucle de réconciliation) pour automatiser la gestion d’applications complexes.

Utilisateur kubectl apply → CRD (ex: Database)
                                │
                           Contrôleur (Operator)
                           surveille l'état désiré
                                │
                           Agit sur le cluster
                           (crée des Pods, Secrets,
                            Services, PVCs…)
                                │
                           Réconcilie en continu
                           état réel == état désiré

Exemples d’Operators connus

OperatorCe qu’il gère
cert-managerCertificate, ClusterIssuer → gère le cycle de vie TLS
KEDAScaledObject → pilote le HPA selon des métriques externes
ArgoCDApplication → synchronise Git avec le cluster
Prometheus OperatorServiceMonitor, PrometheusRule → configure Prometheus via CRDs
VeleroBackup, Schedule, Restore → orchestre les sauvegardes

3. Admission Webhooks

Les webhooks d’admission permettent d’intercepter chaque appel API (création, modification, suppression) pour :

  • Mutating : modifier la ressource à la volée (injecter un sidecar, ajouter des labels)
  • Validating : accepter ou rejeter selon des règles métier
kubectl apply
     │
     ▼
kube-apiserver
     │
     ├── Mutating Admission Webhooks   ← modifient la ressource
     │         (ex: injecter un sidecar Istio, forcer des limites)
     │
     ├── Validation de schéma (OpenAPI)
     │
     ├── Validating Admission Webhooks ← acceptent ou rejettent
     │         (ex: OPA Gatekeeper, Kyverno)
     │
     └── Persistance dans etcd

Exemple : MutatingWebhookConfiguration (injection de sidecar)

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: sidecar-injector
webhooks:
- name: sidecar.monoperateur.io
  rules:
  - apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
    operations: ["CREATE"]
  clientConfig:
    service:
      name: sidecar-injector-svc
      namespace: default
      path: /mutate
    caBundle: <base64-ca>
  admissionReviewVersions: ["v1"]
  sideEffects: None
  namespaceSelector:
    matchLabels:
      injection: enabled              # uniquement les namespaces avec ce label

Exemple : ValidatingWebhookConfiguration (règle custom)

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: no-latest-tag
webhooks:
- name: validate.images.io
  rules:
  - apiGroups: ["apps"]
    apiVersions: ["v1"]
    resources: ["deployments"]
    operations: ["CREATE", "UPDATE"]
  clientConfig:
    service:
      name: image-validator-svc
      namespace: default
      path: /validate
    caBundle: <base64-ca>
  admissionReviewVersions: ["v1"]
  sideEffects: None
  failurePolicy: Fail               # rejette si le webhook est injoignable

4. API Aggregation Layer

Permet de greffer un serveur API tiers directement sur l’API Kubernetes. L’objet APIService délègue des requêtes vers un serveur externe.

apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  name: v1beta1.metrics.k8s.io
spec:
  service:
    name: metrics-server
    namespace: kube-system
  group: metrics.k8s.io
  version: v1beta1
  insecureSkipTLSVerify: true
  groupPriorityMinimum: 100
  versionPriority: 100

C’est ainsi que kubectl top pods fonctionne : metrics-server est un serveur API agrégé.


5. CNI — Container Network Interface

Le CNI est l’interface standardisée par laquelle Kubernetes délègue la gestion réseau à un plugin externe. À la création d’un pod, kubelet appelle le binaire CNI installé sur le nœud.

kubelet crée un pod
   │
   ▼
Appelle le plugin CNI (ex: /opt/cni/bin/cilium)
   │
   ▼
Le plugin CNI configure :
  - l'interface réseau du pod (veth pair)
  - l'adresse IP du pod
  - les routes
  - les politiques réseau

Implémentations : cilium, Calico, Flannel, Weave.


6. CSI — Container Storage Interface

Le CSI est l’interface standardisée pour les drivers de stockage. Il permet d’utiliser n’importe quel système de stockage (Ceph, NFS, AWS EBS, GCP PD…) sans modifier le code Kubernetes.

# StorageClass utilisant un driver CSI
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-sc
provisioner: ebs.csi.aws.com          # driver CSI AWS EBS
parameters:
  type: gp3
  encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
# PVC qui utilise cette StorageClass
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mon-volume
spec:
  storageClassName: ebs-sc
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 20Gi

7. Device Plugins

Permettent d’exposer des ressources matérielles custom (GPU NVIDIA, FPGA, TPU) aux pods via le kubelet.

# Pod demandant un GPU via Device Plugin
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
  - name: cuda-app
    image: nvidia/cuda:12.0-base
    resources:
      limits:
        nvidia.com/gpu: 1             # ressource exposée par le Device Plugin NVIDIA

Récapitulatif : Extensions vs Plugins

ExtensionPlugin
NatureMécanisme natif KubernetesOutil tiers installé dans le cluster
Fourni parLe projet KubernetesLa communauté / éditeurs
ExemplesCRD, Webhook, CNI, CSI, API Aggregationcert-manager, ArgoCD, KEDA, Cilium
RelationFournit les points d’accrocheUtilise les extensions pour fonctionner
Sans pluginFonctionnel mais limitéNécessite les extensions comme socle

Liens