microservices

Service Mesh для микросервисов

Управление взаимодействием микросервисов с помощью Service Mesh (Istio, Linkerd)

#microservices #service-mesh #istio #kubernetes #infrastructure

Service Mesh для микросервисов

Service Mesh — это выделенный инфраструктурный слой для управления взаимодействием между микросервисами, обеспечивающий наблюдаемость, безопасность и надежность.

Что такое Service Mesh?

Service Mesh добавляет прокси-сервер (sidecar) к каждому микросервису, который перехватывает весь сетевой трафик и предоставляет дополнительные возможности без изменения кода приложения.

┌─────────────┐     ┌─────────────┐
│  Service A  │     │  Service B  │
│  ┌───────┐  │     │  ┌───────┐  │
│  │  App  │  │     │  │  App  │  │
│  └───┬───┘  │     │  └───┬───┘  │
│      │      │     │      │      │
│  ┌───▼───┐  │     │  ┌───▼───┐  │
│  │ Proxy │◄─┼─────┼─►│ Proxy │  │
│  └───────┘  │     │  └───────┘  │
└─────────────┘     └─────────────┘
       │                   │
       └───────┬───────────┘

        ┌──────▼──────┐
        │ Control     │
        │ Plane       │
        └─────────────┘

Istio - популярная реализация

Установка Istio

# Скачивание Istio
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.20.0
export PATH=$PWD/bin:$PATH

# Установка с профилем по умолчанию
istioctl install --set profile=default -y

# Включение автоматической инъекции sidecar
kubectl label namespace default istio-injection=enabled

Конфигурация сервиса

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: order-service
  labels:
    app: order-service
spec:
  ports:
  - port: 80
    name: http
    targetPort: 3000
  selector:
    app: order-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
      version: v1
  template:
    metadata:
      labels:
        app: order-service
        version: v1
    spec:
      containers:
      - name: order-service
        image: myregistry/order-service:1.0.0
        ports:
        - containerPort: 3000

Traffic Management

Virtual Service - маршрутизация трафика

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: order-service
spec:
  hosts:
  - order-service
  http:
  - match:
    - headers:
        user-type:
          exact: premium
    route:
    - destination:
        host: order-service
        subset: v2
      weight: 100
  - route:
    - destination:
        host: order-service
        subset: v1
      weight: 90
    - destination:
        host: order-service
        subset: v2
      weight: 10

Destination Rule - политики трафика

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: order-service
spec:
  host: order-service
  trafficPolicy:
    loadBalancer:
      simple: LEAST_REQUEST
    connectionPool:
      tcp:
        maxConnections: 100
      http:
        http1MaxPendingRequests: 50
        http2MaxRequests: 100
    outlierDetection:
      consecutiveErrors: 5
      interval: 30s
      baseEjectionTime: 30s
      maxEjectionPercent: 50
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
    trafficPolicy:
      loadBalancer:
        simple: ROUND_ROBIN

Canary Deployment

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: order-service-canary
spec:
  hosts:
  - order-service
  http:
  - match:
    - headers:
        canary:
          exact: "true"
    route:
    - destination:
        host: order-service
        subset: v2
  - route:
    - destination:
        host: order-service
        subset: v1
      weight: 95
    - destination:
        host: order-service
        subset: v2
      weight: 5

Circuit Breaking

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: payment-service-circuit-breaker
spec:
  host: payment-service
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 10
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 2
    outlierDetection:
      consecutiveErrors: 3
      interval: 10s
      baseEjectionTime: 30s
      maxEjectionPercent: 100

Retry и Timeout

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: inventory-service
spec:
  hosts:
  - inventory-service
  http:
  - route:
    - destination:
        host: inventory-service
    timeout: 3s
    retries:
      attempts: 3
      perTryTimeout: 1s
      retryOn: 5xx,reset,connect-failure,refused-stream

Fault Injection - тестирование отказоустойчивости

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: payment-service-fault
spec:
  hosts:
  - payment-service
  http:
  - fault:
      delay:
        percentage:
          value: 10
        fixedDelay: 5s
      abort:
        percentage:
          value: 5
        httpStatus: 503
    route:
    - destination:
        host: payment-service

Security - mTLS

Включение mTLS для namespace

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT

Authorization Policy

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: order-service-authz
  namespace: production
spec:
  selector:
    matchLabels:
      app: order-service
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/production/sa/api-gateway"]
    to:
    - operation:
        methods: ["GET", "POST"]
        paths: ["/api/orders/*"]

Observability

Distributed Tracing с Jaeger

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: tracing-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http-tracing
      protocol: HTTP
    hosts:
    - "tracing.example.com"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: tracing-vs
spec:
  hosts:
  - "tracing.example.com"
  gateways:
  - tracing-gateway
  http:
  - route:
    - destination:
        host: tracing
        port:
          number: 80

Метрики Prometheus

# Получение метрик сервиса
kubectl -n istio-system port-forward svc/prometheus 9090:9090

# Примеры запросов
# Latency P99
histogram_quantile(0.99, 
  sum(rate(istio_request_duration_milliseconds_bucket[1m])) by (le, destination_service)
)

# Error rate
sum(rate(istio_requests_total{response_code=~"5.*"}[1m])) by (destination_service) /
sum(rate(istio_requests_total[1m])) by (destination_service)

Linkerd - альтернатива Istio

Установка Linkerd

# Установка CLI
curl -sL https://run.linkerd.io/install | sh

# Проверка кластера
linkerd check --pre

# Установка control plane
linkerd install | kubectl apply -f -

# Проверка установки
linkerd check

Добавление сервиса в mesh

# Инъекция proxy в deployment
kubectl get deploy order-service -o yaml | \
  linkerd inject - | \
  kubectl apply -f -

# Или через аннотацию
kubectl annotate namespace production linkerd.io/inject=enabled

Service Profile для retry

apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
  name: payment-service.production.svc.cluster.local
  namespace: production
spec:
  routes:
  - name: POST /api/payments
    condition:
      method: POST
      pathRegex: /api/payments
    isRetryable: true
    timeout: 3s

Сравнение Istio и Linkerd

ХарактеристикаIstioLinkerd
СложностьВысокаяНизкая
ПроизводительностьСредняяВысокая
ФункциональностьОчень богатаяБазовая
Потребление ресурсовВысокоеНизкое
Кривая обученияКрутаяПологая

Best Practices

  1. Начните с простого — не включайте все фичи сразу
  2. Мониторьте overhead — service mesh добавляет латентность
  3. Используйте mTLS — для безопасности между сервисами
  4. Настройте observability — трейсинг и метрики критичны
  5. Тестируйте отказоустойчивость — используйте fault injection
  6. Версионируйте конфигурацию — храните манифесты в Git
  7. Постепенная миграция — не переводите все сервисы сразу

Заключение

Service Mesh предоставляет мощные инструменты для управления микросервисами, но требует тщательного планирования и понимания trade-offs между функциональностью и сложностью.