Monitoring et Logging dans Kubernetes : Outils et Stratégies
Découvrez les meilleures pratiques et outils pour surveiller et logger vos applications dans Kubernetes, de la collecte de métriques à l'analyse des logs.
InSkillCoach
Introduction
Dans un environnement Kubernetes, la visibilité est cruciale pour maintenir la santé et la performance de vos applications. Le monitoring et le logging sont deux aspects fondamentaux de l’observabilité qui vous permettent de détecter les problèmes, comprendre leur cause et prendre des mesures préventives.
Cet article explore les outils et stratégies pour mettre en place un système complet de monitoring et de logging dans Kubernetes.
Monitoring dans Kubernetes
Le monitoring dans Kubernetes consiste à collecter, analyser et visualiser des métriques sur l’état de votre cluster et de vos applications. Voici les principales approches et outils.
Métriques de Base avec kubectl
Kubernetes fournit des commandes de base pour surveiller l’état de votre cluster :
# Vérifier l'état des nœuds
kubectl get nodes
# Vérifier l'état des pods
kubectl get pods
# Vérifier l'état des services
kubectl get services
# Vérifier les événements du cluster
kubectl get events
# Vérifier l'utilisation des ressources des nœuds
kubectl top nodes
# Vérifier l'utilisation des ressources des pods
kubectl top pods
Métriques de Kubernetes avec Metrics Server
Metrics Server est un composant qui collecte les métriques de base de Kubernetes (CPU, mémoire) et les expose via l’API Kubernetes.
apiVersion: v1
kind: ServiceAccount
metadata:
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: system:aggregated-metrics-reader
labels:
rbac.authorization.k8s.io/aggregate-to-view: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rules:
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: system:metrics-server
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
- apiGroups:
- ""
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: metrics-server-auth-delegator
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: metrics-server:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:metrics-server
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:metrics-server
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
name: metrics-server
namespace: kube-system
labels:
kubernetes.io/name: Metrics-server
kubernetes.io/cluster-service: "true"
spec:
selector:
k8s-app: metrics-server
ports:
- name: https
port: 443
protocol: TCP
targetPort: https
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: metrics-server
namespace: kube-system
labels:
k8s-app: metrics-server
spec:
selector:
matchLabels:
k8s-app: metrics-server
strategy:
rollingUpdate:
maxUnavailable: 0
template:
metadata:
name: metrics-server
labels:
k8s-app: metrics-server
spec:
serviceAccountName: metrics-server
containers:
- name: metrics-server
image: k8s.gcr.io/metrics-server/metrics-server:v0.5.0
args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls
ports:
- name: https
containerPort: 4443
protocol: TCP
livenessProbe:
httpGet:
path: /livez
port: https
scheme: HTTPS
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe:
httpGet:
path: /readyz
port: https
scheme: HTTPS
initialDelaySeconds: 20
periodSeconds: 10
resources:
requests:
cpu: 100m
memory: 200Mi
limits:
cpu: 200m
memory: 400Mi
volumeMounts:
- name: tmp-dir
mountPath: /tmp
volumes:
- name: tmp-dir
emptyDir: {}
Prometheus : Collecte de Métriques Avancée
Prometheus est un système de monitoring open-source qui collecte et stocke des métriques sous forme de séries temporelles. Il est particulièrement adapté aux environnements cloud-native.
Installation de Prometheus avec Helm
# Ajouter le repo Helm de Prometheus
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# Installer Prometheus
helm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace
Configuration de Prometheus pour Kubernetes
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: app-monitor
labels:
release: prometheus
spec:
selector:
matchLabels:
app: myapp
endpoints:
- port: http
interval: 15s
path: /metrics
Grafana : Visualisation des Métriques
Grafana est un outil de visualisation qui permet de créer des tableaux de bord interactifs pour vos métriques Prometheus.
Installation de Grafana avec Helm
# Ajouter le repo Helm de Grafana
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
# Installer Grafana
helm install grafana grafana/grafana \
--namespace monitoring \
--create-namespace
Exemple de Dashboard Grafana
{
"annotations": {
"list": []
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "sum(rate(container_cpu_usage_seconds_total{namespace=\"default\"}[5m])) by (pod) * 100",
"refId": "A"
}
],
"title": "CPU Usage by Pod",
"type": "timeseries"
}
],
"refresh": "5s",
"schemaVersion": 38,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Kubernetes Monitoring",
"uid": "kubernetes",
"version": 1,
"weekStart": ""
}
Alertmanager : Gestion des Alertes
Alertmanager gère les alertes envoyées par Prometheus et les route vers différents canaux de notification.
Configuration d’Alertmanager
apiVersion: monitoring.coreos.com/v1
kind: AlertmanagerConfig
metadata:
name: app-alerts
namespace: default
spec:
route:
receiver: 'slack'
groupBy: ['alertname', 'namespace']
groupWait: 30s
groupInterval: 5m
repeatInterval: 4h
receivers:
- name: 'slack'
slackConfigs:
- apiURL: 'https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK'
channel: '#alerts'
sendResolved: true
Logging dans Kubernetes
Le logging dans Kubernetes consiste à collecter, stocker et analyser les logs de vos applications et du système. Voici les principales approches et outils.
Logging de Base avec kubectl
Kubernetes fournit des commandes de base pour accéder aux logs de vos pods :
# Voir les logs d'un pod
kubectl logs <pod-name>
# Voir les logs d'un conteneur spécifique dans un pod
kubectl logs <pod-name> -c <container-name>
# Voir les logs en temps réel
kubectl logs -f <pod-name>
# Voir les logs d'un pod précédent (en cas de redémarrage)
kubectl logs <pod-name> --previous
Architecture de Logging Centralisée
Pour une solution de logging complète, vous pouvez mettre en place une architecture centralisée avec les composants suivants :
- Collecteur de logs : Collecte les logs de tous les pods
- Stockage : Stocke les logs pour une analyse ultérieure
- Interface de visualisation : Permet de rechercher et d’analyser les logs
ELK Stack : Elasticsearch, Logstash, Kibana
L’ELK Stack est une solution populaire pour la collecte, le stockage et l’analyse des logs.
Installation de l’ELK Stack avec Helm
# Ajouter le repo Helm d'Elastic
helm repo add elastic https://helm.elastic.co
helm repo update
# Installer Elasticsearch
helm install elasticsearch elastic/elasticsearch \
--namespace logging \
--create-namespace
# Installer Kibana
helm install kibana elastic/kibana \
--namespace logging \
--create-namespace
# Installer Logstash
helm install logstash elastic/logstash \
--namespace logging \
--create-namespace
Configuration de Filebeat pour la Collecte de Logs
Filebeat est un agent léger qui collecte les logs et les envoie à Elasticsearch ou Logstash.
apiVersion: beat.k8s.elastic.co/v1beta1
kind: Filebeat
metadata:
name: filebeat
namespace: logging
spec:
version: 7.14.0
elasticsearchRef:
name: elasticsearch
config:
filebeat.inputs:
- type: container
paths:
- /var/log/containers/*.log
processors:
- add_kubernetes_metadata:
host: ${NODE_NAME}
matchers:
- logs_path:
logs_path: "/var/log/containers/"
daemonSet:
podTemplate:
spec:
containers:
- name: filebeat
volumeMounts:
- name: varlogcontainers
mountPath: /var/log/containers
- name: varlogpods
mountPath: /var/log/pods
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
volumes:
- name: varlogcontainers
hostPath:
path: /var/log/containers
- name: varlogpods
hostPath:
path: /var/log/pods
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
EFK Stack : Elasticsearch, Fluentd, Kibana
Une alternative à l’ELK Stack est l’EFK Stack, qui utilise Fluentd au lieu de Logstash.
Installation de l’EFK Stack avec Helm
# Ajouter le repo Helm de Fluentd
helm repo add fluent https://fluent.github.io/helm-charts
helm repo update
# Installer Fluentd
helm install fluentd fluent/fluentd \
--namespace logging \
--create-namespace
Configuration de Fluentd
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
namespace: logging
data:
fluent.conf: |
<source>
@type tail
path /var/log/containers/*.log
pos_file /var/log/fluentd-containers.log.pos
tag kubernetes.*
read_from_head true
<parse>
@type json
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
</source>
<filter kubernetes.**>
@type kubernetes_metadata
</filter>
<match kubernetes.**>
@type elasticsearch
host elasticsearch
port 9200
logstash_format true
logstash_prefix k8s
<buffer>
@type memory
flush_interval 5s
retry_max_times 5
</buffer>
</match>
Loki : Solution de Logging Légère
Loki est une solution de logging légère développée par Grafana Labs, conçue pour être très efficace et facile à utiliser.
Installation de Loki avec Helm
# Ajouter le repo Helm de Grafana
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
# Installer Loki
helm install loki grafana/loki-stack \
--namespace logging \
--create-namespace
Configuration de Promtail
Promtail est l’agent de collecte de logs pour Loki.
apiVersion: v1
kind: ConfigMap
metadata:
name: promtail-config
namespace: logging
data:
promtail.yaml: |
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_name]
regex: (.+)
target_label: pod
- source_labels: [__meta_kubernetes_namespace_name]
regex: (.+)
target_label: namespace
pipeline_stages:
- docker: {}
- cri: {}
Bonnes Pratiques pour le Monitoring et le Logging
1. Collecte de Métriques au Niveau de l’Application
Instrumentez vos applications pour exposer des métriques au format Prometheus :
// Exemple avec Micrometer pour Java
@RestController
public class MetricsController {
private final Counter requestCounter;
public MetricsController(MeterRegistry registry) {
this.requestCounter = Counter.builder("app_requests_total")
.description("Total number of requests")
.register(registry);
}
@GetMapping("/api/resource")
public String handleRequest() {
requestCounter.increment();
return "Response";
}
}
2. Structuration des Logs
Utilisez un format structuré pour vos logs (JSON) pour faciliter l’analyse :
// Exemple avec SLF4J et Logback
<configuration>
<appender name="JSON" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeMDC>true</includeMDC>
<customFields>{"app_name":"myapp"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="JSON" />
</root>
</configuration>
3. Étiquetage des Métriques et des Logs
Ajoutez des étiquettes pertinentes à vos métriques et logs pour faciliter le filtrage et l’analyse :
# Exemple de configuration Prometheus
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_name]
regex: (.+)
target_label: pod
- source_labels: [__meta_kubernetes_namespace_name]
regex: (.+)
target_label: namespace
- source_labels: [__meta_kubernetes_pod_label_app]
regex: (.+)
target_label: app
4. Définition d’Alertes Pertinentes
Définissez des alertes qui détectent les problèmes réels sans générer de faux positifs :
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: app-alerts
namespace: monitoring
spec:
groups:
- name: app
rules:
- alert: HighErrorRate
expr: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.05
for: 5m
labels:
severity: critical
annotations:
summary: High error rate detected
description: Error rate is above 5% for the last 5 minutes
5. Rétention et Archivage
Configurez une stratégie de rétention et d’archivage pour vos métriques et logs :
# Exemple de configuration Elasticsearch pour la rétention
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: elasticsearch
spec:
version: 7.14.0
nodeSets:
- name: default
count: 3
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
indices:
lifecycle:
policies:
- name: logs-policy
phases:
hot:
min_age: 0s
actions:
rollover:
max_age: 1d
max_size: 50gb
warm:
min_age: 7d
actions:
forcemerge:
max_num_segments: 1
cold:
min_age: 30d
actions:
freeze: {}
delete:
min_age: 90d
actions:
delete: {}
Exemple Complet : Stack de Monitoring et Logging
Voici un exemple complet d’une configuration pour un stack de monitoring et logging dans Kubernetes :
# Prometheus Operator
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: prometheus
namespace: monitoring
spec:
serviceAccountName: prometheus
serviceMonitorSelector:
matchLabels:
release: prometheus
resources:
requests:
memory: 2Gi
cpu: 1
limits:
memory: 4Gi
cpu: 2
storage:
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 50Gi
---
# Grafana
apiVersion: integreatly.org/v1alpha1
kind: Grafana
metadata:
name: grafana
namespace: monitoring
spec:
config:
auth:
adminUser: admin
adminPassword: admin
dashboard:
defaultDashboard: kubernetes
dashboardLabelSelector:
- matchLabels:
grafana_dashboard: "1"
resources:
requests:
memory: 1Gi
cpu: 500m
limits:
memory: 2Gi
cpu: 1
---
# Loki
apiVersion: loki.grafana.com/v1
kind: Loki
metadata:
name: loki
namespace: logging
spec:
size: 1x.small
storage:
type: filesystem
size: 10Gi
resources:
requests:
memory: 512Mi
cpu: 250m
limits:
memory: 1Gi
cpu: 500m
---
# Promtail
apiVersion: v1
kind: ConfigMap
metadata:
name: promtail-config
namespace: logging
data:
promtail.yaml: |
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_name]
regex: (.+)
target_label: pod
- source_labels: [__meta_kubernetes_namespace_name]
regex: (.+)
target_label: namespace
pipeline_stages:
- docker: {}
- cri: {}
---
# ServiceMonitor pour l'application
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: app-monitor
namespace: monitoring
labels:
release: prometheus
spec:
selector:
matchLabels:
app: myapp
endpoints:
- port: http
interval: 15s
path: /metrics
---
# Service pour l'application avec métriques
apiVersion: v1
kind: Service
metadata:
name: app-service
labels:
app: myapp
spec:
selector:
app: myapp
ports:
- name: http
port: 80
targetPort: 8080
- name: metrics
port: 8080
targetPort: 8080
Conclusion
Un système robuste de monitoring et de logging est essentiel pour maintenir la santé et la performance de vos applications dans Kubernetes. En combinant des outils comme Prometheus, Grafana, et Loki, vous pouvez obtenir une visibilité complète sur votre cluster et vos applications.
Les bonnes pratiques comme la collecte de métriques au niveau de l’application, la structuration des logs, et la définition d’alertes pertinentes vous aideront à détecter et résoudre les problèmes avant qu’ils n’affectent vos utilisateurs.
Dans le prochain article, nous explorerons la sécurité dans Kubernetes, un aspect crucial pour protéger vos applications et vos données.
À propos de InSkillCoach
Expert en formation et technologies
Coach spécialisé dans les technologies avancées et l'IA, porté par GNeurone Inc.
Certifications:
- AWS Certified Solutions Architect – Professional
- Certifications Google Cloud
- Microsoft Certified: DevOps Engineer Expert
- Certified Kubernetes Administrator (CKA)
- CompTIA Security+
Commentaires
Les commentaires sont alimentés par GitHub Discussions
Connectez-vous avec GitHub pour participer à la discussion