Ich versuche .NET Core + Kubernetes + Appmetrics + Prometheus + Grafana + Jobs + Gesundheitschecks

Kurze Bekanntschaft mit Kubernetes für Entwickler am Beispiel der Bereitstellung einer einfachen Vorlagenwebsite, deren Einrichtung für die Überwachung, Durchführung geplanter Jobs und Integritätsprüfungen (alle Quellcodes sind beigefügt)

- Installieren Sie Kubernetes
- Installieren Sie die Benutzeroberfläche
- Starten Sie Ihre Anwendung im Cluster
- Hinzufügen benutzerdefinierter Metriken zur Anwendung
- Erfassung von Metriken durch Prometheus
- Metriken in Grafana anzeigen
- Geplante Aufgaben
- Fehlertoleranz
- Schlussfolgerungen
- Notizen
- Referenzen

Installieren Sie Kubernetes


Nicht für Linux-Benutzer geeignet, müssen Sie Minikube verwenden
  1. Haben Sie einen Docker-Desktop?
  2. Darin müssen Sie Kubernetes Single-Node-Cluster finden und aktivieren
  3. Jetzt haben Sie api http: // localhost: 8001 / für die Arbeit mit kubernetis
  4. Die Kommunikation mit ihm erfolgt über ein praktisches Dienstprogramm kubectl
    Überprüfen Sie die Version mit dem Befehl> kubectl version
    Die neuesten relevanten Informationen finden Sie hier https://storage.googleapis.com/kubernetes-release/release/stable.txt
    Sie können es unter dem entsprechenden Link https://storage.googleapis.com/kubernetes-release/release/v1.13.2/bin/windows/amd64/kubectl.exe herunterladen
  5. kubectl cluster-info dass der Cluster funktioniert> kubectl cluster-info

UI-Installation


  1. Die Schnittstelle wird im selben Cluster bereitgestellt
     kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml 
  2. Holen Sie sich ein Token, um auf die Schnittstelle zuzugreifen
     kubectl describe secret 

    Und kopieren
  3. Starten Sie nun den Proxy
     kubectl proxy 
  4. Und Sie können http: // localhost: 8001 / api / v1 / namespaces / kube-system / services / https: kubernetes-dashboard: / proxy / verwenden


Ausführen Ihrer Anwendung in einem Cluster


  1. Ich habe über das Studio https://github.com/SanSYS/kuberfirst eine Standardanwendung für mvc netcoreapp2.1 erstellt
  2. Dockerfile:
     FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base WORKDIR /app EXPOSE 80 FROM microsoft/dotnet:2.1-sdk AS build WORKDIR /src COPY ./MetricsDemo.csproj . RUN ls RUN dotnet restore "MetricsDemo.csproj" COPY . . RUN dotnet build "MetricsDemo.csproj" -c Release -o /app FROM build AS publish RUN dotnet publish "MetricsDemo.csproj" -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "MetricsDemo.dll"] 
  3. Sammelte dieses Ding mit dem Metricsdemo3-Tag
     docker build -t metricsdemo3 . 
  4. Aber! Coober zieht standardmäßig Bilder vom Hub, daher erhöhe ich das lokale Register
  5. Hinweis - Ich habe nicht versucht, in Kubernetis zu laufen
     docker create -p 5000:5000 --restart always --name registry registry:2 
  6. Und ich verschreibe es als autorisiert unsicher:
     { "registry-mirrors": [], "insecure-registries": [ "localhost:5000" ], "debug": true, "experimental": false } 
  7. Bevor Sie in das Register drücken, noch ein paar Gesten
     docker start registry docker tag metricsdemo3 localhost:5000/sansys/metricsdemo3 docker push localhost:5000/sansys/metricsdemo3 
  8. Es wird ungefähr so ​​aussehen:
  9. Starten Sie über die Benutzeroberfläche



Wenn es startet, ist alles in Ordnung und Sie können den Betrieb aufnehmen


