Monitoring Multi-Cloud
1 - Défis du monitoring Multi-Cloud
1.1 Problématiques
| Défi | Description |
|---|---|
| Silos | Données dispersées par cloud |
| Corrélation | Difficile de lier les événements |
| Dashboards | Multiples interfaces |
| Alerting | Règles dupliquées |
| Coût | Plusieurs outils payants |
2 - Solutions de monitoring unifié
2.1 Options
| Solution | Type | Multi-Cloud |
|---|---|---|
| Datadog | SaaS | Natif |
| Grafana Cloud | SaaS | Natif |
| Prometheus + Grafana | Self-hosted | Oui |
| Elastic Stack | Self-hosted/SaaS | Oui |
| New Relic | SaaS | Natif |
2.2 Architecture recommandée
3 - Prometheus Multi-Cluster
3.1 Installation par cluster
# values-prometheus.yaml (Helm)
prometheus:
prometheusSpec:
replicas: 2
retention: 24h # Local retention court
externalLabels:
cluster: aws-production
cloud: aws
region: eu-west-1
remoteWrite:
- url: https://thanos-receive.monitoring.svc:19291/api/v1/receive
headers:
X-Scope-OrgID: tenant1
3.2 Thanos pour agrégation
# Thanos Query Frontend
apiVersion: apps/v1
kind: Deployment
metadata:
name: thanos-query
spec:
template:
spec:
containers:
- name: thanos-query
image: quay.io/thanos/thanos:v0.32.0
args:
- query
- --http-address=0.0.0.0:9090
- --store=thanos-store-aws:10901
- --store=thanos-store-azure:10901
- --store=thanos-store-gcp:10901
- --query.replica-label=replica
- --query.auto-downsampling
3.3 Labels pour Multi-Cloud
# Métriques avec labels cloud
- targets: ['app:8080']
labels:
cloud: aws
cluster: production
region: eu-west-1
environment: prod
4 - Logging centralisé
4.1 Architecture
4.2 Fluent Bit Configuration
# fluent-bit.conf
[INPUT]
Name tail
Path /var/log/containers/*.log
Parser docker
Tag kube.*
Refresh_Interval 5
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc:443
Merge_Log On
K8S-Logging.Parser On
[FILTER]
Name record_modifier
Match *
Record cloud ${CLOUD_PROVIDER}
Record cluster ${CLUSTER_NAME}
Record region ${REGION}
[OUTPUT]
Name es
Match *
Host elasticsearch.monitoring.svc
Port 9200
Index logs-multicloud
Type _doc
4.3 Loki avec Grafana
# Loki configuration
auth_enabled: false
server:
http_listen_port: 3100
distributor:
ring:
kvstore:
store: memberlist
ingester:
lifecycler:
ring:
kvstore:
store: memberlist
replication_factor: 3
schema_config:
configs:
- from: 2024-01-01
store: boltdb-shipper
object_store: s3
schema: v11
index:
prefix: loki_index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/cache
shared_store: s3
aws:
s3: s3://eu-west-1/loki-logs
5 - Tracing distribué
5.1 OpenTelemetry
# otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 10s
resource:
attributes:
- key: cloud.provider
value: ${CLOUD_PROVIDER}
action: upsert
- key: cloud.region
value: ${REGION}
action: upsert
exporters:
jaeger:
endpoint: jaeger-collector:14250
tls:
insecure: true
otlp:
endpoint: tempo.monitoring.svc:4317
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, resource]
exporters: [jaeger, otlp]
5.2 Instrumentation application
# Python avec OpenTelemetry
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
resource = Resource.create({
"service.name": "my-service",
"cloud.provider": os.getenv("CLOUD_PROVIDER", "unknown"),
"cloud.region": os.getenv("REGION", "unknown"),
"deployment.environment": os.getenv("ENVIRONMENT", "unknown")
})
provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint="otel-collector:4317"))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
6 - Alerting unifié
6.1 Alertmanager
# alertmanager.yml
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'cloud', 'cluster']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'default'
routes:
- match:
severity: critical
receiver: 'pagerduty'
- match:
severity: warning
receiver: 'slack'
receivers:
- name: 'default'
webhook_configs:
- url: 'http://webhook.example.com/alert'
- name: 'pagerduty'
pagerduty_configs:
- service_key: '<pagerduty-key>'
severity: critical
- name: 'slack'
slack_configs:
- api_url: '<slack-webhook>'
channel: '#alerts'
title: '[{{ .Status | toUpper }}] {{ .GroupLabels.alertname }}'
text: 'Cloud: {{ .GroupLabels.cloud }} | Cluster: {{ .GroupLabels.cluster }}'
6.2 Règles d'alerte communes
# prometheus-rules.yaml
groups:
- name: multicloud-alerts
rules:
- alert: HighErrorRate
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m])) by (cloud, cluster, service)
/
sum(rate(http_requests_total[5m])) by (cloud, cluster, service)
> 0.01
for: 5m
labels:
severity: warning
annotations:
summary: "High error rate on {{ $labels.service }}"
description: "Error rate is {{ $value | humanizePercentage }} on {{ $labels.cloud }}/{{ $labels.cluster }}"
- alert: ClusterDown
expr: up{job="kubernetes-nodes"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: "Cluster {{ $labels.cluster }} on {{ $labels.cloud }} is down"
7 - Dashboards Multi-Cloud
7.1 Dashboard Grafana
{
"title": "Multi-Cloud Overview",
"panels": [
{
"title": "Requests by Cloud",
"type": "stat",
"targets": [
{
"expr": "sum(rate(http_requests_total[5m])) by (cloud)",
"legendFormat": "{{cloud}}"
}
]
},
{
"title": "Error Rate by Region",
"type": "timeseries",
"targets": [
{
"expr": "sum(rate(http_requests_total{status=~\"5..\"}[5m])) by (cloud, region) / sum(rate(http_requests_total[5m])) by (cloud, region)",
"legendFormat": "{{cloud}}-{{region}}"
}
]
},
{
"title": "Cluster Health",
"type": "table",
"targets": [
{
"expr": "count(up{job=\"kubernetes-nodes\"} == 1) by (cloud, cluster)",
"format": "table"
}
]
}
]
}
Résumé
Dans ce chapitre, nous avons appris :
- Les défis du monitoring Multi-Cloud
- Les solutions de monitoring unifié
- Prometheus et Thanos multi-cluster
- Le logging centralisé avec Loki/ELK
- Le tracing distribué avec OpenTelemetry
- L'alerting unifié
Prochaine étape
Dans le prochain chapitre, nous verrons les Bonnes pratiques.
→ Chapitre suivant : Bonnes pratiques