0%
Monitoring et Logging dans Kubernetes : Outils et Stratégies

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.

I

InSkillCoach

· min

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 :

  1. Collecteur de logs : Collecte les logs de tous les pods
  2. Stockage : Stocke les logs pour une analyse ultérieure
  3. 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.

InSkillCoach

À 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+
802
324

Commentaires

Les commentaires sont alimentés par GitHub Discussions

Connectez-vous avec GitHub pour participer à la discussion

Lien copié !