Erstellen Sie eine Bereitstellungsdatei
1-deploy-app.yaml
 kind: Deployment apiVersion: apps/v1 metadata: name: metricsdemo labels: app: web spec: replicas: 2 #    (  ) #  ,      selector: matchLabels: app: metricsdemo template: metadata: labels: app: metricsdemo #     selector  kind: Service spec: containers: - name: metricsdemo #   image: localhost:5000/sansys/metricsdemo3 #    ports: - containerPort: 80 #       # :    ,       --- kind: Service apiVersion: v1 metadata: name: metricsdemo #    __meta_kubernetes_service_name="metricsdemo",  https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config labels: apptype: business #    __meta_kubernetes_service_label_apptype="business" -  instancetype: web #    __meta_kubernetes_service_label_instancetype="web" spec: selector: app: metricsdemo #    labels:app type: LoadBalancer #      ports: - protocol: TCP #    _meta_kubernetes_service_port_protocol="TCP" port: 9376 targetPort: 80 name: portapi #    __meta_kubernetes_service_port_name="portapi" 

Kleine Beschreibung
  • Art - Gibt an, welcher Entitätstyp in der yaml-Datei beschrieben wird
  • apiVersion - Auf welche API wird das Objekt übertragen?
  • Beschriftungen - im Wesentlichen nur Beschriftungen (Tasten links und Werte können Sie sich selbst ausdenken)
  • Selektor - Ermöglicht das Verknüpfen von Diensten mit der Bereitstellung, z. B. über Labels

Weiter:
 kubectl create -f .\1-deployment-app.yaml 

Und Sie sollten Ihre Bereitstellung in der Schnittstelle http: // localhost: 8001 / api / v1 / namespaces / kube-system / services / https: kubernetes-dashboard: / proxy / #! / Deployment? Namespace = default sehen
Bildschirm

In diesem befindet sich ein Replikatsatz, der anzeigt, dass die Anwendung in zwei Instanzen (Pods) ausgeführt wird, und dass es einen verwandten Dienst mit einer Adresse von außen gibt, um eine synchronisierte Anwendung im Browser zu öffnen
Screenshots



Hinzufügen benutzerdefinierter Metriken zur Anwendung


