service-mesh-observability

Par wshobson · agents

Implémentez une observabilité complète pour les service meshes, incluant le tracing distribué, les métriques et la visualisation. À utiliser lors de la mise en place du monitoring de mesh, du débogage de problèmes de latence ou de l'implémentation de SLOs pour la communication entre services.

npx skills add https://github.com/wshobson/agents --skill service-mesh-observability

Observabilité des Service Mesh

Guide complet des patterns d'observabilité pour Istio, Linkerd et déploiements de service mesh.

Quand utiliser cette compétence

  • Configurer le tracing distribué entre services
  • Implémenter les métriques et dashboards du service mesh
  • Déboguer les problèmes de latence et d'erreurs
  • Définir des SLOs pour la communication entre services
  • Visualiser les dépendances entre services
  • Dépanner les problèmes de connectivité du mesh

Concepts fondamentaux

1. Les trois piliers de l'observabilité

┌─────────────────────────────────────────────────────┐
│                 Observabilité                        │
├─────────────────┬─────────────────┬─────────────────┤
│    Métriques    │     Traces      │      Logs       │
│                 │                 │                 │
│ • Taux requête  │ • Contexte span │ • Logs accès    │
│ • Taux erreur   │ • Latence       │ • Détails erreur│
│ • Latence P50   │ • Dépendances   │ • Info debug    │
│ • Saturation    │ • Goulots       │ • Audit trail   │
└─────────────────┴─────────────────┴─────────────────┘

2. Signaux d'or pour le Mesh

Signal Description Seuil d'alerte
Latence Durée requête P50, P99 P99 > 500ms
Trafic Requêtes par seconde Détection anomalie
Erreurs Taux erreur 5xx > 1%
Saturation Utilisation ressources > 80%

Templates

Template 1 : Istio avec Prometheus & Grafana

# Installer Prometheus
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus
  namespace: istio-system
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
    scrape_configs:
      - job_name: 'istio-mesh'
        kubernetes_sd_configs:
          - role: endpoints
            namespaces:
              names:
                - istio-system
        relabel_configs:
          - source_labels: [__meta_kubernetes_service_name]
            action: keep
            regex: istio-telemetry
---
# ServiceMonitor pour Prometheus Operator
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: istio-mesh
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: istiod
  endpoints:
    - port: http-monitoring
      interval: 15s

Template 2 : Requêtes clés de métriques Istio

# Taux requête par service
sum(rate(istio_requests_total{reporter="destination"}[5m])) by (destination_service_name)

# Taux erreur (5xx)
sum(rate(istio_requests_total{reporter="destination", response_code=~"5.."}[5m]))
  / sum(rate(istio_requests_total{reporter="destination"}[5m])) * 100

# Latence P99
histogram_quantile(0.99,
  sum(rate(istio_request_duration_milliseconds_bucket{reporter="destination"}[5m]))
  by (le, destination_service_name))

# Connexions TCP
sum(istio_tcp_connections_opened_total{reporter="destination"}) by (destination_service_name)

# Taille requête
histogram_quantile(0.99,
  sum(rate(istio_request_bytes_bucket{reporter="destination"}[5m]))
  by (le, destination_service_name))

Template 3 : Jaeger Distributed Tracing

# Installation Jaeger pour Istio
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    enableTracing: true
    defaultConfig:
      tracing:
        sampling: 100.0 # 100% en dev, inférieur en prod
        zipkin:
          address: jaeger-collector.istio-system:9411
---
# Déploiement Jaeger
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jaeger
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: jaeger
  template:
    metadata:
      labels:
        app: jaeger
    spec:
      containers:
        - name: jaeger
          image: jaegertracing/all-in-one:1.50
          ports:
            - containerPort: 5775 # UDP
            - containerPort: 6831 # Thrift
            - containerPort: 6832 # Thrift
            - containerPort: 5778 # Config
            - containerPort: 16686 # UI
            - containerPort: 14268 # HTTP
            - containerPort: 14250 # gRPC
            - containerPort: 9411 # Zipkin
          env:
            - name: COLLECTOR_ZIPKIN_HOST_PORT
              value: ":9411"

Template 4 : Linkerd Viz Dashboard

# Installer l'extension Linkerd viz
linkerd viz install | kubectl apply -f -

# Accéder au dashboard
linkerd viz dashboard

# Commandes CLI pour l'observabilité
# Top requêtes
linkerd viz top deploy/my-app

# Métriques par route
linkerd viz routes deploy/my-app --to deploy/backend

# Inspection du trafic live
linkerd viz tap deploy/my-app --to deploy/backend

# Edges service (dépendances)
linkerd viz edges deployment -n my-namespace

Template 5 : Grafana Dashboard JSON

