Aller au contenu principal

Cours Après-midi - Service Mesh, Sécurité & Gestion des accès

Service Mesh : architecture et historique

Un service mesh est une couche d'infrastructure logicielle destinée à contrôler la communication entre les services.

Il se compose de deux plans :

  • Le Data Plane : ensemble de proxys réseau (souvent Envoy) déployés aux côtés de chaque service pour intercepter le trafic entrant et sortant
  • Le Control Plane : cerveau du mesh — configure les proxys, assure la découverte de services, centralise l'observabilité

Pourquoi un service mesh dans une architecture microservices ?

  • Les problématiques de droits d'accès n'ont plus besoin d'être codées dans chaque microservice
  • Les flux réseau sont automatiquement chiffrés de bout en bout (mTLS)
  • La métrologie des communications inter-services est automatisée

Historique

  • Pré-2015 : Solutions ad hoc par langage (Hystrix pour circuit breaking, Ribbon pour load balancing en Java)
  • 2015 : Linkerd (Buoyant) — premier service mesh populaire, résilience et sécurité sans modification du code
  • 2016 : Envoy (Lyft) — proxy haute performance, devient le sidecar standard
  • 2017 : Istio (Google + IBM + Lyft) — basé sur Envoy, contrôle complet du réseau microservices
  • 2018 : Istio 1.0 — version stable (trafic, sécurité, télémétrie)
  • 2020 : Istiod — consolidation de plusieurs composants en un seul binaire

Architecture d'Istio

Documentation officielle : https://istio.io/latest/docs/ops/deployment/architecture/

Istio injecte automatiquement un proxy sidecar Envoy dans chaque pod. Ce proxy intercepte tout le trafic et applique les politiques définies dans le control plane (Istiod).


Comparatif des solutions de Service Mesh

CritèreIstioLinkerdConsul
SécuritémTLS, RBAC, JWTmTLS, politiques simplifiéesmTLS, ACLs
Gestion du traficRoutage avancé, A/B, canariesRoutage de base, load balancingRoutage avancé
DéploiementComplexeSimpleModérément complexe
PerformancePeut introduire de la latenceOptimiséLatence minimale
ObservabilitéTracing + Metrics + LogsTracing basique + MetricsMetrics + Logs

Résumé :

  • Istio → environnements complexes, grand nombre de services, fonctionnalités avancées
  • Linkerd → bon compromis performance/simplicité, environnements moyens à grands
  • Consul → intégration HashiCorp, multi-plateforme (VMs + K8s)
  • Cilium → mesh basé sur eBPF, déjà utilisé comme CNI

mTLS et sécurité des échanges

mTLS (mutual TLS) assure l'authentification mutuelle : chaque service vérifie le certificat de l'autre avant d'établir la connexion.

Contrairement au TLS classique (client vérifie serveur), mTLS garantit que les deux parties sont légitimes.

Citadel (Istio)

Citadel est la PKI interne d'Istio : il crée et signe les paires clé/certificat pour chaque compte de service, surveille les durées de vie et effectue la rotation automatique.

SPIFFE / SPIRE

Istio utilise le standard SPIFFE pour les identités de service. Chaque workload reçoit une identité SVID (SPIFFE Verifiable Identity Document). SPIRE est l'implémentation de référence de SPIFFE.

Politique d'authentification

# Activer mTLS pour un namespace
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "default"
namespace: "ns1"
spec:
peers:
- mtls: {}

Politique d'autorisation

# Autoriser sleep (ns/default) et le namespace dev à accéder à httpbin v1 dans foo
# uniquement en GET avec JWT Google valide
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: httpbin
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
version: v1
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/sleep"]
- source:
namespaces: ["dev"]
to:
- operation:
methods: ["GET"]
when:
- key: request.auth.claims[iss]
values: ["https://accounts.google.com"]

Modèles d'implémentation : Sidecar, Ambient, Cluster Mesh

CaractéristiqueSidecarAmbient MeshCluster Mesh
MaturitéMature (depuis 2016)En développementÉmergent (~2020)
Complexité déploiementÉlevée (injection dans chaque pod)Moyenne (proxys au niveau nœud)Élevée (multi-cluster)
Overhead ressourcesImportantRéduitVariable
AvantagesGranularité fine, isolationSimplicité, moins d'overheadHaute résilience, multi-cluster
ExemplesIstio, Linkerd, Consul ConnectIstio Ambient (expérimental)Cilium Cluster Mesh, Linkerd Multi-cluster

Le modèle Ambient Mesh d'Istio supprime le besoin d'injecter un sidecar dans chaque pod en utilisant des proxys au niveau du nœud — réduisant l'overhead de ressources mais encore en phase de maturation.


Sécurité Kubernetes : approche DevSecOps

La sécurité Kubernetes n'est pas une couche ajoutée en fin de projet : elle doit être intégrée à chaque phase du cycle de vie DevOps.

Domaines de sécurité à couvrir

  • Identités et accès (IAM) : Qui peut faire quoi sur le cluster (RBAC, OIDC, ServiceAccounts)
  • Sécurité réseau : Chiffrement en transit (mTLS), Network Policies
  • Sécurité des images : Scan de vulnérabilités, pas de latest, registres privés
  • Gestion des secrets : Vault, Sealed Secrets, External Secrets Operator
  • Conformité et audit : kube-bench (CIS Benchmark), audit logs, Falco

Outils par phase DevOps

