mTLS service mesh — runbook d'activation Linkerd¶
AKKO embarque un sub-chart akko-mtls (ADR-037) qui enveloppe Linkerd
pour chiffrer et authentifier mutuellement chaque appel pod-à-pod
dans le namespace akko. Désactivé par défaut — cette page
documente l'activation lorsque vous décidez de l'enclencher.
Pourquoi mTLS¶
Aujourd'hui, chaque appel service-à-service (Trino → Polaris, Airflow → PostgreSQL, ADEN → OPA, …) circule en clair sur HTTP. Les NetworkPolicy contrôlent qui peut parler à qui, mais pas ce qui transite. mTLS apporte deux garanties :
- Chiffrement — Un pod compromis ou un opérateur malveillant
avec
kubectl execne peut plus capturer du trafic sensible via tcpdump. - Authentification mutuelle — Chaque pod prouve son identité via un certificat éphémère émis par Linkerd. Plus de "confiance aveugle" entre services partageant un namespace.
Bénéfice conformité : les contrôles SOC2 / ISO27001 / PCI-DSS sur le chiffrement en transit sont satisfaits sans configuration par-service.
Pourquoi Linkerd (et pas Istio / Cilium)¶
Voir ADR-037. Version courte :
- Linkerd est CNCF Graduated, Apache 2.0, gouvernance Foundation-neutre
- ~10 Mo RAM par sidecar (Istio est 15× plus lourd ; coule la box démo Netcup)
- CNI-agnostique — fonctionne sur k3s/EKS/GKE existants sans rupture
- Un seul sub-chart, pas d'explosion de couplage Lego
Pré-requis¶
- Kubernetes 1.27+ (Linkerd 2.16 le requiert)
- cert-manager déjà installé (réutilisé comme issuer d'identité Linkerd)
- Helm 3.13+
- ~500 Mo de RAM libre cluster-wide pour les sidecars
- Un redémarrage one-shot des pods (l'injection se fait à l'admission)
Activation¶
Étape 1 — Installer les CRD Linkerd (one-time par cluster)¶
helm repo add linkerd https://helm.linkerd.io/stable
helm repo update
helm install linkerd-crds linkerd/linkerd-crds \
-n linkerd --create-namespace
Étape 2 — Installer le control plane Linkerd¶
L'ancre de confiance + le certificat d'issuer sont mieux provisionnés
via cert-manager. AKKO fournit un exemple Issuer aligné avec le
ClusterIssuer wildcard existant :
# Générer une ancre de confiance cluster-wide (CA root, gardée hors-ligne)
step certificate create root.linkerd.cluster.local \
ca.crt ca.key --profile root-ca \
--no-password --insecure
# Générer le cert d'issuer per-cluster
step certificate create identity.linkerd.cluster.local \
issuer.crt issuer.key --profile intermediate-ca \
--not-after 8760h --no-password --insecure \
--ca ca.crt --ca-key ca.key
# Installer le control plane Linkerd avec les certs
helm install linkerd-control-plane linkerd/linkerd-control-plane \
-n linkerd \
--set-file identityTrustAnchorsPEM=ca.crt \
--set-file identity.issuer.tls.crtPEM=issuer.crt \
--set-file identity.issuer.tls.keyPEM=issuer.key
Étape 3 — Activer le sub-chart AKKO mTLS¶
helm upgrade akko helm/akko -n akko \
--set akko-mtls.enabled=true \
--set akko-mtls.injectNamespace=true \
-f helm/examples/values-domain.yaml \
-f helm/examples/values-dev-secrets.yaml
Étape 4 — Redémarrer les workloads AKKO pour injecter les sidecars¶
kubectl rollout restart deploy -l app.kubernetes.io/part-of=akko -n akko
kubectl rollout restart statefulset -l app.kubernetes.io/part-of=akko -n akko
Cela redémarre ~50 deployments en rolling — bascule cluster complète typiquement ~5 min sur la box démo Netcup.
Étape 5 — Vérifier que mTLS est actif¶
Installer le CLI Linkerd :
Lancer le check cluster :
Attendu : chaque section ✓.
Vérifier la handshake mTLS sur un appel échantillon :
Chercher "tls": "true" dans la sortie.
Déploiement progressif (recommandé)¶
- Sprint N (audit) —
injectNamespace=false. Choisir un workload (par exempleakko-akko-aden), annoter son pod template aveclinkerd.io/inject: enabled, redémarrer, observerlinkerd checkpendant 24h. - Sprint N+1 (audit cluster-wide) —
injectNamespace=true, redémarrer tous les workloads, surveiller la métrique Prometheusrequest_total{tls="true"}qui doit atteindre ~100%. - Sprint N+2 (enforce) — annoter chaque workload avec
config.linkerd.io/default-inbound-policy: cluster-authenticatedpour que les requêtes plaintext soient REJETÉES.
Dépannage¶
Expiration du cert issuer Linkerd¶
Linkerd utilise par défaut une durée de vie de 24h avec auto-rotation.
Si linkerd check indique l'expiration prochaine de l'issuer, lancer :
helm upgrade linkerd-control-plane linkerd/linkerd-control-plane \
-n linkerd \
--set-file identityTrustAnchorsPEM=ca.crt \
--set-file identity.issuer.tls.crtPEM=issuer-renewed.crt \
--set-file identity.issuer.tls.keyPEM=issuer-renewed.key \
--reuse-values
Pods bloqués en pending après redémarrage¶
L'injection sidecar ajoute ~50 Mo de demande mémoire par pod. Si
Netcup atteint son plafond de 16 Go, abaisser la demande mémoire
par sidecar via
linkerd-control-plane.proxy.resources.requests.memory.
Spark / Trino federation cassent¶
Spark Connect et la fédération Trino utilisent HTTP/2 + gRPC. Linkerd
les gère de façon transparente — mais le premier appel après
activation du sidecar peut échouer en "EOF" pendant que le proxy
négocie la handshake TLS. Ré-essayer une fois. Si ça persiste,
vérifier linkerd viz stat deploy/akko-akko-spark-master.
Désactiver mTLS (rollback)¶
helm upgrade akko helm/akko -n akko \
--set akko-mtls.enabled=false \
--set akko-mtls.injectNamespace=false
kubectl rollout restart deploy -l app.kubernetes.io/part-of=akko -n akko
Rollout service-par-service (Sprint 60.1)¶
Deux stratégies d'activation supportées. Choisir l'une ou l'autre — jamais les deux.
Stratégie A : namespace entier¶
Injection sur tous les pods du namespace akko. Plus simple mais bascule tous les services en même temps.
Stratégie B : opt-in par service (recommandée)¶
Activer un service à la fois, valider le sidecar, puis passer au
suivant. Les flags sont à false par défaut donc un helm upgrade
n'ajoute rien.
global:
serviceMesh:
linkerdInject:
aden: true # phase 1 — API interne, rollback facile
keycloak: false # phase 2
postgres: false # phase 3 (StatefulSet — drainer prudemment)
trino: false # phase 4 — blast radius le plus large
akko-mtls:
enabled: true
injectNamespace: false # PAS namespace-wide — opt-in par service
Après avoir basculé un flag :
kubectl -n akko rollout restart deploy/akko-akko-aden # ou sts/akko-akko-postgresql
kubectl -n akko get pods -l app.kubernetes.io/name=akko-aden -o jsonpath='{.items[*].spec.containers[*].name}'
# Sortie attendue : "aden linkerd-proxy" ← sidecar présent
Vérification end-to-end : lancer la marathon spec AKKO ; la marathon du founder (B1..B14) couvre chaque appel cross-service que ADEN fait (Trino, OPA, OpenMetadata, LiteLLM). Les 13 tests doivent rester verts après injection.
Cas Trino¶
Trino est un chart Helm community — ses valeurs dictent le point d'injection de l'annotation. Activer via :
trino:
coordinator:
podAnnotations:
linkerd.io/inject: enabled
worker:
podAnnotations:
linkerd.io/inject: enabled
L'umbrella global.serviceMesh.linkerdInject.trino n'est câblé que pour
la documentation et la parité avec les 3 autres services ; il ne se
propage PAS au pod template du chart community par lui-même.
Rollback¶
Repasser le flag à false et redémarrer le workload. Les certificats
d'identité Linkerd tournent toutes les 24 h ; le proxy disparaît au
prochain rollout.
Référence¶
- ADR-037 — sélection mTLS service mesh
helm/akko/charts/akko-mtls/— source du sub-chart- Documentation Linkerd : https://linkerd.io/2-edge/getting-started/