{
  "dashboard": {
    "title": "Service Mesh Overview",
    "panels": [
      {
        "title": "Request Rate",
        "type": "graph",
        "targets": [
          {
            "expr": "sum(rate(istio_requests_total{reporter=\"destination\"}[5m])) by (destination_service_name)",
            "legendFormat": "{{destination_service_name}}"
          }
        ]
      },
      {
        "title": "Error Rate",
        "type": "gauge",
        "targets": [
          {
            "expr": "sum(rate(istio_requests_total{response_code=~\"5..\"}[5m])) / sum(rate(istio_requests_total[5m])) * 100"
          }
        ],
        "fieldConfig": {
          "defaults": {
            "thresholds": {
              "steps": [
                { "value": 0, "color": "green" },
                { "value": 1, "color": "yellow" },
                { "value": 5, "color": "red" }
              ]
            }
          }
        }
      },
      {
        "title": "P99 Latency",
        "type": "graph",
        "targets": [
          {
            "expr": "histogram_quantile(0.99, sum(rate(istio_request_duration_milliseconds_bucket{reporter=\"destination\"}[5m])) by (le, destination_service_name))",
            "legendFormat": "{{destination_service_name}}"
          }
        ]
      },
      {
        "title": "Service Topology",
        "type": "nodeGraph",
        "targets": [
          {
            "expr": "sum(rate(istio_requests_total{reporter=\"destination\"}[5m])) by (source_workload, destination_service_name)"
          }
        ]
      }
    ]
  }
}

Template 6 : Kiali Service Mesh Visualization

# Installation Kiali
apiVersion: kiali.io/v1alpha1
kind: Kiali
metadata:
  name: kiali
  namespace: istio-system
spec:
  auth:
    strategy: anonymous # ou openid, token
  deployment:
    accessible_namespaces:
      - "**"
  external_services:
    prometheus:
      url: http://prometheus.istio-system:9090
    tracing:
      url: http://jaeger-query.istio-system:16686
    grafana:
      url: http://grafana.istio-system:3000

Template 7 : Intégration OpenTelemetry

# Collecteur OpenTelemetry pour mesh
apiVersion: v1
kind: ConfigMap
metadata:
  name: otel-collector-config
data:
  config.yaml: |
    receivers:
      otlp:
        protocols:
          grpc:
            endpoint: 0.0.0.0:4317
          http:
            endpoint: 0.0.0.0:4318
      zipkin:
        endpoint: 0.0.0.0:9411

    processors:
      batch:
        timeout: 10s

    exporters:
      jaeger:
        endpoint: jaeger-collector:14250
        tls:
          insecure: true
      prometheus:
        endpoint: 0.0.0.0:8889

    service:
      pipelines:
        traces:
          receivers: [otlp, zipkin]
          processors: [batch]
          exporters: [jaeger]
        metrics:
          receivers: [otlp]
          processors: [batch]
          exporters: [prometheus]
---
# Istio Telemetry v2 avec OTel
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: mesh-default
  namespace: istio-system
spec:
  tracing:
    - providers:
        - name: otel
      randomSamplingPercentage: 10

Règles d'alerte

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: mesh-alerts
  namespace: istio-system
spec:
  groups:
    - name: mesh.rules
      rules:
        - alert: HighErrorRate
          expr: |
            sum(rate(istio_requests_total{response_code=~"5.."}[5m])) by (destination_service_name)
            / sum(rate(istio_requests_total[5m])) by (destination_service_name) > 0.05
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "Taux d'erreur élevé pour {{ $labels.destination_service_name }}"

        - alert: HighLatency
          expr: |
            histogram_quantile(0.99, sum(rate(istio_request_duration_milliseconds_bucket[5m]))
            by (le, destination_service_name)) > 1000
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "Latence P99 élevée pour {{ $labels.destination_service_name }}"

        - alert: MeshCertExpiring
          expr: |
            (certmanager_certificate_expiration_timestamp_seconds - time()) / 86400 < 7
          labels:
            severity: warning
          annotations:
            summary: "Certificat mesh expirant dans moins de 7 jours"

Bonnes pratiques

À faire

  • Échantillonner de manière appropriée - 100% en dev, 1-10% en prod
  • Utiliser le contexte de trace - Propager les en-têtes de manière cohérente
  • Configurer des alertes - Pour les signaux d'or
  • Corréler métriques/traces - Utiliser les exemplaires
  • Conserver stratégiquement - Niveaux de stockage chaud/froid

À ne pas faire

  • Ne pas sur-échantillonner - Les coûts de stockage s'accumulent
  • Ne pas ignorer la cardinalité - Limiter les valeurs de labels
  • Ne pas négliger les dashboards - Visualiser les dépendances
  • Ne pas oublier les coûts - Surveiller les coûts d'observabilité

Skills similaires