PhaseOutilsRôle
PlanOPA, KyvernoPolitiques de conformité déclaratives
CodeSnyk, TrivyScan des dépendances et vulnérabilités
BuildGitLab CI, TektonPipelines sécurisés, registres privés
TestSonarQube, Trivy, ClairAnalyse statique, scan d'images
ReleaseGitleaks, Snyk IaCDétection de secrets exposés, scan Helm
DeployArgoCD, FluxGitOps — pas d'accès prod direct aux devs
OperateVault, Vault OperatorGestion des secrets et rotation automatique
MonitorFalco, TraceeDétection comportementale en temps réel

Admission Controllers : OPA et Kyverno

OPA (Open Policy Agent) et Kyverno permettent de définir des règles de sécurité appliquées automatiquement à chaque ressource soumise à l'API server :

  • Bloquer les images avec latest
  • Imposer des resources.requests sur tous les pods
  • Refuser les pods avec privileged: true
  • Forcer l'ajout de labels obligatoires

Kyverno utilise des policies en YAML natif Kubernetes (plus accessible). OPA utilise le langage Rego (plus expressif).


HashiCorp Vault pour la gestion des secrets

Vault centralise la gestion des secrets avec audit complet, rotation automatique et politiques d'accès granulaires.

Architecture Vault dans Kubernetes

Application (Pod)

│ Token ServiceAccount K8s

Vault (Kubernetes Auth Method)

│ Secret dynamique ou statique

Application reçoit la valeur du secret

Vault Operator

Le Vault Kubernetes Operator permet de synchroniser des secrets Vault vers des Kubernetes Secrets natifs :

  • Les pods déclarent les secrets dont ils ont besoin via des CRDs
  • L'Operator récupère les secrets depuis Vault et les injecte en tant que Kubernetes Secrets
  • Rotation automatique quand Vault renouvelle les baux

Avantages par rapport aux Kubernetes Secrets natifs

AspectKubernetes SecretsVault
Chiffrement au reposOptionnel (etcd encrypt)Natif
AuditLimité (audit logs API)Complet (qui a accès à quoi)
RotationManuelleAutomatique
Secrets dynamiquesNonOui (DB, PKI, cloud creds)
Multi-clusterNonOui

RBAC et gestion des accès utilisateurs

A REDIGER :

  • Rappel RBAC : Role, ClusterRole, RoleBinding, ClusterRoleBinding
  • ServiceAccounts vs utilisateurs (certificats client, OIDC)
  • Intégration LDAP/AD (Kubi, Dex, Keycloak)
  • Namespace isolation par équipe : ResourceQuota + LimitRange + RBAC
  • Audit logging : qu'est-ce qui est loggé, comment l'exploiter

ResourceQuota : limiter les ressources et les objets d'un namespace

ResourceQuota peut restreindre non seulement les ressources CPU/RAM, mais aussi le nombre d'objets créables dans un namespace :

# Quota sur les objets
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quotas
spec:
hard:
pods: "8"
configmaps: "10"
secrets: "10"
persistentvolumeclaims: "5"
services: "5"
services.loadbalancers: "2"
requests.storage: "20Gi"

Utile pour éviter qu'une équipe monopolise les LoadBalancers cloud (coûteux) ou crée trop de PVCs.

LimitRange : valeurs par défaut et min/max par conteneur

LimitRange complète ResourceQuota en définissant des contraintes par conteneur dans un namespace — y compris des valeurs par défaut appliquées automatiquement aux pods qui ne définissent pas de requests/limits :

apiVersion: v1
kind: LimitRange
metadata:
name: cpu-limits
spec:
limits:
- type: Container
default:
cpu: "1000m"
memory: "256Mi"
defaultRequest:
cpu: "500m"
memory: "128Mi"
min:
cpu: "200m"
max:
cpu: "800m"
kubectl apply -f cpu-limits.yaml -n dev

Tout pod déployé dans ce namespace sans resources se voit automatiquement injecter les valeurs default et defaultRequest. LimitRange s'applique aussi aux PVCs (min/max storage) :

limits:
- type: PersistentVolumeClaim
max:
storage: 20Gi
min:
storage: 1Gi

DevSecOps pour les workloads existants

A REDIGER :

  • Comment appliquer une démarche DevSecOps à des workloads déjà en production
  • Stratégie progressive : audit → correction des critiques → automatisation
  • Outils de scanning continu (Trivy, Falco en mode "observe")
  • Introduction des Network Policies sans casser l'existant (log mode first)
  • Migration vers Vault sans downtime

Ingress vs Gateway API

La Gateway API est la nouvelle génération d'Ingress, standardisée par le SIG Network de Kubernetes.

Comparaison

AspectIngressGateway API
MaturitéGA depuis K8s 1.1GA depuis K8s 1.24
ExpressivitéLimitée (HTTP/HTTPS basique)Avancée (HTTP, gRPC, TCP, UDP)
Séparation des rôlesFaibleForte (infra / namespace / dev)
Routage avancéAnnotations propriétairesNatif (HTTPRoute, canary, header matching)
Multi-protocolesNonOui (gRPC, WebSocket, TLS passthrough)

Modèle de rôles Gateway API

GatewayClass  →  géré par l'équipe infra (choix de l'implémentation)

Gateway → géré par l'équipe plateforme (ports, TLS)

HTTPRoute → géré par l'équipe applicative (règles de routage)

Exemple HTTPRoute avec canary

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-route
spec:
parentRefs:
- name: prod-gateway
rules:
- matches:
- headers:
- name: "X-Canary"
value: "true"
backendRefs:
- name: my-app-v2
port: 80
weight: 100
- backendRefs:
- name: my-app-v1
port: 80
weight: 90
- name: my-app-v2
port: 80
weight: 10

La Gateway API est recommandée pour les nouveaux clusters. La migration depuis Ingress est progressive — les deux peuvent coexister.