0%
المراقبة وتسجيل السجلات في Kubernetes: الأدوات والاستراتيجيات

المراقبة وتسجيل السجلات في Kubernetes: الأدوات والاستراتيجيات

اكتشف أفضل الممارسات والأدوات لمراقبة تطبيقاتك وتسجيل سجلاتها في Kubernetes، من جمع المقاييس إلى تحليل السجلات.

I

InSkillCoach

· دقيقة

مقدمة

في بيئة Kubernetes، تُعدّ الرؤية الشاملة لما يجري داخل المنظومة أمرًا حاسمًا للحفاظ على صحة تطبيقاتك وأدائها. فالمراقبة (monitoring) وتسجيل السجلات (logging) جانبان أساسيان من جوانب قابلية الملاحظة (observability)، يتيحان لك اكتشاف المشكلات وفهم أسبابها واتخاذ إجراءات وقائية.

يستعرض هذا المقال الأدوات والاستراتيجيات اللازمة لإعداد نظام متكامل للمراقبة وتسجيل السجلات في Kubernetes.

المراقبة في Kubernetes

تتمثل المراقبة في Kubernetes في جمع المقاييس المتعلقة بحالة العنقود (cluster) وتطبيقاتك وتحليلها وعرضها بصريًا. فيما يلي أبرز الأساليب والأدوات.

المقاييس الأساسية باستخدام kubectl

يوفّر Kubernetes أوامر أساسية لمراقبة حالة العنقود:

# 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

مقاييس Kubernetes باستخدام Metrics Server

Metrics Server مكوّن يجمع المقاييس الأساسية في Kubernetes (المعالج والذاكرة) ويوفّرها عبر واجهة Kubernetes البرمجية (API).

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: جمع المقاييس المتقدم

Prometheus نظام مراقبة مفتوح المصدر يجمع المقاييس ويخزّنها على شكل سلاسل زمنية. وهو مناسب بشكل خاص لبيئات cloud-native.

تثبيت Prometheus باستخدام 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

إعداد Prometheus لـ 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: عرض المقاييس بصريًا

Grafana أداة لعرض البيانات بصريًا تتيح إنشاء لوحات معلومات تفاعلية لمقاييس Prometheus الخاصة بك.

تثبيت Grafana باستخدام 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

مثال على لوحة معلومات 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: إدارة التنبيهات

يتولى Alertmanager إدارة التنبيهات التي يرسلها Prometheus ويوجّهها إلى قنوات إشعار مختلفة.

إعداد 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

تسجيل السجلات في Kubernetes

يتمثل تسجيل السجلات في Kubernetes في جمع سجلات تطبيقاتك والنظام وتخزينها وتحليلها. فيما يلي أبرز الأساليب والأدوات.

التسجيل الأساسي باستخدام kubectl

يوفّر Kubernetes أوامر أساسية للوصول إلى سجلات الـ 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

معمارية التسجيل المركزية

للحصول على حل متكامل لتسجيل السجلات، يمكنك إعداد معمارية مركزية تتألف من المكوّنات التالية:

  1. مجمّع السجلات: يجمع سجلات جميع الـ pods
  2. التخزين: يخزّن السجلات لتحليلها لاحقًا
  3. واجهة العرض: تتيح البحث في السجلات وتحليلها

ELK Stack: ‏Elasticsearch وLogstash وKibana

يُعدّ ELK Stack حلًا شائعًا لجمع السجلات وتخزينها وتحليلها.

تثبيت ELK Stack باستخدام 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

إعداد Filebeat لجمع السجلات

Filebeat وكيل (agent) خفيف يجمع السجلات ويرسلها إلى Elasticsearch أو 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

بديل ELK Stack هو EFK Stack، الذي يستخدم Fluentd بدلًا من Logstash.

تثبيت EFK Stack باستخدام 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

إعداد 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: حل خفيف لتسجيل السجلات

Loki حل خفيف لتسجيل السجلات طورته Grafana Labs، صُمّم ليكون عالي الكفاءة وسهل الاستخدام.

تثبيت Loki باستخدام 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

إعداد Promtail

Promtail هو وكيل جمع السجلات الخاص بـ 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: {}

أفضل الممارسات للمراقبة وتسجيل السجلات

1. جمع المقاييس على مستوى التطبيق

قم بتهيئة تطبيقاتك لكي تعرض المقاييس بصيغة 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. هيكلة السجلات

استخدم صيغة منظَّمة (JSON) لسجلاتك لتسهيل تحليلها:

// 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. وسم المقاييس والسجلات

أضف وسومًا (labels) مناسبة إلى مقاييسك وسجلاتك لتسهيل التصفية والتحليل:

# 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. تعريف تنبيهات مناسبة

عرّف تنبيهات تكشف المشكلات الحقيقية دون أن تولّد إنذارات كاذبة:

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. الاحتفاظ بالبيانات والأرشفة

اضبط استراتيجية للاحتفاظ بالبيانات وأرشفتها لمقاييسك وسجلاتك:

# 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: {}

مثال كامل: حزمة المراقبة وتجميع السجلات

فيما يلي مثال كامل لإعداد حزمة للمراقبة وتجميع السجلات في 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

الخاتمة

يُعدّ وجود نظام متين للمراقبة وتجميع السجلات أمرًا أساسيًا للحفاظ على سلامة تطبيقاتك وأدائها في Kubernetes. وبالجمع بين أدوات مثل Prometheus وGrafana وLoki، يمكنك الحصول على رؤية شاملة لعنقودك (cluster) ولتطبيقاتك.

وتساعدك أفضل الممارسات، مثل جمع المقاييس على مستوى التطبيق، وهيكلة السجلات، وتعريف تنبيهات مناسبة، على اكتشاف المشكلات وحلّها قبل أن تؤثر في مستخدميك.

في المقال القادم، سنستكشف الأمان في Kubernetes، وهو جانب حاسم لحماية تطبيقاتك وبياناتك.

InSkillCoach

نبذة عن InSkillCoach

خبير في التدريب والتقنيات

مدرّب متخصص في التقنيات المتقدمة والذكاء الاصطناعي، تدعمه شركة GNeurone Inc.

الشهادات:

  • AWS Certified Solutions Architect – Professional
  • شهادات Google Cloud
  • Microsoft Certified: DevOps Engineer Expert
  • Certified Kubernetes Administrator (CKA)
  • CompTIA Security+
1.4k
79

التعليقات

التعليقات مدعومة عبر GitHub Discussions

سجّل الدخول باستخدام GitHub للمشاركة في النقاش

تم نسخ الرابط!