Das Paket https://www.app-metrics.io/ wurde zur Anwendung hinzugefügt
Ich werde vorerst nicht im Detail beschreiben, wie ich sie hinzufügen werde - ich registriere die Middleware zum Inkrementieren der Zähler von Aufrufen zu den API-Methoden
Hier ist die Middleware
 private static void AutoDiscoverRoutes(HttpContext context) { if (context.Request.Path.Value == "/favicon.ico") return; List<string> keys = new List<string>(); List<string> vals = new List<string>(); var routeData = context.GetRouteData(); if (routeData != null) { keys.AddRange(routeData.Values.Keys); vals.AddRange(routeData.Values.Values.Select(p => p.ToString())); } keys.Add("method"); vals.Add(context.Request.Method); keys.Add("response"); vals.Add(context.Response.StatusCode.ToString()); keys.Add("url"); vals.Add(context.Request.Path.Value); Program.Metrics.Measure.Counter.Increment(new CounterOptions { Name = "api", //ResetOnReporting = true, // ,     MeasurementUnit = Unit.Calls, Tags = new MetricTags(keys.ToArray(), vals.ToArray()) }); } 

Die gesammelten Metriken sind unter http: // localhost: 9376 /metrics verfügbar



* IMetricRoot oder seine Abstraktion kann einfach in Diensten registriert und in der Anwendung verwendet werden ( services.AddMetrics (Program.Metrics); )

Metriksammlung durch Prometheus


Die grundlegendste Prometheus-Einstellung: Fügen Sie der Konfiguration (prometheus.yml) einen neuen Job hinzu und geben Sie ihm ein neues Ziel:
 global: scrape_interval: 15s evaluation_interval: 15s rule_files: # - "first.rules" # - "second.rules" scrape_configs: - job_name: prometheus static_configs: - targets: ['localhost:9090', '__:'] 

Prometheus bietet jedoch native Unterstützung für das Sammeln von Metriken aus kubernetis https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config
Ich möchte jeden Dienst einzeln filtern und nach Apptyp filtern: Geschäftslabel
Nachdem Sie sich mit dem Dock vertraut gemacht haben, gehen Sie wie folgt vor:
 - job_name: business-metrics #     metrics_path: /metrics kubernetes_sd_configs: - role: endpoints #   .   service,pod,ingress static_configs: - targets: - localhost:9090 relabel_configs: #       default   c  apptype = business - action: keep regex: default;business source_labels: - __meta_kubernetes_namespace - __meta_kubernetes_service_label_apptype 

In kubernetis gibt es einen speziellen Ort zum Speichern von Konfigurationsdateien - ConfigMap
Ich speichere diese Konfiguration dort:
2-prometheus-configmap.yaml
 apiVersion: v1 kind: ConfigMap #  ,   metadata: name: prometheus-config #  - namespace: default labels: kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: EnsureExists data: #     prometheus.yml: | global: scrape_interval: 5s # Default is every 1 minute. evaluation_interval: 5s # The default is every 1 minute. scrape_configs: - job_name: prometheus static_configs: - targets: - localhost:9090 - job_name: business-metrics #     metrics_path: /metrics kubernetes_sd_configs: - role: endpoints #   .   service,pod,ingress static_configs: - targets: - localhost:9090 relabel_configs: #       default   c  apptype = business - action: keep regex: default;business source_labels: - __meta_kubernetes_namespace - __meta_kubernetes_service_label_apptype 

Abfahrt nach Kubernetis
 kubectl create -f .\2-prometheus-configmap.yaml 

Jetzt müssen Sie prometheus mit dieser Konfigurationsdatei bereitstellen
kubectl create -f. \ 3-deploy-prometheus.yaml
 apiVersion: extensions/v1beta1 kind: Deployment metadata: name: prometheus namespace: default spec: replicas: 1 template: metadata: labels: app: prometheus-server spec: containers: - name: prometheus image: prom/prometheus args: - "--config.file=/etc/config/prometheus.yml" - "--web.enable-lifecycle" ports: - containerPort: 9090 volumeMounts: - name: prometheus-config-volume #    mountPath: /etc/config/ #     volumes: - name: prometheus-config-volume #     configMap: defaultMode: 420 name: prometheus-config #  - --- kind: Service apiVersion: v1 metadata: name: prometheus spec: selector: app: prometheus-server #    labels:app type: LoadBalancer #      ports: - protocol: TCP port: 9090 targetPort: 9090 

Achtung - die Datei prometheus.yml ist nirgendwo angegeben
Alle Dateien, die in der Konfigurationszuordnung angegeben wurden, werden zu Dateien im Abschnitt prometheus-config-volume, der im Verzeichnis / etc / config / bereitgestellt wird
Außerdem verfügt der Container über Startargumente mit dem Pfad zur Konfiguration
--web.enable-lifecycle - sagt, dass Sie POST / - / reload aufrufen können, wodurch neue Konfigurationen angewendet werden (nützlich, wenn sich die Konfiguration "on the fly" ändert und Sie den Container nicht neu starten möchten).

Eigentlich bereitstellen
 kubectl create -f .\3-deployment-prometheus.yaml 

Befolgen Sie die kleinen Schritte und gehen Sie zur Adresse http: // localhost: 9090 / Ziele . Dort sollten Sie die Endpunkte Ihres Dienstes sehen



Und auf der Hauptseite können Sie Anfragen an den Prometheus schreiben
 sum by (response, action, url, app) (delta(application_api[15s])) 

Vorausgesetzt, jemand hat die Site besucht, wird es so ausfallen


Abfragesprache - https://prometheus.io/docs/prometheus/latest/querying/basics/

Metriken in Grafana anzeigen


Wir hatten Glück - bis Version 5 konnten Dashboard-Konfigurationen nur über die HTTP-API übertragen werden, aber jetzt können Sie den gleichen Trick wie mit Prometeus ausführen
Grafana kann beim Start standardmäßig Datenquellenkonfigurationen und Dashboards aufrufen
  1. /etc/grafana/provisioning/datasources/ - Quellkonfigurationen (Einstellungen für den Zugriff auf Prometeus, Postgres, Zabbiks, Gummiband usw.)
  2. /etc/grafana/provisioning/dashboards/ - /etc/grafana/provisioning/dashboards/ Zugriffseinstellungen
  3. /var/lib/grafana/dashboards/ - hier werde ich die Dashboards selbst in Form von JSON-Dateien speichern

Es stellte sich so heraus
 apiVersion: v1 kind: ConfigMap metadata: creationTimestamp: null name: grafana-provisioning-datasources namespace: default data: all.yml: | datasources: - name: 'Prometheus' type: 'prometheus' access: 'proxy' org_id: 1 url: 'http://prometheus:9090' is_default: true version: 1 editable: true --- apiVersion: v1 kind: ConfigMap metadata: creationTimestamp: null name: grafana-provisioning-dashboards namespace: default data: all.yml: | apiVersion: 1 providers: - name: 'default' orgId: 1 folder: '' type: file disableDeletion: false updateIntervalSeconds: 10 #how often Grafana will scan for changed dashboards options: path: /var/lib/grafana/dashboards --- apiVersion: v1 kind: ConfigMap metadata: creationTimestamp: null name: grafana-dashboards namespace: default data: service-http-requests.json: | { "annotations": { "list": [ { "builtIn": 1, "datasource": "-- Grafana --", "enable": true, "hide": true, "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" } ] }, "editable": true, "gnetId": null, "graphTooltip": 0, "links": [], "panels": [ { "aliasColors": {}, "bars": false, "dashLength": 10, "dashes": false, "fill": 1, "gridPos": { "h": 9, "w": 12, "x": 0, "y": 0 }, "id": 2, "legend": { "alignAsTable": false, "avg": false, "current": false, "max": false, "min": false, "rightSide": true, "show": true, "total": false, "values": false }, "lines": true, "linewidth": 1, "links": [], "nullPointMode": "null", "percentage": false, "pointradius": 5, "points": false, "renderer": "flot", "seriesOverrides": [], "spaceLength": 10, "stack": false, "steppedLine": false, "targets": [ { "expr": "sum by (response, action, url, app) (delta(application_api[15s]))", "format": "time_series", "interval": "15s", "intervalFactor": 1, "legendFormat": "{{app}} {{response}} - {{url}}", "refId": "A" } ], "thresholds": [], "timeFrom": null, "timeRegions": [], "timeShift": null, "title": "Http requests", "tooltip": { "shared": true, "sort": 0, "value_type": "individual" }, "type": "graph", "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] }, "yaxes": [ { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }, { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true } ], "yaxis": { "align": false, "alignLevel": null } } ], "refresh": "5s", "schemaVersion": 16, "style": "dark", "tags": [], "templating": { "list": [] }, "time": { "from": "now-30m", "to": "now" }, "timepicker": { "refresh_intervals": [ "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d" ], "time_options": [ "5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d" ] }, "timezone": "", "title": "Business metrics", "uid": "Dm0tD0Qik", "version": 1 } 

Bereitstellung selbst, nichts Neues
 apiVersion: extensions/v1beta1 kind: Deployment metadata: name: grafana namespace: default labels: app: grafana component: core spec: replicas: 1 template: metadata: labels: app: grafana component: core spec: containers: - image: grafana/grafana name: grafana imagePullPolicy: IfNotPresent resources: limits: cpu: 100m memory: 100Mi requests: cpu: 100m memory: 100Mi env: - name: GF_AUTH_BASIC_ENABLED value: "true" - name: GF_AUTH_ANONYMOUS_ENABLED value: "true" - name: GF_AUTH_ANONYMOUS_ORG_ROLE value: Admin readinessProbe: httpGet: path: /login port: 3000 # initialDelaySeconds: 30 # timeoutSeconds: 1 volumeMounts: - name: grafana-provisioning-datasources mountPath: /etc/grafana/provisioning/datasources/ - name: grafana-provisioning-dashboards mountPath: /etc/grafana/provisioning/dashboards/ - name: grafana-dashboards mountPath: /var/lib/grafana/dashboards/ volumes: - name: grafana-provisioning-datasources configMap: defaultMode: 420 name: grafana-provisioning-datasources - name: grafana-provisioning-dashboards configMap: defaultMode: 420 name: grafana-provisioning-dashboards - name: grafana-dashboards configMap: defaultMode: 420 name: grafana-dashboards nodeSelector: beta.kubernetes.io/os: linux --- apiVersion: v1 kind: Service metadata: name: grafana namespace: default labels: app: grafana component: core spec: type: LoadBalancer ports: - protocol: TCP port: 3000 targetPort: 3000 selector: app: grafana component: core 

Erweitern
 kubectl create -f .\4-grafana-configmap.yaml kubectl create -f .\5-deployment-grafana.yaml 

Denken Sie daran, dass der Graphan nicht sofort steigt, sondern durch SQLite-Migrationen, die Sie in den Protokollen sehen können, etwas gedämpft wird
Gehen Sie jetzt zu http: // localhost: 3000 /
Und klicken Sie auf das Dashboard




Wenn Sie eine neue Ansicht hinzufügen oder eine vorhandene ändern möchten - ändern Sie sie direkt in der Benutzeroberfläche und klicken Sie dann auf Speichern. Sie erhalten ein modales Fenster mit json, das Sie in die Konfigurationszuordnung einfügen müssen
Alles ist bereitgestellt und funktioniert hervorragend

Geplante Aufgaben


Um Aufgaben an der Krone im Cuber auszuführen, gibt es das Konzept von CronJob
Mit CronJob können Sie einen Zeitplan für jede Aufgabe festlegen. Das einfachste Beispiel:
 # https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/ apiVersion: batch/v1beta1 kind: CronJob metadata: name: runapijob spec: schedule: "*/1 * * * *" jobTemplate: spec: template: spec: containers: - name: runapijob image: busybox args: - /bin/sh - -c - date; wget -O - http://metricsdemo:9376/api/job/run/wakeUp > /dev/null restartPolicy: OnFailure 

Der Zeitplanabschnitt legt die klassische Regel für die Krone fest
Der Trigger startet den Pod des Containers (Busybox), in dem ich die Metrikdemo-Service-API-Methode abrufe
Mit dem Befehl können Sie den Job verfolgen.
 kubectl.exe get cronjob runapijob --watch 



Der Hauptdienst, der aus dem Job ruckelt, wird in mehreren Fällen gestartet, da der Anruf an den Dienst mit einer ungefähr gleichmäßigen Verteilung an einen der Herde geht
Wie es in Prometheus aussieht

Um den Job zu debuggen, können Sie ihn manuell auslösen

Eine kleine Demo am Beispiel der Berechnung der Anzahl von π über den Unterschied bei den Starts von der Konsole aus
 #   ,       -      kubectl run pi --image=perl -- perl -Mbignum=bpi -wle 'print bpi(2000)' #   . , ,  .   -   kubectl run pi --image=perl --restart=OnFailure -- perl -Mbignum=bpi -wle 'print bpi(2000)' #    5  kubectl run pi --image=perl --restart=OnFailure --schedule="0/5 * * * ?" -- perl -Mbignum=bpi -wle 'print bpi(2000)' 


Fehlertoleranz


Wenn die Anwendung unerwartet beendet wird, startet der Cluster den Pod neu
Zum Beispiel habe ich eine Methode erstellt, mit der API gelöscht wird
 [HttpGet("kill/me")] public async void Kill() { throw new Exception("Selfkill"); } 

* Die Ausnahme, die in der API bei der asynchronen Void-Methode aufgetreten ist, wird als nicht behandelte Ausnahme betrachtet, die die Anwendung vollständig zum Absturz bringt

Ich appelliere an http: // localhost: 9376 / api / job / kill / me
Die Liste der Herde zeigt, dass einer der Herde des Dienstes neu gestartet wurde



Der Befehl logs zeigt die aktuelle Ausgabe an und mit der Option -p werden die Protokolle der vorherigen Instanz angezeigt. Auf diese Weise können Sie den Grund für den Neustart herausfinden.

Ich denke mit einem einfachen Sturz ist alles klar: fiel - Rose

Die Anwendung kann jedoch bedingt live sein, d.h. nicht gefallen, aber nichts zu tun oder seinen Job zu machen, aber langsam

Gemäß der Dokumentation gibt es mindestens zwei Arten von Überlebensprüfungen von Anwendungen in Pods
  1. Bereitschaft - Diese Art der Überprüfung wird verwendet, um zu verstehen, ob es möglich ist, den Verkehr auf diesem Pod zu starten. Wenn nicht, wird der Pod dereguliert, bis er wieder normal ist.
  2. Lebendigkeit - Überprüfen Sie den Antrag "auf Überlebensfähigkeit". Insbesondere wenn kein Zugriff auf eine wichtige Ressource besteht oder die Anwendung überhaupt nicht reagiert (z. B. Deadlock und daher Zeitüberschreitung), wird der Container neu gestartet. Alle http-Codes zwischen 200 und 400 gelten als erfolgreich, der Rest schlägt fehl

Ich werde den Neustart nach Zeitüberschreitung überprüfen. Dazu werde ich eine neue API-Methode hinzufügen, die nach einem bestimmten Befehl die Methode zur Überprüfung der Überlebensfähigkeit für 123 Sekunden verlangsamt

 static bool deadlock; [HttpGet("alive/{cmd}")] public string Kill(string cmd) { if (cmd == "deadlock") { deadlock = true; return "Deadlocked"; } if (deadlock) Thread.Sleep(123 * 1000); return deadlock ? "Deadlocked!!!" : "Alive"; } 


Ich füge der Datei 1-deploy-app.yaml im Container einige Abschnitte hinzu:
 containers: - name: metricsdemo image: localhost:5000/sansys/metricsdemo3:6 ports: - containerPort: 80 readinessProbe: #       httpGet: path: /health port: 80 initialDelaySeconds: 5 periodSeconds: 5 livenessProbe: #      httpGet: path: /api/job/alive/check port: 80 initialDelaySeconds: 5 periodSeconds: 5 

Ich bin mir sicher, dass die App gestartet wurde und Ereignisse abonniert
 kubectl get events --watch 

Ich drücke auf das Menü Deadlock me ( http: // localhost: 9376 / api / job / living / deadlock )



Und innerhalb von fünf Sekunden beginne ich, das Problem und seine Lösung zu beobachten

 1s Warning Unhealthy Pod Liveness probe failed: Get http://10.1.0.137:80/api/job/alive/check: net/http: request canceled (Client.Timeout exceeded while awaiting headers) 1s Warning Unhealthy Pod Liveness probe failed: Get http://10.1.0.137:80/api/job/alive/check: net/http: request canceled (Client.Timeout exceeded while awaiting headers) 0s Warning Unhealthy Pod Liveness probe failed: Get http://10.1.0.137:80/api/job/alive/check: net/http: request canceled (Client.Timeout exceeded while awaiting headers) 0s Warning Unhealthy Pod Readiness probe failed: Get http://10.1.0.137:80/health: dial tcp 10.1.0.137:80: connect: connection refused 0s Normal Killing Pod Killing container with id docker://metricsdemo:Container failed liveness probe.. Container will be killed and recreated. 0s Normal Pulled Pod Container image "localhost:5000/sansys/metricsdemo3:6" already present on machine 0s Normal Created Pod Created container 0s Normal Started Pod Started container 


Schlussfolgerungen


  1. Einerseits stellte sich heraus, dass die Eintrittsschwelle viel niedriger war als ich dachte, andererseits handelt es sich überhaupt nicht um einen echten Kubernetes-Cluster, sondern nur um einen Entwicklercomputer. Und die Grenzen für Ressourcen, Stateful Applications, A / B-Tests usw. wurden nicht berücksichtigt.
  2. Prometeus hat es zum ersten Mal versucht, aber das Lesen verschiedener Dokumente und Beispiele während der Überprüfung des Cuber hat deutlich gemacht, dass es sehr gut zum Sammeln von Metriken aus dem Cluster und den Anwendungen geeignet ist
  3. Es ist so gut, dass der Entwickler eine Funktion auf seinem Computer implementieren und zusätzlich zu den Informationen zur Bereitstellung die Bereitstellung des Zeitplans an den Graphan anhängen kann. Infolgedessen werden neue Metriken automatisch ohne zusätzliche Metriken erstellt. Die Bemühungen werden auf der Bühne und auf dem Produkt gezeigt. Bequem


Anmerkungen


  1. Anwendungen können sich unter dem : kontaktieren : , was mit grafana → prometeus gemacht wurde. Für diejenigen, die mit Docker-Compose vertraut sind, gibt es nichts Neues
  2. kubectl create -f file.yml - Erstelle eine Entität
  3. kubectl delete -f file.yml - löscht eine Entität
  4. kubectl get pod - kubectl get pod sich eine Liste aller Herde (Service, Endpunkte ...)
    • --namespace=kube-system - Filtern nach Namespace
    • -n kube-system - ähnlich
  5. kubectl -it exec grafana-d8d4d9f5c-cvnkh -- /bin/bash - Anhang an der Unterseite
  6. kubectl delete service grafana - lösche einen service, pod. Bereitstellung (--all - alle löschen)
  7. kubectl describe - beschreiben Sie die Entität (Sie können alles auf einmal tun)
  8. kubectl edit service metricsdemo - Bearbeiten Sie alle Yamls im Handumdrehen durch den Start des Notepads
    Demo
  9. kubectl --help - große Hilfe)
  10. Ein typisches Problem ist, dass es einen Pod gibt (betrachten Sie das laufende Image), etwas schief gelaufen ist und es keine Optionen gibt, außer es gibt keine Möglichkeit, darin zu debuggen (über tcpdump / nc usw.). - Yuzai kubectl-debug habr.com/de/company/flant/blog/436112


Referenzliste


  1. Was sind App-Metriken?
  2. Kubernetes
  3. Prometheus
  4. Vorbereitete Grafana-Konfiguration
  5. Um zu sehen, wie es den Leuten geht (aber es gibt bereits einige Dinge, die veraltet sind) - im Prinzip geht es auch um Protokollierung, Warnungen usw.
  6. Helm - Der Paketmanager für Kubernetes - dadurch war es einfacher, prometeus + grafana zu organisieren, aber manuell - es erscheint mehr Verständnis
  7. Würfel für Prometheus von Coober
  8. Kubernetes-Fehlergeschichten
  9. Kubernetes-HA. Stellen Sie den Kubernetes-Failovercluster mit 5 Assistenten bereit

Quellcode und Marmeladen auf Github verfügbar

Source: https://habr.com/ru/post/de437286/


All Articles