Blog

Service Mesh sur OpenShift avec OpenShift Service Mesh (Istio)

OpenShift
Service Mesh
Istio
mTLS
Observabilité

Déploiement et configuration d'OpenShift Service Mesh (basé sur Istio) pour sécuriser les communications inter-services avec mTLS, gérer le trafic, observer les métriques et implémenter des politiques de réseau avancées.

20 janvier 2025

Qu’est-ce qu’un Service Mesh ?

Un Service Mesh est une couche d’infrastructure dédiée à la gestion des communications entre microservices. Il opère au niveau du réseau, de façon transparente pour les applications, en injectant des proxies sidecar (Envoy) dans chaque pod.

OpenShift Service Mesh est la distribution Red Hat certifiée d’Istio, enrichie de Kiali (observabilité), Jaeger (tracing distribué) et Prometheus/Grafana (métriques).

Les fonctionnalités clés :

  • mTLS automatique — chiffrement et authentification mutuelle entre services
  • Gestion du trafic — canary deployments, circuit breakers, retry, timeout
  • Observabilité — traces distribuées, métriques RED (Rate, Error, Duration)
  • Politiques d’accès — AuthorizationPolicies fine-grained

Installation des Operators

OpenShift Service Mesh requiert plusieurs Operators : Elasticsearch, Jaeger, Kiali, et OpenShift Service Mesh lui-même.

# 1. Elasticsearch Operator (pour Jaeger)
cat <<EOF | oc apply -f -
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: elasticsearch-operator
  namespace: openshift-operators-redhat
spec:
  channel: stable
  name: elasticsearch-operator
  source: redhat-operators
  sourceNamespace: openshift-marketplace
EOF

# 2. Jaeger Operator
cat <<EOF | oc apply -f -
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: jaeger-product
  namespace: openshift-distributed-tracing
spec:
  channel: stable
  name: jaeger-product
  source: redhat-operators
  sourceNamespace: openshift-marketplace
EOF

# 3. Kiali Operator
cat <<EOF | oc apply -f -
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: kiali-ossm
  namespace: openshift-operators
spec:
  channel: stable
  name: kiali-ossm
  source: redhat-operators
  sourceNamespace: openshift-marketplace
EOF

# 4. OpenShift Service Mesh Operator
cat <<EOF | oc apply -f -
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: servicemeshoperator
  namespace: openshift-operators
spec:
  channel: stable
  name: servicemeshoperator
  source: redhat-operators
  sourceNamespace: openshift-marketplace
EOF

Créer le Control Plane (ServiceMeshControlPlane)

Le Control Plane Istio est instancié via la CR ServiceMeshControlPlane dans un namespace dédié.

oc new-project istio-system
apiVersion: maistra.io/v2
kind: ServiceMeshControlPlane
metadata:
  name: basic
  namespace: istio-system
spec:
  version: v2.6
  tracing:
    type: Jaeger
    sampling: 1000    # 100% en dev, réduire en prod
  addons:
    jaeger:
      install:
        storage:
          type: Memory    # Elasticsearch en production
    kiali:
      enabled: true
    grafana:
      enabled: true
    prometheus:
      enabled: true
  security:
    dataPlane:
      mtls: true          # mTLS automatique entre tous les services
      automtls: true
  proxy:
    runtime:
      container:
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 256Mi

Inscrire des namespaces dans le Mesh (ServiceMeshMemberRoll)

Contrairement à Istio upstream, OpenShift Service Mesh utilise un ServiceMeshMemberRoll pour déclarer les namespaces participants — une approche opt-in plus sécurisée.

apiVersion: maistra.io/v1
kind: ServiceMeshMemberRoll
metadata:
  name: default
  namespace: istio-system
spec:
  members:
    - production
    - staging
    - mon-app

L’injection du sidecar Envoy est activée par annotation sur le namespace :

oc annotate namespace mon-app \
  maistra.io/memberOf=istio-system

Ou directement sur un déploiement :

spec:
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "true"

mTLS : chiffrement automatique inter-services

Avec automtls: true, Istio gère automatiquement les certificats et le chiffrement. Vérifier l’état mTLS :

# Vérifier que le trafic est chiffré
istioctl x describe pod mon-pod-xyz -n mon-app

Pour enforcer mTLS strict (rejeter les connexions non chiffrées) :

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: mtls-strict
  namespace: mon-app
spec:
  mtls:
    mode: STRICT

Gestion du trafic

VirtualService et DestinationRule

# Répartition du trafic : 90% v1, 10% v2 (canary)
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: mon-service
  namespace: mon-app
spec:
  hosts:
    - mon-service
  http:
    - match:
        - headers:
            x-canary:
              exact: "true"
      route:
        - destination:
            host: mon-service
            subset: v2
    - route:
        - destination:
            host: mon-service
            subset: v1
          weight: 90
        - destination:
            host: mon-service
            subset: v2
          weight: 10
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: mon-service
  namespace: mon-app
spec:
  host: mon-service
  trafficPolicy:
    connectionPool:
      http:
        h2UpgradePolicy: UPGRADE
    outlierDetection:
      consecutive5xxErrors: 3
      interval: 10s
      baseEjectionTime: 30s    # Circuit breaker
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2

Retry et Timeout

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: service-resilient
spec:
  hosts:
    - service-resilient
  http:
    - timeout: 5s
      retries:
        attempts: 3
        perTryTimeout: 2s
        retryOn: 5xx,gateway-error,connect-failure
      route:
        - destination:
            host: service-resilient

AuthorizationPolicies : contrôle d’accès fin

# Autoriser seulement le service A à appeler le service B en GET
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-service-a
  namespace: mon-app
spec:
  selector:
    matchLabels:
      app: service-b
  action: ALLOW
  rules:
    - from:
        - source:
            principals:
              - "cluster.local/ns/mon-app/sa/service-a"
      to:
        - operation:
            methods: ["GET"]
            paths: ["/api/*"]

Observabilité avec Kiali

Kiali fournit une topologie visuelle du mesh en temps réel, indiquant les taux d’erreur, les latences et l’état mTLS de chaque service.

# Accéder à Kiali
oc get route kiali -n istio-system

Kiali permet également de valider la configuration Istio et de détecter les mauvaises configurations (VirtualService orphelins, conflits de DestinationRule, etc.).


Performances et dimensionnement

Le sidecar Envoy ajoute une latence typique de 1-5ms par hop. Pour les applications latency-sensitive :

# Optimiser le sidecar pour la production
spec:
  proxy:
    runtime:
      container:
        resources:
          requests:
            cpu: 200m
            memory: 256Mi
    concurrency: 2    # Threads Envoy worker

Désactiver le sidecar pour les workloads qui n’en ont pas besoin (jobs batch, etc.) :

metadata:
  annotations:
    sidecar.istio.io/inject: "false"

Conclusion

OpenShift Service Mesh transforme une architecture microservices en une plateforme sécurisée, observable et résiliente, sans modifier une ligne de code applicatif. Le mTLS automatique élimine les certificats manuels, les VirtualServices permettent des déploiements progressifs sûrs, et Kiali offre une visibilité sans précédent sur les flux entre services. La version 2.x d’OpenShift Service Mesh apporte des améliorations majeures de performance et une meilleure intégration avec les SCC OpenShift.