One place for hosting & domains

      Bereitstellen einer skalierbaren und sicheren Django-Anwendung mit Kubernetes


      Einführung

      In diesem Tutorial stellen Sie eine containerisierte Django-Umfrageanwendung in einem Kubernetes-Cluster bereit.

      Django ist ein leistungsfähiges Web-Framework, das Ihnen dabei helfen kann, Ihre Python-Anwendung schnell bereitzustellen. Es enthält mehrere praktische Funktionen wie einen objektrelationalen Mapper, eine Benutzerauthentifizierung und eine anpassbare Verwaltungsoberfläche für Ihre Anwendung. Es beinhaltet auch ein Caching-Framework und fördert ein sauberes App-Design durch seinen URL Dispatcher und das Vorlagensystem.

      In Erstellen einer Django- und Gunicorn-Anwendung mit Docker wurde die Django Tutorial Umfrageanwendung gemäß der Zwölf-Faktor-Methodik zur Erstellung skalierbarer Cloud-nativer Web-Apps modifiziert. Diese containerisierte Einrichtung wurde mit einem Nginx Reverse-Proxy und Let’s Encrypt-signierten TLS-Zertifikaten in Skalieren und Sichern einer Django-Anwendung mit Docker, Nginx und Let’s Encrypt skaliert und gesichert. In diesem letzten Tutorial der Reihe Von Containern zu Kubernetes mit Django wird die modernisierte Django-Umfrageanwendung in einem Kubernetes-Cluster bereitgestellt.

      Kubernetes ist ein leistungsstarker Open-Source-Container-Orchestrator, der die Bereitstellung, das Skalieren und die Verwaltung von containerisierten Anwendungen automatisiert. Mit Kubernetes-Objekten wie ConfigMaps und Secrets können Sie die Konfiguration zentralisieren und von Ihren Containern entkoppeln, während Controller wie Deployments fehlgeschlagene Container automatisch neu starten und eine schnelle Skalierung von Container-Replikaten ermöglichen. Die TLS-Verschlüsselung wird mit einem Ingress-Objekt und dem Open-Source Ingress-Controller ingress-nginx aktiviert. Das Kubernetes Add-on cert-manager erneuert und stellt Zertifikate mit der kostenlosen Zertifizierungsstelle Let’s Encrypt aus.

      Voraussetzungen

      Um dieser Anleitung zu folgen, benötigen Sie:

      • Einen Kubernetes 1.15+-Cluster mit aktivierter rollenbasierter Zugriffskontrolle (RBAC). In diesem Setup wird ein DigitalOcean Kubernetes-Cluster verwendet, doch Sie können einen Cluster auch mit einer anderen Methode erstellen.
      • Das Befehlszeilen-Tool kubectl, das auf Ihrem lokalen Rechner installiert und für die Verbindung mit Ihrem Cluster konfiguriert ist. Weitere Informationen zur Installation von kubectl finden Sie in der offiziellen Dokumentation. Wenn Sie einen DigitalOcean Kubernetes-Cluster verwenden, lesen Sie bitte Verbinden mit einem DigitalOcean Kubernetes-Cluster, um zu erfahren, wie Sie sich mit kubectl mit Ihrem Cluster verbinden können.
      • Einen registrierten Domänennamen. In diesem Tutorial wird durchgängig your_domain.com verwendet. Einen Domänennamen können Sie kostenlos bei Freenom erhalten oder Sie nutzen eine Domänenregistrierungsstelle Ihrer Wahl.
      • Einen ingress-nginx Ingress-Controller und den TLS-Zertifizierungsmanager cert-manager, die in Ihrem Cluster installiert und zur Ausgabe von TLS-Zertifikaten konfiguriert sind. Um zu erfahren, wie Sie einen Ingress mit cert-manager installieren und konfigurieren, konsultieren Sie bitte Einrichten eines Nginx Ingress mit Cert-Manager in DigitalOcean Kubernetes.
      • Einen A-DNS-Datensatz mit your_domain.com, der auf die öffentliche IP-Adresse des Ingress Load Balancers verweist. Wenn Sie DigitalOcean zum Verwalten der DNS-Datensätze Ihrer Domäne verwenden, konsultieren Sie bitte Verwalten von DNS-Datensätzen, um zu erfahren, wie Sie A-Datensätze erstellen.
      • Einen S3-Objektspeicher-Bucket wie beispielsweise einen DigitalOcean Space zur Speicherung der statischen Dateien Ihres Django-Projekts und einen Satz von Zugriffsschlüsseln für diesen Space. Um zu erfahren, wie Sie einen Space erstellen können, lesen Sie die Produktdokumentation Erstellen von Spaces. Um zu erfahren, wie Sie Zugriffsschlüssel für Spaces erstellen können, lesen Sie Zugriff auf Spaces mit Zugriffsschlüsseln gemeinsam nutzen. Mit geringfügigen Änderungen können Sie jeden Objektspeicherdienst verwenden, der das Plugin django-storages verwendet.
      • Eine PostgreSQL-Server-Instanz, Datenbank und Benutzer für Ihre Django-Anwendung. Mit geringfügigen Änderungen können Sie jede Datenbank verwenden, die Django unterstützt.
      • Ein Docker Hub-Konto und ein öffentliches Repository. Weitere Informationen zu deren Erstellung finden Sie in Repositories in der Docker-Dokumentation.
      • Die auf Ihrem lokalen Rechner installierte Docker-Engine. Weitere Informationen finden Sie unter Installieren und Verwenden von Docker unter Ubuntu 18.04.

      Sobald Sie diese Komponenten eingerichtet haben, können Sie mit diesem Leitfaden beginnen.

      Schritt 1 — Klonen und Konfigurieren der Anwendung

      In diesem Schritt klonen wir den Anwendungscode von GitHub und konfigurieren Einstellungen wie Datenbankzugangsdaten und Objektspeicherschlüssel.

      Der Anwendungscode und das Dockerfile befinden sich im Zweig polls-docker der Django Tutorial Umfrageanwendung GitHub-Repository. Dieses Repository enthält Code für die Beispiel-Umfrageanwendung aus der Django-Dokumentation, in der Sie lernen, wie Sie eine Umfrageanwendung von Grund auf erstellen.

      Der Zweig polls-docker enthält eine dockerisierte Version der Umfrageanwendung. Um zu erfahren, wie die Umfrageanwendung modifiziert wurde, um effektiv in einer containerisierten Umgebung zu arbeiten, lesen Sie bitte Erstellen einer Django- und Gunicorn-Anwendung mit Docker.

      Beginnen Sie mit der Verwendung von git zum Klonen des Zweigs polls-docker der Django Tutorial Umfrageanwendung GitHub-Repository auf Ihren lokalen Rechner:

      • git clone --single-branch --branch polls-docker https://github.com/do-community/django-polls.git

      Navigieren Sie in das Verzeichnis django-polls:

      Dieses Verzeichnis enthält den Python-Code der Django-Anwendung, ein Dockerfile, das Docker zum Erstellen des Container-Images verwendet, sowie eine Datei env, die eine Liste von Umgebungsvariablen enthält, die an die laufende Umgebung des Containers übergeben werden müssen. Prüfen Sie das Dockerfile:

      Output

      FROM python:3.7.4-alpine3.10 ADD django-polls/requirements.txt /app/requirements.txt RUN set -ex && apk add --no-cache --virtual .build-deps postgresql-dev build-base && python -m venv /env && /env/bin/pip install --upgrade pip && /env/bin/pip install --no-cache-dir -r /app/requirements.txt && runDeps="$(scanelf --needed --nobanner --recursive /env | awk '{ gsub(/,/, "nso:", $2); print "so:" $2 }' | sort -u | xargs -r apk info --installed | sort -u)" && apk add --virtual rundeps $runDeps && apk del .build-deps ADD django-polls /app WORKDIR /app ENV VIRTUAL_ENV /env ENV PATH /env/bin:$PATH EXPOSE 8000 CMD ["gunicorn", "--bind", ":8000", "--workers", "3", "mysite.wsgi"]

      Dieses Dockerfile verwendet das offizielle Python 3.7.4 Docker-Image als Basis und installiert die Python-Paketanforderungen von Django und Gunicorn, wie sie in der Datei django-polls/requirements.txt definiert sind. Anschließend entfernt es einige unnötige Builddateien, kopiert den Anwendungscode in das Image und legt den Ausführungspfad PATH fest. Schließlich gibt es an, dass Port 8000 verwendet wird, um eingehende Container-Verbindungen zu akzeptieren und gunicorn mit 3 Workern ausgeführt wird, die Port 8000 abhören.

      Um mehr über die einzelnen Schritte in diesem Dockerfile zu erfahren, lesen Sie bitte Schritt 6 von Erstellen einer Django- und Gunicorn-Anwendung mit Docker.

      Erstellen Sie nun das Image mit docker build:

      Wir benennen das Image polls mit dem Flag -t und übergeben im aktuellen Verzeichnis als Build-Kontext den Satz von Daten, auf den beim Erstellen des Images verwiesen werden soll.

      Nachdem Docker das Image erstellt und mit Tags versehen hat, listen wir die verfügbaren Images mit docker images auf:

      Sie sollten die polls-Images aufgelistet sehen:

      OutputREPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
      polls               latest              80ec4f33aae1        2 weeks ago         197MB
      python              3.7.4-alpine3.10    f309434dea3a        8 months ago        98.7MB
      

      Bevor wir den Django-Container ausführen, müssen wir seine Betriebsumgebung mithilfe der im aktuellen Verzeichnis vorhandenen Datei env konfigurieren. Diese Datei wird an den Befehl docker run übergeben, der zum Ausführen des Containers verwendet wird, und Docker injiziert die konfigurierten Umgebungsvariablen in die Betriebsumgebung des Containers.

      Öffnen Sie die Datei env mit nano oder Ihrem bevorzugten Editor:

      django-polls/env

      DJANGO_SECRET_KEY=
      DEBUG=True
      DJANGO_ALLOWED_HOSTS=
      DATABASE_ENGINE=postgresql_psycopg2
      DATABASE_NAME=polls
      DATABASE_USERNAME=
      DATABASE_PASSWORD=
      DATABASE_HOST=
      DATABASE_PORT=
      STATIC_ACCESS_KEY_ID=
      STATIC_SECRET_KEY=
      STATIC_BUCKET_NAME=
      STATIC_ENDPOINT_URL=
      DJANGO_LOGLEVEL=info
      

      Geben Sie die fehlenden Werte für die folgenden Schlüssel ein:

      • DJANGO_SECRET_KEY: Setzen Sie diesen auf einen eindeutigen, nicht vorhersagbaren Wert, wie in den Django-Dokumentationen beschrieben. Eine Methode zur Generierung dieses Wertes wird in Anpassen der Anwendungseinstellungen in dem Tutorial Skalierbare Django-Anwendung angeboten.
      • DJANGO_ALLOWED_HOSTS: Diese Variable sichert die Anwendung und verhindert HTTP-Host-Header-Angriffe. Setzen Sie diese Variable für Testzwecke auf *, einen Platzhalter, der auf alle Hosts zutrifft. In der Produktion sollten Sie diese Variable auf your_domain.com setzen. Um mehr über diese Django-Einstellungen zu erfahren, konsultieren Sie die Core-Einstellungen der Django-Dokumentation.
      • DATABASE_USERNAME: Setzen Sie diesen auf den in den vorbereitenden Schritten erstellten PostgreSQL Datenbankbenutzer.
      • DATABASE_NAME: Setzen Sie diesen auf polls oder den in den vorbereitenden Schritten erstellten Namen der PostgreSQL-Datenbank.
      • DATABASE_PASSWORD: Setzen Sie dieses auf das in den vorbereitenden Schritten erstellte Passwort für den PostgreSQL Benutzer.
      • DATABASE_HOST: Setzen Sie diesen Wert auf den Hostnamen Ihrer Datenbank.
      • DATABASE_PORT: Setzen Sie diesen Wert auf den Port Ihrer Datenbank.
      • STATIC_ACCESS_KEY_ID: Setzen Sie dies auf den Zugriffsschlüssel Ihres Space oder Objektspeichers.
      • STATIC_SECRET_KEY: Setzen Sie dies auf den Zugriffsschlüssel Ihres Space- oder Objektspeicher-Secret.
      • STATIC_BUCKET_NAME: Setzen Sie dies auf den Namen Ihres Space- oder Objektspeicher-Buckets.
      • STATIC_ENDPOINT_URL: Setzen Sie diese auf die entsprechende Endpunkt-URL des Space oder Objektspeichers, z. B. https://space-name.nyc3.digitaloceanspaces.com, wenn sich Ihr Space in der Region nyc3 befindet.

      Wenn Sie die Bearbeitung abgeschlossen haben, speichern und schließen Sie die Datei.

      Im nächsten Schritt führen wir den konfigurierten Container lokal aus und erstellen das Datenbankschema. Wir laden ebenfalls statische Assets wie Stylesheets und Images in den Objektspeicher hoch.

      Schritt 2 — Erstellen des Datenbankschemas und Hochladen von Assets in den Objektspeicher

      Nachdem der Container erstellt und konfiguriert ist, verwenden wir nun docker run, um den CMD-Satz in dem Dockerfile zu überschreiben und das Datenbankschema mit den Befehlen manage.py makemigrations und manage.py migrate zu erstellen:

      • docker run --env-file env polls sh -c "python manage.py makemigrations && python manage.py migrate"

      Wir führen das Container-Image polls:latest aus, übergeben die von uns gerade modifizierte Umgebungsvariablendatei und überschreiben den Dockerfile-Befehl mit sh -c "python manage.py makemigrations && python manage.py migrate", wodurch das durch den Anwendungscode definierte Datenbankschema erstellt wird.

      Wenn Sie dies zum ersten Mal ausführen, sollten Sie Folgendes sehen:

      Output

      No changes detected Operations to perform: Apply all migrations: admin, auth, contenttypes, polls, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying auth.0010_alter_group_name_max_length... OK Applying auth.0011_update_proxy_permissions... OK Applying polls.0001_initial... OK Applying sessions.0001_initial... OK

      Dies zeigt an, dass das Datenbankschema erfolgreich erstellt wurde.

      Wenn Sie migrate zu einem späteren Zeitpunkt ausführen, führt Django eine Nulloperation durch, es sei denn, das Datenbankschema wurde geändert.

      Als Nächstes führen wir eine weitere Instanz des Anwendungscontainers aus und verwenden darin eine interaktive Shell, um einen Administratorbenutzer für das Django-Projekt zu erstellen.

      • docker run -i -t --env-file env polls sh

      Dadurch erhalten Sie eine Shell-Eingabeaufforderung innerhalb des laufenden Containers, die Sie zum Erstellen des Django-Benutzers verwenden können:

      • python manage.py createsuperuser

      Geben Sie einen Benutzernamen, eine E-Mail-Adresse und ein Passwort für Ihren Benutzer ein. Drücken Sie nach dem Erstellen des Benutzers STRG+D, um den Container zu verlassen und zu beenden.

      Schließlich generieren wir die statischen Dateien für die Anwendung und laden sie mit collectstatic in den DigitalOcean Space hoch. Beachten Sie, dass dies möglicherweise einige Zeit dauern kann.

      • docker run --env-file env polls sh -c "python manage.py collectstatic --noinput"

      Nachdem diese Dateien generiert und hochgeladen sind, erhalten Sie folgende Ausgabe.

      Output

      121 static files copied.

      Wir können die Anwendung nun ausführen:

      • docker run --env-file env -p 80:8000 polls

      Output

      [2019-10-17 21:23:36 +0000] [1] [INFO] Starting gunicorn 19.9.0 [2019-10-17 21:23:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1) [2019-10-17 21:23:36 +0000] [1] [INFO] Using worker: sync [2019-10-17 21:23:36 +0000] [7] [INFO] Booting worker with pid: 7 [2019-10-17 21:23:36 +0000] [8] [INFO] Booting worker with pid: 8 [2019-10-17 21:23:36 +0000] [9] [INFO] Booting worker with pid: 9

      Hier führen wir den in dem Dockerfile definierten Standardbefehl gunicorn ---bind :8000 --workers 3 mysite.wsgi:application aus und geben den Container-Port 8000 frei, sodass Port 80 auf Ihrem lokalen Rechner dem Port 8000 des Containers polls zugeordnet wird.

      Sie sollten nun über Ihren Webbrowser zu der Anwendung polls navigieren können, indem Sie http://localhost in die URL-Leiste eingeben. Da für den Pfad / keine Route definiert ist, erhalten Sie wahrscheinlich einen 404 Page Not Found-Fehler, der zu erwarten ist.

      Navigieren Sie zu http://localhost/polls, um die Benutzeroberfläche der Umfrageanwendung zu sehen:

      Oberfläche der Umfrageanwendung

      Um die administrative Oberfläche anzuzeigen, besuchen Sie http://localhost/admin. Sie sollten das Authentifizierungsfenster für den Administrator der Umfrageanwendung sehen:

      Authentifizierungsseite für Polls-Administrator

      Geben Sie den administrativen Benutzernamen und das Passwort ein, das Sie mit dem Befehl createsuperuser erstellt haben.

      Nach der Authentifizierung können Sie auf die administrative Oberfläche der Umfrageanwendung zugreifen:

      Administrative Hauptoberfläche von Polls

      Beachten Sie, dass statische Assets für die Anwendungen admin und polls direkt aus dem Objektspeicher bereitgestellt werden. Um dies zu bestätigen, konsultieren Sie Prüfen der statischen Dateizustellung von Spaces.

      Wenn Sie die Erkundung abgeschlossen haben, drücken Sie STRG+C im Terminalfenster, in dem der Docker-Container ausgeführt wird, um den Container zu beenden.

      Nachdem das Docker-Image der Django-Anwendung getestet, die statischen Assets in den Objektspeicher hochgeladen und das Datenbankschema konfiguriert und für die Verwendung mit Ihrer Anwendung bereit ist/sind, können Sie Ihr Django-App-Image in eine Bildregistrierung wie Docker Hub hochladen.

      Schritt 3 — Verschieben des Django-App-Images zu Docker Hub

      Um Ihre Anwendung unter Kubernetes bereitzustellen, muss Ihr App-Image in eine Registrierung wie Docker Hub hochgeladen werden. Kubernetes zieht das App-Image aus seinem Repository und stellt es dann in Ihren Cluster bereit.

      Sie können eine private Docker-Registrierung verwenden, wie die DigitalOcean Container Registry, die derzeit kostenlos in Early Access ist, oder eine öffentliche Docker-Registrierung wie Docker Hub. Mit Docker Hub können Sie auch private Docker-Repositorys erstellen. Ein öffentliches Repository erlaubt jedem, die Container-Images zu sehen und abzurufen, während Sie mit einem privaten Repository den Zugriff auf Sie und Ihre Teammitglieder beschränken können.

      In diesem Tutorial verschieben wir das Django-Image in das öffentliche Docker Hub-Repository, das in den Voraussetzungen erstellt wurde. Sie können Ihr Image auch in ein privates Repository verschieben, aber das Abrufen von Images aus einem privaten Repository liegt außerhalb des Rahmens dieses Artikels. Um mehr über die Authentifizierung von Kubernetes mit Docker Hub und das Abrufen von privaten Images zu erfahren, lesen Sie bitte Abrufen eines Images aus einer privaten Registrierung aus den Kubernetes-Dokumenten.

      Beginnen Sie mit der Anmeldung an Docker Hub auf Ihrem lokalen Rechner:

      Output

      Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username:

      Geben Sie Ihren Docker Hub-Benutzernamen und Ihr Passwort ein, um sich anzumelden.

      Das Django-Image hat derzeit die Markierung polls:latest. Um es in Ihr Docker Hub-Repository zu verschieben, markieren Sie das Image erneut mit Ihrem Docker Hub-Benutzernamen und dem Repository-Namen:

      • docker tag polls:latest your_dockerhub_username/your_dockerhub_repo_name:latest

      Verschieben Sie das Image in das Repository:

      • docker push sammy/sammy-django:latest

      In diesem Tutorial ist der Docker Hub-Benutzername sammy und der Repository-Name ist sammy-django. Sie sollten diese Werte durch Ihren eigenen Docker Hub-Benutzernamen und Repository-Namen ersetzen.

      Sie sehen eine Ausgabe, die sich aktualisiert, wenn Image-Schichten in Docker Hub verschoben werden.

      Nachdem Ihr Image nun für Kubernetes unter Docker Hub verfügbar ist, können Sie es in Ihrem Cluster bereitstellen.

      Schritt 4 — Einrichten der ConfigMap

      Als wir den Django-Container lokal ausgeführt haben, haben wir die Datei env an docker run übergeben, um Konfigurationsvariablen in die Laufzeitumgebung zu injizieren. Bei Kubernetes können Konfigurationsvariablen mit ConfigMaps und Secrets injiziert werden.

      ConfigMaps sollte verwendet werden, um nicht vertrauliche Konfigurationsdaten wie App-Einstellungen zu speichern, und Secrets sollte für sensible Informationen wie API-Schlüssel und Datenbank-Zugangsdaten verwendet werden. Sie werden beide auf ähnliche Weise in Container injiziert, aber Secrets haben zusätzliche Zugriffskontrolle und Sicherheitsfunktionen wie Verschlüsselung im Ruhezustand. Secrets speichern außerdem Daten in base64, während ConfigMaps Daten im Klartext speichern.

      Erstellen Sie zunächst ein Verzeichnis namens yaml, in dem wir unsere Kubernetes-Manifeste speichern werden. Navigieren Sie in das Verzeichnis.

      Öffnen Sie eine Datei namens polls-configmap.yaml in nano oder Ihrem bevorzugten Texteditor:

      • nano polls-configmap.yaml

      Fügen Sie das folgende ConfigMap-Manifest ein:

      polls-configmap.yaml

      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: polls-config
      data:
        DJANGO_ALLOWED_HOSTS: "*"
        STATIC_ENDPOINT_URL: "https://your_space_name.space_region.digitaloceanspaces.com"
        STATIC_BUCKET_NAME: "your_space_name"
        DJANGO_LOGLEVEL: "info"
        DEBUG: "True"
        DATABASE_ENGINE: "postgresql_psycopg2"
      

      Wir haben die nicht sensible Konfiguration aus der in Schritt 1 geänderten Datei env extrahiert und in ein ConfigMap-Manifest eingefügt. Das ConfigMap-Objekt wird polls-config genannt. Kopieren Sie die gleichen Werte hinein, die Sie im vorherigen Schritt in die Datei env eingegeben haben.

      Lassen Sie für Testzwecke DJANGO_ALLOWED_HOSTS auf * stehen, um die Host-Header-basierte Filterung zu deaktivieren. In einer Produktionsumgebung sollten Sie dies auf die Domäne Ihrer Anwendung setzen.

      Wenn Sie mit der Bearbeitung der Datei fertig sind, speichern und schließen Sie sie.

      Erstellen Sie die ConfigMap in Ihrem Cluster mit kubectl apply:

      • kubectl apply -f polls-configmap.yaml

      Output

      configmap/polls-config created

      Nachdem die ConfigMap erstellt wurde, erstellen wir im nächsten Schritt das von unserer Anwendung verwendete Secret.

      Schritt 5 — Einrichten des Secret

      Secret-Werte müssen base64-kodiert sein, d. h. das Erstellen von Secret-Objekten in Ihrem Cluster ist etwas aufwendiger als das Erstellen von ConfigMaps. Sie können den Vorgang aus dem vorherigen Schritt wiederholen, indem Sie Secret-Werte manuell base64-kodieren und in eine Manifestdatei einfügen. Sie können sie auch mit einer Umgebungsvariablendatei kubectl create und dem Flag --from-env-file erstellen, was wir in diesem Schritt tun werden.

      Wir verwenden erneut die Datei env von Schritt 1 und entfernen die in die ConfigMap eingefügten Variablen. Erstellen Sie eine Kopie der Datei env mit dem Namen polls-secrets im Verzeichnis yaml:

      • cp ../env ./polls-secrets

      Bearbeiten Sie die Datei in Ihrem bevorzugten Editor:

      polls-secrets

      DJANGO_SECRET_KEY=
      DEBUG=True
      DJANGO_ALLOWED_HOSTS=
      DATABASE_ENGINE=postgresql_psycopg2
      DATABASE_NAME=polls
      DATABASE_USERNAME=
      DATABASE_PASSWORD=
      DATABASE_HOST=
      DATABASE_PORT=
      STATIC_ACCESS_KEY_ID=
      STATIC_SECRET_KEY=
      STATIC_BUCKET_NAME=
      STATIC_ENDPOINT_URL=
      DJANGO_LOGLEVEL=info
      

      Löschen Sie alle in das ConfigMap-Manifest eingefügten Variablen. Wenn Sie fertig sind, sollte die Datei wie folgt aussehen:

      polls-secrets

      DJANGO_SECRET_KEY=your_secret_key
      DATABASE_NAME=polls
      DATABASE_USERNAME=your_django_db_user
      DATABASE_PASSWORD=your_django_db_user_password
      DATABASE_HOST=your_db_host
      DATABASE_PORT=your_db_port
      STATIC_ACCESS_KEY_ID=your_space_access_key
      STATIC_SECRET_KEY=your_space_access_key_secret
      

      Stellen Sie sicher, dass Sie die gleichen Werte wie in Schritt 1 verwenden. Wenn Sie fertig sind, speichern und schließen Sie die Datei.

      Erstellen Sie das Secret in Ihrem Cluster mit kubectl create secret:

      • kubectl create secret generic polls-secret --from-env-file=poll-secrets

      Output

      secret/polls-secret created

      Hier erstellen wir ein Secret-Objekt namens polls-secret und übergeben die soeben erstellte Secrets-Datei.

      Sie können das Secret mit kubectl describe inspizieren:

      • kubectl describe secret polls-secret

      Output

      Name: polls-secret Namespace: default Labels: <none> Annotations: <none> Type: Opaque Data ==== DATABASE_PASSWORD: 8 bytes DATABASE_PORT: 5 bytes DATABASE_USERNAME: 5 bytes DJANGO_SECRET_KEY: 14 bytes STATIC_ACCESS_KEY_ID: 20 bytes STATIC_SECRET_KEY: 43 bytes DATABASE_HOST: 47 bytes DATABASE_NAME: 5 bytes

      Zu diesem Zeitpunkt haben Sie die Konfiguration Ihrer Anwendung in Ihrem Kubernetes-Cluster mithilfe der Objekttypen Secret und ConfigMap gespeichert. Wir sind nun bereit, die Anwendung in dem Cluster bereitzustellen.

      Schritt 6 — Bereitstellen der Django-Anwendung mithilfe eines Deployment

      In diesem Schritt erstellen Sie ein Deployment für Ihre Django-Anwendung. Eine Kubernetes Deployment ist ein Controller, der zur Verwaltung von zustandslosen Anwendungen in Ihrem Cluster verwendet werden kann. Ein Controller ist eine Kontrollschleife, die Arbeitslasten reguliert, indem er sie herauf- oder herunterskaliert. Controller starten auch fehlgeschlagene Container neu und leeren sie aus.

      Deployments steuern ein oder mehrere Pods, die kleinste einsetzbare Einheit in einem Kubernetes-Cluster. Pods umschließen einen oder mehrere Container. Um mehr über die verschiedenen Arten von Arbeistlasten zu erfahren, die Sie starten können, lesen Sie bitte Eine Einführung in Kubernetes.

      Öffnen Sie zunächst eine Datei namens polls-deployment.yaml in Ihrem bevorzugten Editor:

      • nano polls-deployment.yaml

      Fügen Sie das folgende Deployment-Manifest ein:

      polls-deployment.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: polls-app
        labels:
          app: polls
      spec:
          replicas: 2
        selector:
          matchLabels:
            app: polls
        template:
          metadata:
            labels:
              app: polls
          spec:
            containers:
              - image: your_dockerhub_username/app_repo_name:latest
                name: polls
                envFrom:
                - secretRef:
                    name: polls-secret
                - configMapRef:
                    name: polls-config
                ports:
                  - containerPort: 8000
                    name: gunicorn
      

      Geben Sie den entsprechenden Container-Image-Namen ein und verweisen Sie dabei auf das Django Umfrage-Image, das Sie in Schritt 2 in Docker Hub verschoben haben.

      Hier definieren wir eine Kubernetes Deployment namens polls-app und kennzeichnen es mit dem Schlüsselwertpaar app: polls. Wir geben an, dass wir zwei Replikate des Pods ausführen möchten, der unterhalb des Felds template definiert ist.

      Durch die Verwendung von envFrom mit secretRef und configMapRef legen wir fest, dass alle Daten aus dem Secret polls-secret und der ConfigMap polls-config als Umgebungsvariablen in die Container injiziert werden sollen. Die Schlüssel ConfigMap und Secret werden zu den Namen der Umgebungsvariablen.

      Abschließend geben wir containerPort 8000 frei und nennen ihn gunicorn.

      Um mehr über die Konfiguration von Kubernetes Deployments zu erfahren, konsultieren Sie bitte Deployments aus der Kubernetes-Dokumentation.

      Wenn Sie mit der Bearbeitung der Datei fertig sind, speichern und schließen Sie sie.

      Erstellen Sie das Deployment in Ihrem Cluster mit kubectl apply -f:

      • kubectl apply -f polls-deployment.yaml
      • deployment.apps/polls-app created

      Überprüfen Sie mit kubectl get, ob das Deployment korrekt bereitgestellt wurde:

      • kubectl get deploy polls-app

      Output

      NAME READY UP-TO-DATE AVAILABLE AGE polls-app 2/2 2 2 6m38s

      Wenn Sie auf einen Fehler stoßen, oder etwas nicht so ganz funktioniert, können Sie kubectl describe verwenden, um das fehlgeschlagene Deployment zu inspizieren:

      Sie können die beiden Pods mit kubectl get pod inspizieren:

      Output

      NAME READY STATUS RESTARTS AGE polls-app-847f8ccbf4-2stf7 1/1 Running 0 6m42s polls-app-847f8ccbf4-tqpwm 1/1 Running 0 6m57s

      Zwei Replikate Ihrer Django-Anwendung sind nun im Cluster in Betrieb. Um auf die Anwendung zuzugreifen, müssen Sie einen Kubernetes-Dienst erstellen, was wir als Nächstes tun.

      Schritt 7 — Erlauben des externen Zugriffs unter Verwendung eines Dienstes

      In diesem Schritt erstellen Sie einen Dienst für Ihre Django-Anwendung. Ein Kubernetes-Dienst ist eine Abstraktion, die es Ihnen ermöglicht, einen Satz laufender Pods als Netzwerkdienst bereitzustellen. Mit einem Dienst können Sie einen stabilen Endpunkt für Ihre Anwendung erstellen, der sich nicht ändert, wenn Pods sterben und neu erstellt werden.

      Es gibt mehrere Dienstarten, einschließlich ClusterIP-Dienste, die den Dienst auf einer clusterinternen IP-Adresse bereitstellen, NodePort-Dienste, die den Dienst auf jedem Knoten an einem statischen Port, dem Nodeport, bereitstellen, und LoadBalancer-Dienste, die einen Cloud-Load-Balancer bereitstellen, um externen Datenverkehr zu den Pods in Ihrem Cluster zu leiten (über NodePorts, die er automatisch erstellt). Um mehr über diese zu erfahren, lesen Sie bitte Service in den Kubernetes-Dokumenten.

      In unserer endgültigen Einrichtung verwenden wir einen ClusterIP-Dienst, der über einen Ingress und den in den Voraussetzungen für diesen Leitfaden eingerichteten Ingress-Controller freigegeben wird. Um zu testen, ob alles korrekt funktioniert, erstellen wir zunächst einen temporären NodePort-Dienst, um auf die Django-Anwendung zuzugreifen.

      Beginnen Sie mit dem Erstellen einer Datei namens polls-svc.yaml mit Ihrem bevorzugten Editor:

      Fügen Sie das folgende Dienst-Manifest ein:

      polls-svc.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: polls
        labels:
          app: polls
      spec:
        type: NodePort
        selector:
          app: polls
        ports:
          - port: 8000
            targetPort: 8000
      

      Hier erstellen wir einen NodePort-Dienst namens polls und geben ihm die Kennzeichnung app: polls. Dann wählen wir Backend-Pods mit der Kennzeichnung app: polls, und zielen auf deren Ports 8000.

      Wenn Sie mit der Bearbeitung der Datei fertig sind, speichern und schließen Sie sie.

      Stellen Sie den Dienst mit kubectl apply bereit:

      • kubectl apply -f polls-svc.yaml

      Output

      service/polls created

      Bestätigen Sie mit kubectl get svc, dass Ihr Dienst erstellt wurde:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE polls NodePort 10.245.197.189 <none> 8000:32654/TCP 59s

      Diese Ausgabe zeigt die clusterinterne IP des Dienstes und den NodePort (32654). Um eine Verbindung mit dem Dienst herzustellen, benötigen wir die externen IP-Adressen für unsere Cluster-Knoten:

      Output

      NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME pool-7no0qd9e0-364fd Ready <none> 27h v1.18.8 10.118.0.5 203.0.113.1 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9 pool-7no0qd9e0-364fi Ready <none> 27h v1.18.8 10.118.0.4 203.0.113.2 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9 pool-7no0qd9e0-364fv Ready <none> 27h v1.18.8 10.118.0.3 203.0.113.3 Debian GNU/Linux 10 (buster) 4.19.0-10-cloud-amd64 docker://18.9.9

      Rufen Sie in Ihrem Webbrowser Ihre Umfrageanwendung mit der externen IP-Adresse eines beliebigen Knotens und dem NodePort auf. Mit der vorstehenden Ausgabe würde die URL der Anwendung lauten: http://203.0.113.1:32654/polls.

      Sie sollten die gleiche Oberfläche der Umfrageanwendung sehen, auf die Sie in Schritt 1 lokal zugegriffen haben:

      Oberfläche der Umfrageanwendung

      Sie können den gleichen Test mit der Route /admin wiederholen: http://203.0.113.1:32654/admin. Sie sollten die gleiche Admin-Oberfläche wie zuvor sehen:

      Authentifizierungsseite für Polls-Administrator

      Zu diesem Zeitpunkt haben Sie zwei Replikate des Django Umfrageanwendungs-Containers mithilfe eines Deployments bereitgestellt. Außerdem haben Sie einen stabilen Netzwerk-Endpunkt für diese beiden Replikate erstellt und ihn mit einem NodePort-Dienst von außen zugänglich gemacht.

      Der letzte Schritt in diesem Tutorial ist die Sicherung des externen Datenverkehrs zu Ihrer Anwendung mit HTTPS. Dazu verwenden wir den in den Voraussetzungen installierten Ingress-Controller ingress-nginx und erstellen ein Ingress-Objekt, um den externen Verkehr in den Kubernetes-Dienst polls zu leiten.

      Schritt 8 — Konfigurieren von HTTPS unter Verwendung von Nginx Ingress und cert-manager

      Mit Ingresses von Kubernetes können Sie den Datenverkehr von außerhalb Ihres Kubernetes-Clusters flexibel an Dienste innerhalb Ihres Clusters leiten. Dies geschieht mit der Verwendung von Ingress-Objekten, die Regeln für das Routing von HTTP- und HTTPS-Verkehr zu Kubernetes-Diensten definieren, und Ingress-Controllern, die die Regeln umsetzen, indem sie den Verkehr durch Lastverteilung an die entsprechenden Backend-Dienste weiterleiten.

      In den Voraussetzungen haben den Ingress-Controller ingress-nginx und das TLS-Zertifizierungsautomatisierungs-Add-on cert-manager installiert. Außerdem haben Sie die Staging- und Produktions-ClusterIssuers für Ihre Domäne unter Verwendung der Zertifizierungsstelle Let’s Encrypt eingerichtet und einen Ingress erstellt, um die Ausstellung von Zertifikaten und die TLS-Verschlüsselung für zwei Dummy-Backend-Dienste zu testen. Bevor Sie mit diesem Schritt fortfahren, sollten Sie den in dem Voraussetzungs-Tutorial erstellten Ingress echo-ingress löschen:

      • kubectl delete ingress echo-ingress

      Wenn Sie möchten, können Sie auch die Dummy-Dienste und -Deployments mit kubectl delete svc und kubectl delete delploy löschen, aber dies ist für die Durchführung des Tutorials nicht unbedingt erforderlich.

      Sie sollten auch einen DNS-A-Datensatz mit your_domain.com erstellt haben, der auf die öffentliche IP-Adresse des Ingress Load Balancers verweist. Wenn Sie einen DigitalOcean Load Balancer verwenden, finden Sie diese IP-Adresse im Abschnitt Load Balancers des Bedienfelds. Wenn Sie DigitalOcean auch für die Verwaltung der DNS-Datensätze Ihrer Domäne verwenden, konsultieren Sie bitte Verwalten von DNS-Datensätzen, um zu erfahren, wie Sie A-Datensätze erstellen.

      Wenn Sie DigitalOcean Kubernetes verwenden, stellen Sie außerdem sicher, dass Sie die in Schritt 5 von Einrichten eines Nginx-Ingress mit Cert-Manager unter DigitalOcean Kubernetes beschriebene Problemumgehung umgesetzt haben.

      Sobald Sie einen A-Datensatz haben, der auf den Ingress Controller Load Balancer verweist, können Sie einen Ingress für your_domain.com und den Dienst polls erstellen.

      Öffnen Sie eine Datei namens polls-ingress.yaml mit Ihrem bevorzugten Editor:

      Fügen Sie das folgende Ingress-Manifest ein:

      [polls-ingress.yaml]
      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: polls-ingress
        annotations:
          kubernetes.io/ingress.class: "nginx"
          cert-manager.io/cluster-issuer: "letsencrypt-staging"
      spec:
        tls:
        - hosts:
          - your_domain.com
          secretName: polls-tls
        rules:
        - host: your_domain.com
          http:
            paths:
            - backend:
                serviceName: polls
                servicePort: 8000
      

      Wir erstellen ein Ingress-Objekt namens polls-ingress und annotieren es, um die Steuerungsebene anzuweisen, den Ingress-Controller ingress-nginx und den ClusterIssuer „staging“ zu verwenden. Außerdem aktivieren wir TLS für your_domain.com und speichern das Zertifikat und den privaten Schlüssel in einem Secret namens polls-tls. Schließlich definieren wir eine Regel, um den Verkehr für den Host your_domain.com an den Dienst polls auf Port 8000 zu leiten.

      Wenn Sie mit der Bearbeitung der Datei fertig sind, speichern und schließen Sie sie.

      Erstellen Sie den Ingress in Ihrem Cluster mit kubectl apply:

      • kubectl apply -f polls-ingress.yaml

      Output

      ingress.networking.k8s.io/polls-ingress created

      Sie können kubectl describe verwenden, um den Status des soeben erstellten Ingress zu verfolgen:

      • kubectl describe ingress polls-ingress

      Output

      Name: polls-ingress Namespace: default Address: workaround.your_domain.com Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) TLS: polls-tls terminates your_domain.com Rules: Host Path Backends ---- ---- -------- your_domain.com polls:8000 (10.244.0.207:8000,10.244.0.53:8000) Annotations: cert-manager.io/cluster-issuer: letsencrypt-staging kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 51s nginx-ingress-controller Ingress default/polls-ingress Normal CreateCertificate 51s cert-manager Successfully created Certificate "polls-tls" Normal UPDATE 25s nginx-ingress-controller Ingress default/polls-ingress

      Sie können auch describe für das Zertifikat polls-tls ausführen, um dessen erfolgreiche Erstellung weiter zu bestätigen:

      • kubectl describe certificate polls-tls

      Output

      . . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Issuing 3m33s cert-manager Issuing certificate as Secret does not exist Normal Generated 3m32s cert-manager Stored new private key in temporary Secret resource "polls-tls-v9lv9" Normal Requested 3m32s cert-manager Created new CertificateRequest resource "polls-tls-drx9c" Normal Issuing 2m58s cert-manager The certificate has been successfully issued

      Dies bestätigt, dass das TLS-Zertifikat erfolgreich ausgestellt wurde und die HTTPS-Verschlüsselung nun für your_domain.com aktiv ist.

      Da wir den Staging-ClusterIssuer verwendet haben, werden die meisten Webbrowser dem gefälschten Let’s Encrypt-Zertifikat nicht vertrauen, das es ausgestellt hat, sodass die Navigation zu your_domain.com Sie zu einer Fehlerseite führt.

      Um eine Testanfrage zu senden, verwenden wir wget von der Befehlszeile aus:

      • wget -O - http://your_domain.com/polls

      Output

      . . . ERROR: cannot verify your_domain.com's certificate, issued by ‘CN=Fake LE Intermediate X1’: Unable to locally verify the issuer's authority. To connect to your_domain.com insecurely, use `--no-check-certificate'.

      Wir verwenden das vorgeschlagene Flag --no-check-certificate, um die Zertifikatsprüfung zu umgehen:

      • wget --no-check-certificate -q -O - http://your_domain.com/polls

      Output

      <link rel="stylesheet" type="text/css" href="https://your_space.nyc3.digitaloceanspaces.com/django-polls/static/polls/style.css"> <p>No polls are available.</p>

      Diese Ausgabe zeigt das HTML für die Benutzeroberflächenseite /polls und bestätigt auch, dass das Stylesheet aus dem Objektspeicher bedient wird.

      Nachdem Sie nun die Zertifikatausstellung mit dem Staging-ClusterIssuer erfolgreich getestet haben, können Sie den Ingress ändern, um den ClusterIssuer, zu verwenden.

      Öffnen Sie polls-ingress.yaml zur erneuten Bearbeitung:

      Ändern Sie die Annotation cluster-issuer:

      [polls-ingress.yaml]
      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress
      metadata:
        name: polls-ingress
        annotations:
          kubernetes.io/ingress.class: "nginx"
          cert-manager.io/cluster-issuer: "letsencrypt-prod"
      spec:
        tls:
        - hosts:
          - your_domain.com
          secretName: polls-tls
        rules:
        - host: your_domain.com
          http:
            paths:
            - backend:
                serviceName: polls
                servicePort: 8000
      

      Wenn Sie fertig sind, speichern und schließen Sie die Datei. Aktualisieren Sie den Ingress mit kubectl apply:

      • kubectl apply -f polls-ingress.yaml

      Output

      ingress.networking.k8s.io/polls-ingress configured

      Um den Status der Zertifikatausstellung zu verfolgen, können Sie kubectl describe certificate polls-tls und kubectl describe ingress polls-ingress verwenden:

      • kubectl describe ingress polls-ingress

      Output

      . . . Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal CREATE 23m nginx-ingress-controller Ingress default/polls-ingress Normal CreateCertificate 23m cert-manager Successfully created Certificate "polls-tls" Normal UPDATE 76s (x2 over 22m) nginx-ingress-controller Ingress default/polls-ingress Normal UpdateCertificate 76s cert-manager Successfully updated Certificate "polls-tls"

      Die obige Ausgabe bestätigt, dass das neue Produktionszertifikat erfolgreich ausgestellt und im Secret polls-tls gespeichert wurde.

      Navigieren Sie in Ihrem Webbrowser zu your_domain.com/polls, um zu bestätigen, dass die HTTPS-Verschlüsselung aktiviert ist und alles wie erwartet funktioniert. Sie sollten die Oberfläche der Umfrageanwendung sehen:

      Oberfläche der Umfrageanwendung

      Überprüfen Sie, ob die HTTPS-Verschlüsselung in Ihrem Webbrowser aktiv ist. Wenn Sie Google Chrome verwenden, bestätigt die Ankunft auf der obigen Seite ohne Fehler, dass alles korrekt funktioniert. Außerdem sollten Sie ein Vorhängeschloss in der URL-Leiste sehen. Durch Klicken auf das Vorhängeschloss können Sie die Details des Let’s Encrypt-Zertifikats einsehen.

      Als letzte Bereinigungsaufgabe können Sie optional den Typ des Dienstes polls von NodePort auf den nut internen Typ ClusterIP umstellen.

      Ändern Sie polls-svc.yaml mit Ihrem Editor:

      Ändern Sie den type von NodePort auf ClusterIP:

      polls-svc.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: polls
        labels:
          app: polls
      spec:
        type: ClusterIP
        selector:
          app: polls
        ports:
          - port: 8000
            targetPort: 8000
      

      Wenn Sie mit der Bearbeitung der Datei fertig sind, speichern und schließen Sie sie.

      Stellen Sie die Änderungen mit kubectl apply bereit:

      • kubectl apply -f polls-svc.yaml --force

      Output

      service/polls configured

      Bestätigen Sie mit kubectl get svc, dass Ihr Dienst geändert wurde:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE polls ClusterIP 10.245.203.186 <none> 8000/TCP 22s

      Diese Ausgabe zeigt, dass der Diensttyp nun ClusterIP ist. Der einzige Weg darauf zuzugreifen, ist über Ihre Domäne und den in diesem Schritt erstellten Ingress.

      Zusammenfassung

      In diesem Tutorial haben Sie eine skalierbare HTTPS-gesicherte Django-Anwendung in einem Kubernetes-Cluster bereitgestellt. Statische Inhalte werden direkt aus dem Objektspeicher bedient, und die Anzahl der laufenden Pods kann über das Feld replicas in dem Deployment-Manifest polls-app schnell herauf- oder herunterskaliert werden.

      Wenn Sie einen DigitalOcean Space verwenden, können Sie auch die Bereitstellung statischer Assets über ein Content Delivery-Netzwerk aktivieren und eine benutzerdefinierte Subdomäne für Ihren Space erstellen. Lesen Sie bitte Aktivieren von CDN aus Einrichten einer skalierbaren Django-Anwendung mit von DigitalOcean verwalteten Datenbanken und Spaces, um mehr zu erfahren.

      Um den Rest der zu lesen, besuchen Sie bitte unsere Seite Von Containern zu Kubernetes mit Django.



      Source link

      Verwenden von Break-, Continue- und Pass-Anweisungen bei der Arbeit mit Schleifen in Python 3


      Einführung

      Die Verwendung von for-Schleifen und while-Schleifen in Python ermöglicht Ihnen die Automatisierung und Wiederholung von Aufgaben in effizienter Weise.

      Jedoch kann ein externer Faktor die Ausführung Ihres Programms manchmal beeinflussen. Wenn dies der Fall ist, möchten Sie vielleicht, dass Ihr Programm eine Schleife vollständig verlässt, vor dem Fortfahren einen Teil einer Schleife überspringt oder diesen externen Faktor ignoriert. Sie können diese Aktionen mit den Anweisungen break, continue und pass durchführen.

      Break-Anweisung

      In Python bietet Ihnen die break-Anweisung die Möglichkeit, eine Schleife zu verlassen, wenn eine externe Bedingung ausgelöst wird. Sie setzen die break-Anweisung innerhalb des Codeblocks unter Ihrer Schleifenanweisung ein, normalerweise nach einer bedingten if-Anweisung.

      Sehen wir uns ein Beispiel an, das die Anweisung break in einer Schleife for verwendet:

      number = 0
      
      for number in range(10):
          if number == 5:
              break    # break here
      
          print('Number is ' + str(number))
      
      print('Out of loop')
      
      

      In diesem kleinen Programm wird Variable number bei 0 initialisiert. Dann erstellt eine Anweisung for die Schleife so lange, bis die Variable number kleiner als 10 ist.

      Innerhalb der Schleife for gibt es eine Anweisung if, die die Bedingung stellt, dass, wenn die Variable number gleich der Ganzzahl 5 ist, dann die Schleife abbricht.

      Innerhalb der Schleife gibt es auch eine Anweisung print(), die bei jeder Iteration der Schleife for ausgeführt wird, bis die Schleife abbricht, da sie nach der Anweisung break steht.

      Um zu wissen, wann wir aus der Schleife heraus sind, haben wir eine abschließende Anweisung print() außerhalb der Schleife for eingefügt.

      Wenn wir diesen Code ausführen, wird unsere Ausgabe wie folgt aussehen:

      Output

      Number is 0 Number is 1 Number is 2 Number is 3 Number is 4 Out of loop

      Dies zeigt, dass, sobald die Ganzzahl number als gleichwertig zu 5 ausgewertet wird, die Schleife abbricht, da das Programm mit der Anweisung break dazu aufgefordert wird.

      Die Anweisung break veranlasst ein Programm, aus einer Schleife auszubrechen.

      Continue-Anweisung

      Die Anweisung continue gibt Ihnen die Möglichkeit, den Teil einer Schleife zu überspringen, in der eine externe Bedingung ausgelöst wird, aber den Rest der Schleife zu Ende zu führen. Das heißt, die aktuelle Iteration der Schleife wird unterbrochen, aber das Programm kehrt an den Anfang der Schleife zurück.

      Die Anweisung continue befindet sich innerhalb des Codeblocks unter der Schleifenanweisung, normalerweise nach einer bedingten if-Anweisung.

      Unter Verwendung des gleichen Schleifenprogramms for wie im vorstehenden Abschnitt Break-Anweisung, verwenden wir eine Anweisung continue anstelle einer Anweisung break:

      number = 0
      
      for number in range(10):
          if number == 5:
              continue    # continue here
      
          print('Number is ' + str(number))
      
      print('Out of loop')
      
      

      Der Unterschied bei der Verwendung der Anweisung continue anstelle einer Anweisung break besteht darin, dass unser Code trotz der Unterbrechung fortgesetzt wird, wenn die Variable number als äquivalent zu 5 ausgewertet wird. Schauen wir uns unsere Ausgabe an:

      Output

      Number is 0 Number is 1 Number is 2 Number is 3 Number is 4 Number is 6 Number is 7 Number is 8 Number is 9 Out of loop

      Hier tritt Nuber is 5 nie in der Ausgabe auf, aber die Schleife fährt nach diesem Punkt fort, um Zeilen für die Zahlen 6–10 auszugeben, bevor sie die Schleife verlässt.

      Sie können die Anweisung continue verwenden, um tief verschachtelten bedingten Code zu vermeiden oder eine Schleife zu optimieren, indem Sie häufig auftretende Fälle, die Sie verwerfen möchten, eliminieren.

      Die Anweisung continue veranlasst ein Programm, bestimmte Faktoren zu überspringen, die innerhalb einer Schleife auftreten, dann aber den Rest der Schleife zu durchlaufen.

      Pass-Anweisung

      Wenn eine externe Bedingung ausgelöst wird, können Sie mit der Anweisung pass die Bedingung behandeln, ohne dass die Schleife in irgendeiner Weise beeinflusst wird; der gesamte Code wird weiterhin gelesen, bis eine break– oder eine andere Anweisung auftritt.

      Wie bei den anderen Anweisungen, befindet sich die Anweisung pass innerhalb des Codeblocks unter der Schleifenanweisung, normalerweise nach einer bedingten if-Anweisung.

      Unter Verwendung des gleichen Codeblocks wie vorstehend, ersetzen wir die Anweisung break oder continue durch eine Anweisung pass:

      number = 0
      
      for number in range(10):
          if number == 5:
              pass    # pass here
      
          print('Number is ' + str(number))
      
      print('Out of loop')
      
      

      Die Anweisung pass, die nach der bedingten if-Anweisung steht, teilt dem Programm mit, dass es die Schleife weiter ausführen und die Tatsache ignorieren soll, dass die Variable number während einer ihrer Iterationen als gleichwertig zu 5 ausgewertet wird.

      Wir führen das Programm aus und betrachten die Ausgabe:

      Output

      Number is 0 Number is 1 Number is 2 Number is 3 Number is 4 Number is 5 Number is 6 Number is 7 Number is 8 Number is 9 Out of loop

      Durch die Verwendung der Anweisung pass in diesem Programm stellen wir fest, dass das Programm genau so abläuft, wie es ablaufen würde, wenn es keine bedingte Anweisung in dem Programm gäbe. Die Anweisung pass weist das Programm an, diese Bedingung zu ignorieren und das Programm wie gewohnt weiter auszuführen.

      Die Anweisung pass kann minimale Klassen erstellen oder als Platzhalter dienen, wenn Sie an einem neuen Code arbeiten und auf einer algorithmischen Ebene denken, bevor Sie die Details ausarbeiten.

      Zusammenfassung

      Mit den Anweisungen break, continue und pass in Python können Sie for-Schleifen und while-Schleifen effektiver in Ihrem Code verwenden.

      Um mehr mit den Anweisungen break und pass zu arbeiten, können Sie unserem Projekttutorial „Erstellen eines Twitterbots mit Python 3 und der Tweepy-Bibliothek“ folgen.



      Source link

      Verwenden von Journalctl zum Anzeigen und Manipulieren von Systemd-Protokollen


      Einführung

      Einige der überzeugendsten Vorteile von systemd sind diejenigen, die mit der Prozess- und Systemprotokollierung verbunden sind. Bei der Verwendung anderer Tools werden Protokolle normalerweise im gesamten System verteilt, von verschiedenen Daemons und Prozessen bearbeitet und können ziemlich schwer zu interpretieren, wenn sie sich über mehrere Anwendungen erstrecken. Systemd versucht, diese Probleme zu lösen, indem es eine zentralisierte Verwaltungslösung zur Protokollierung aller Kernel- und Userland-Prozesse bereitstellt. Das System, das diese Protokolle sammelt und verwaltet, wird als Journal bezeichnet.

      Das Journal wird mit dem Daemon journald implementiert, der alle vom Kernel, initrd, services etc. erzeugten Nachrichten verarbeitet. In diesem Leitfaden besprechen wir die Verwendung des Dienstprogramms journalctl, mit dem Sie auf die in dem Journal gespeicherten Daten zugreifen und diese manipulieren können.

      Allgemeiner Gedanke

      Eine der Triebfedern hinter dem Journal systemd ist die Zentralisierung der Verwaltung von Protokollen, unabhängig davon, woher die Nachrichten stammen. Da ein Großteil des Boot-Prozesses und der Verwaltung von Diensten durch den Prozess systemd abgewickelt wird, ist es sinnvoll, die Art und Weise, wie Protokolle gesammelt und darauf zugegriffen wird, zu standardisieren. Der Daemon journald sammelt Daten aus allen verfügbaren Quellen und speichert sie in einem Binärformat für einfache und dynamische Manipulation.

      Dies bringt eine Reihe von bedeutenden Vorteilen mit sich. Durch die Interaktion mit den Daten über ein einziges Dienstprogramm sind Administratoren in der Lage, Protokolldaten dynamisch nach ihren Bedürfnissen anzuzeigen. Dies kann so einfach sein, wie das Anzeigen der Boot-Daten von vor drei Boot-Vorgängen oder das Kombinieren der Protokolleinträge von zwei verwandten Diensten nacheinander, um ein Kommunikationsproblem zu beheben.

      Das Speichern der Protokolldaten in einem Binärformat bedeutet auch, dass die Daten in beliebigen Ausgabeformaten angezeigt werden können, je nachdem, was Sie gerade benötigen. Für die tägliche Protokollverwaltung sind Sie eventuell daran gewöhnt, die Protokolle im Standard-Format syslog anzuzeigen, aber wenn Sie sich später entscheiden, Dienstunterbrechungen grafisch darzustellen, können Sie jeden Eintrag als JSON-Objekt ausgeben, um ihn für Ihren grafischen Dienst konsumierbar zu machen. Da die Daten nicht im Klartext auf die Festplatte geschrieben werden, ist keine Konvertierung erforderlich, wenn Sie ein anderes On-Demand-Format benötigen.

      Das Journal systemd kann entweder mit einer vorhandenen syslog-Implementierung verwendet werden oder es kann die Funktionalität syslog ersetzen, je nach Ihren Bedürfnissen. Während das Journal systemd die meisten Protokollierungsanforderungen von Administratoren abdeckt, kann es auch bestehende Protokollierungsmechanismen ergänzen. Sie haben vielleicht einen zentralisierten syslog-Server, den Sie verwenden, um Daten von mehreren Servern zu kompilieren, aber Sie möchten die Protokolle auch von mehreren Diensten auf einem einzigen System mit dem Journal systemd zusammenführen. Sie können beides tun, indem Sie diese Technologien kombinieren.

      Einstellen der Systemzeit

      Einer der Vorteile der Verwendung eines binären Journals für die Protokollierung ist die Fähigkeit, Protokolldatensätze in UTC oder lokaler Zeit anzuzeigen. Standardmäßig zeigt systemd Ergebnisse in der lokalen Zeit an.

      Aus diesem Grund stellen wir, bevor wir mit dem Journal beginnen, sicher, dass die Zeitzone korrekt eingestellt ist. Die Suite systemd verfügt über ein Tool namens timedatectl, das dabei helfen kann.

      Sehen Sie zuerst nach, welche Zeitzonen mit der Option list-timezones verfügbar sind:

      timedatectl list-timezones
      

      Dadurch werden die auf Ihrem System verfügbaren Zeitzonen aufgelistet. Wenn Sie diejenige gefunden haben, die dem Standort Ihres Servers entspricht, können Sie sie mit der Option set-timezone einstellen:

      sudo timedatectl set-timezone zone
      

      Um sicherzustellen, dass Ihr Rechner jetzt die richtige Zeit verwendet, verwenden Sie den Befehl timedatectl allein oder mit der Option status. Die Anzeige wird die gleiche sein:

      timedatectl status
      
            Local time: Thu 2015-02-05 14:08:06 EST
        Universal time: Thu 2015-02-05 19:08:06 UTC
              RTC time: Thu 2015-02-05 19:08:06
             Time zone: America/New_York (EST, -0500)
           NTP enabled: no
      NTP synchronized: no
       RTC in local TZ: no
            DST active: n/a
      

      In der ersten Zeile sollte die korrekte Zeit angezeigt werden.

      Grundlegendes Anzeigen von Protokollen

      Um die Protokolle zu sehen, die der Daemon journald gesammelt hat, verwenden Sie den Befehl journalctl.

      Bei alleiniger Verwendung wird jeder im System vorhandene Journaleintrag innerhalb eines Pager (normalerweise less) angezeigt, damit Sie durchsuchen können. Die ältesten Einträge werden oben angezeigt:

      journalctl
      
      -- Logs begin at Tue 2015-02-03 21:48:52 UTC, end at Tue 2015-02-03 22:29:38 UTC. --
      Feb 03 21:48:52 localhost.localdomain systemd-journal[243]: Runtime journal is using 6.2M (max allowed 49.
      Feb 03 21:48:52 localhost.localdomain systemd-journal[243]: Runtime journal is using 6.2M (max allowed 49.
      Feb 03 21:48:52 localhost.localdomain systemd-journald[139]: Received SIGTERM from PID 1 (systemd).
      Feb 03 21:48:52 localhost.localdomain kernel: audit: type=1404 audit(1423000132.274:2): enforcing=1 old_en
      Feb 03 21:48:52 localhost.localdomain kernel: SELinux: 2048 avtab hash slots, 104131 rules.
      Feb 03 21:48:52 localhost.localdomain kernel: SELinux: 2048 avtab hash slots, 104131 rules.
      Feb 03 21:48:52 localhost.localdomain kernel: input: ImExPS/2 Generic Explorer Mouse as /devices/platform/
      Feb 03 21:48:52 localhost.localdomain kernel: SELinux:  8 users, 102 roles, 4976 types, 294 bools, 1 sens,
      Feb 03 21:48:52 localhost.localdomain kernel: SELinux:  83 classes, 104131 rules
      
      . . .
      

      Sie werden wahrscheinlich seitenweise Daten durchblättern müssen, die zehn- oder hunderttausende Zeilen lang sein können, wenn sich systemd schon lange auf Ihrem System befindet. Dies demonstriert, wie viele Daten in der Journal-Datenbank vorhanden sind.

      Das Format wird denjenigen vertraut sein, die an die Standard-Protokollierung syslog gewöhnt sind. Allerdings werden hier tatsächlich Daten aus mehr Quellen gesammelt als traditionelle syslog-Implementierungen in der Lage sind. Es beinhaltet Protokolle des frühen Boot-Prozesses, des Kernel, der initrd und der Anwendungsstandardfehler und -ausgänge. Diese sind alle im Journal verfügbar.

      Vielleicht fällt Ihnen auf, dass alle angezeigten Zeitstempel in lokaler Zeit sind. Dies ist für jeden Protokolleintrag verfügbar, da die lokale Zeit auf unserem System korrekt eingestellt ist. Alle Protokolle werden mit dieser neuen Information angezeigt.

      Wenn Sie die Zeitstempel in UTC anzeigen möchten, können Sie das Flag --utc verwenden:

      journalctl --utc
      

      Journal-Filterung nach Zeit

      Obwohl der Zugriff auf eine so große Datensammlung durchaus nützlich ist, kann es schwierig oder unmöglich sein, eine so große Menge mental zu untersuchen und zu verarbeiten. Aus diesem Grund ist eine der wichtigsten Funktionen von journalctl seine Filteroptionen.

      Anzeigen von Protokollen aus dem aktuellen Boot

      Die grundlegendste dieser Optionen, die Sie möglicherweise täglich verwenden, ist das Flag -b. Damit werden Ihnen alle Journaleinträge angezeigt, die seit dem neuesten Neustart gesammelt wurden.

      journalctl -b
      

      Dies hilft Ihnen, Informationen zu identifizieren und zu verwalten, die für Ihre aktuelle Umgebung relevant sind.

      In Fällen, in denen Sie diese Funktion nicht verwenden und mehr als einen Tag von Bootvorgängen anzeigen, werden Sie sehen, dass journalctl eine Zeile eingefügt hat, die so aussieht, wann immer das System heruntergefahren wurde:

      . . .
      
      -- Reboot --
      
      . . .
      

      Dies kann verwendet werden, um Ihnen dabei zu helfen, die Informationen logisch in Boot-Sitzungen aufzuteilen.

      Vergangene Bootvorgänge

      Während Sie in der Regel die Informationen aus dem aktuellen Bootvorgang anzeigen möchten, gibt es sicherlich Zeiten, in denen auch vergangene Bootvorgänge hilfreich sind. Das Journal kann Informationen von vielen vorherigen Bootvorgängen speichern, sodass journalctl eingestellt werden kann, um Informationen einfacher anzuzeigen.

      Bei einigen Distributionen ist das Speichern von Informationen zu früheren Bootvorgängen standardmäßig aktiviert, bei anderen ist diese Funktion deaktiviert. Um persistente Boot-Informationen zu aktivieren, können Sie entweder das Verzeichnis zum Speichern des Journals erstellen, indem Sie Folgendes eingeben:

      • sudo mkdir -p /var/log/journal

      Oder Sie können die Journal-Konfigurationsdatei bearbeiten:

      • sudo nano /etc/systemd/journald.conf

      Setzen Sie unter dem Abschnitt [Journal] die Option Storage= auf „persistent“, um die persistente Protokollierung zu aktivieren:

      /etc/systemd/journald.conf

      . . .
      [Journal]
      Storage=persistent
      

      Wenn das Speichern von vorherigen Bootvorgängen auf Ihrem Server aktiviert ist, stellt journalctl einige Befehle bereit, um Ihnen die Arbeit mit Bootvorgängen als Einheit der Division zu erleichtern. Um die Bootvorgänge zu sehen, von denen journald weiß, verwenden Sie die Option --list-boots mit journalctl:

      journalctl --list-boots
      
      -2 caf0524a1d394ce0bdbcff75b94444fe Tue 2015-02-03 21:48:52 UTC—Tue 2015-02-03 22:17:00 UTC
      -1 13883d180dc0420db0abcb5fa26d6198 Tue 2015-02-03 22:17:03 UTC—Tue 2015-02-03 22:19:08 UTC
       0 bed718b17a73415fade0e4e7f4bea609 Tue 2015-02-03 22:19:12 UTC—Tue 2015-02-03 23:01:01 UTC
      

      Dies zeigt eine Zeile für jeden Bootvorgang an. Die erste Spalte ist der Offset für den Bootvorgang, der verwendet werden kann, um den Bootvorgang mit journalctl einfach zu referenzieren. Wenn Sie eine absolute Referenz benötigen, steht die Boot-ID in der zweiten Spalte. Die Zeit, auf die sich die Boot-Sitzung bezieht, erkennen Sie an den beiden Zeitangaben, die am Ende aufgeführt sind.

      Um Informationen von diesen Bootvorgängen anzuzeigen, können Sie entweder Informationen aus der ersten oder zweiten Spalte verwenden.

      Um beispielsweise das Journal von dem vorherigen Boot zu sehen, verwenden Sie den relativen Zeiger -1 mit dem Flag -b:

      journalctl -b -1
      

      Zum Abrufen von Daten aus einem Boot können Sie auch die Boot-ID verwenden:

      journalctl -b caf0524a1d394ce0bdbcff75b94444fe
      

      Zeitfenster

      Während es unglaublich nützlich ist, Protokolleinträge nach Bootvorgang zu sehen, möchten Sie vielleicht oft Zeitfenster abfragen, die nicht gut mit Systemstarts übereinstimmen. Dies kann besonders bei lang laufenden Servern mit erheblicher Betriebszeit der Fall sein.

      Sie können nach beliebigen Zeitgrenzen filtern, indem Sie die Optionen --since und --until verwenden, die die angezeigten Einträge auf diejenigen nach bzw. vor der angegebenen Zeit einschränken.

      Die Zeitwerte können in einer Vielzahl von Formaten vorliegen. Für absolute Zeitwerte sollten Sie das folgende Format verwenden:

      YYYY-MM-DD HH:MM:SS
      

      Beispielsweise können wir alle Einträge seit dem 10. Januar 2015 um 17:15 Uhr sehen, indem wir eingeben:

      journalctl --since "2015-01-10 17:15:00"
      

      Wenn Komponenten des obigen Formats weggelassen werden, werden einige Standardwerte angewendet. Wenn beispielsweise das Datum weggelassen wird, wird das aktuelle Datum angenommen. Wenn die Zeitkomponente fehlt, wird „00:00:00“ (Mitternacht) ersetzt. Das Sekundenfeld kann auch weggelassen werden, sodass standardmäßig „00“ verwendet wir:

      journalctl --since "2015-01-10" --until "2015-01-11 03:00"
      

      Das Journal versteht auch einige relative Werte und benannte Abkürzungen. Beispielsweise können Sie die Wörter „gestern“, „heute“, „morgen“ oder „jetzt“ verwenden. Relative Zeiten geben Sie an, indem Sie einem nummerierten Wert ein „-“ oder „+“ voranstellen oder Wörter wie „vor“ in einem Satzbau verwenden.

      Um die Daten von gestern zu erhalten, könnten Sie eingeben:

      journalctl --since yesterday
      

      Wenn Sie Berichte über eine Dienstunterbrechung erhalten haben, die um 9:00 Uhr begann und bis vor einer Stunde andauerte, könnten Sie eingeben:

      journalctl --since 09:00 --until "1 hour ago"
      

      Wie Sie sehen können, ist es relativ einfach, flexible Zeitfenster zu definieren, um die Einträge zu filtern, die Sie sehen möchten.

      Filtern nach Nachrichteninteresse

      Wir haben vorstehend einige Möglichkeiten kennengelernt, wie Sie die Journaldaten anhand von Zeiteinschränkungen filtern können. In diesem Abschnitt werden wir besprechen, wie Sie basierend auf dem Dienst oder der Komponente filtern können, an der Sie interessiert sind. Das Journal systemd bietet eine Vielzahl von Möglichkeiten, dies zu tun.

      Nach Einheit

      Die vielleicht nützlichste Art der Filterung ist nach der Einheit, an der Sie interessiert sind. Wir können die Option -u verwenden, um auf diese Weise zu filtern.

      Um beispielsweise alle Protokolle einer Nginx-Einheit auf unserem System zu sehen, können wir eingeben:

      journalctl -u nginx.service
      

      Normalerweise würden Sie wahrscheinlich auch nach der Zeit filtern wollen, um die Zeilen anzuzeigen, an denen Sie interessiert sind. Um beispielsweise zu überprüfen, wie der Dienst heute ausgeführt wird, können Sie eingeben:

      journalctl -u nginx.service --since today
      

      Diese Art der Fokussierung wird extrem hilfreich, wenn Sie die Fähigkeit des Journals nutzen, Datensätze aus verschiedenen Einheiten zusammenzuführen. Wenn Ihr Nginx-Prozess beispielsweise mit einer PHP-FPM-Einheit verbunden ist, um dynamischen Inhalt zu verarbeiten, können Sie die Einträge von beiden in chronologischer Reihenfolge zusammenführen, indem Sie beide Einheiten angeben:

      journalctl -u nginx.service -u php-fpm.service --since today
      

      Dies kann es wesentlich einfacher machen, die Interaktionen zwischen verschiedenen zu erkennen und System zu debuggen, anstatt einzelne Prozesse.

      Nach Prozess, Benutzer oder Gruppen-ID

      Einige Dienste spawnen eine Vielzahl von untergeordneten Prozesse, um die Arbeit zu erledigen. Wenn Sie die genaue PID des Prozesses, an dem Sie interessiert sind, ausgekundschaftet haben, können Sie auch nach dieser filtern.

      Dazu können wir durch Angabe des Feldes _PID filtern. Wenn die PID, an der wir interessiert sind, beispielsweise 8088 ist, könnten wir eingeben:

      journalctl _PID=8088
      

      Zu anderen Zeiten möchten Sie möglicherweise alle Einträge anzeigen, die von einem bestimmten Benutzer oder einer Gruppe protokolliert wurden. Dies kann mit den Filtern _UID oder _GID geschehen. Wenn Ihr Webserver beispielsweise unter dem Benutzer www-data läuft, können Sie die Benutzer-ID finden, indem Sie eingeben:

      id -u www-data
      
      33
      

      Anschließend können Sie die zurückgegebene ID verwenden, um die Journalergebnisse zu filtern:

      journalctl _UID=33 --since today
      

      Das Journal systemd hat viele Felder, die für die Filterung verwendet werden können. Einige davon werden von dem zu protokollierenden Prozess übergeben und einige werden von journald anhand von Informationen angewendet, die es zum Zeitpunkt der Protokollierung aus dem System sammelt.

      Der führende Unterstrich gibt an, dass das Feld _PID von dem letzteren Typ ist. Das Journal zeichnet automatisch die PID des protokollierenden Prozesses auf und indexiert sie für spätere Filterungen. Sie können sich über alle verfügbaren Journalfelder informieren, indem Sie eingeben:

      man systemd.journal-fields
      

      Wir werden einige davon in diesem Leitfaden besprechen. Für den Moment werden wir jedoch eine weitere nützliche Option bespreche, die mit der Filterung nach diesen Feldern zu tun hat. Die Option -F kann verwendet werden, um alle verfügbaren Werte für ein bestimmtes Journalfeld anzuzeigen.

      Um beispielsweise zu sehen, für welche Gruppen-IDs das Journal systemd Einträge aufweist, können Sie eingeben:

      journalctl -F _GID
      
      32
      99
      102
      133
      81
      84
      100
      0
      124
      87
      

      Dies zeigt Ihnen alle Werte, die das Journal für das Feld Gruppen-ID gespeichert hat. Dies kann Ihnen beim Erstellen Ihrer Filter helfen.

      Nach Komponentenpfad

      Wir können auch filtern, indem wir eine Pfadposition bereitstellen.

      Wenn der Pfad zu einer ausführbaren Datei führt, zeigt journalctl alle Einträge an, die die betreffende ausführbare Datei betreffen. Um beispielsweise die Einträge zu finden, die die ausführbare Datei bash betreffen, können Sie eingeben:

      journalctl /usr/bin/bash
      

      Wenn eine Einheit für die ausführbare Datei verfügbar ist, ist diese Methode sauberer und bietet bessere Informationen (Einträge aus zugehörigen untergeordneten Prozessen usw.). Manchmal ist dies jedoch nicht möglich.

      Anzeigen von Kernel-Meldungen

      Kernel-Meldungen, die normalerweise in der Ausgabe dmesg zu finden sind, können ebenfalls aus dem Journal abgerufen werden.

      Um nur diese Meldungen anzuzeigen, können wir die Flags -k oder --dmesg zu unserem Befehl hinzufügen:

      journalctl -k
      

      Standardmäßig werden damit die Kernel-Meldungen des aktuellen Bootvorgangs angezeigt. Sie können einen alternativen Bootvorgang angeben, indem Sie die zuvor besprochenen Boot-Auswahl-Flags verwenden. Um beispielsweise die Meldungen von vor fünf Bootvorgängen zu erhalten, könnten Sie eingeben:

      journalctl -k -b -5
      

      Nach Priorität

      Ein Filter, an dem Systemadministratoren oft interessiert sind, ist die Meldungspriorität. Während es oft nützlich ist, Informationen auf einem sehr ausführlichen Niveau zu protokollieren, können Protokolle mit niedriger Priorität beim tatsächlichen Verarbeiten der verfügbaren Informationen ablenken und verwirrend sein.

      Sie können journalctl verwenden, um nur Meldungen einer bestimmten Priorität oder höher anzuzeigen, indem Sie die Option -p verwenden. Dadurch können Sie Meldungen mit niedrigerer Priorität herausfiltern.

      Um beispielsweise nur Einträge anzuzeigen, die auf der Fehlerebene oder höher protokolliert wurden, können Sie eingeben:

      journalctl -p err -b
      

      Dies zeigt Ihnen alle Meldungen an, die als Fehler, kritisch, Alarm oder Notfall gekennzeichnet sind. Das Journal implementiert die Standard-syslog-Meldungsebenen. Sie können entweder den Namen der Priorität oder den entsprechenden numerischen Wert verwenden. In der Reihenfolge von höchster bis niedrigster Priorität sind dies:

      • 0: emerg (Notfall)
      • 1: alert (Alarm)
      • 2: crit (kritisch)
      • 3: err (Fehler)
      • 4: warning (Warnung)
      • 5: notice (Hinweis)
      • 6: info (Information)
      • 7: debug (Fehlersuche)

      Die vorstehenden Zahlen oder Namen können austauschbar mit der Option -p verwendet werden. Wenn Sie die Priorität auswählen, werden Meldungen angezeigt, die auf der angegebenen Ebene markiert sind, und solche, die darüber liegen.

      Ändern der Journalanzeige

      Vorstehend haben wir die Auswahl von Einträgen durch Filterung demonstriert. Es gibt jedoch noch andere Möglichkeiten, die Ausgabe zu ändern. Wir können die Anzeige journalctl an verschiedene Bedürfnisse anpassen.

      Kürzen oder Erweitern der Ausgabe

      Wir können anpassen, wie journalctl Daten anzeigt, indem wir ihn anweisen, die Ausgabe zu verkürzen oder zu erweitern.

      Standardmäßig zeigt journalctl den gesamten Eintrag in dem Pager an und lässt die Einträge rechts am Bildschirm auslaufen. Auf diese Informationen können Sie durch Drücken der rechten Pfeiltaste zugreifen.

      Wenn Sie die Ausgabe lieber gekürzt haben möchten, wobei an den Stellen, an denen Informationen entfernt wurden, eine Ellipse eingefügt wird, können Sie die Option --no-full verwenden:

      journalctl --no-full
      
      . . .
      
      Feb 04 20:54:13 journalme sshd[937]: Failed password for root from 83.234.207.60...h2
      Feb 04 20:54:13 journalme sshd[937]: Connection closed by 83.234.207.60 [preauth]
      Feb 04 20:54:13 journalme sshd[937]: PAM 2 more authentication failures; logname...ot
      

      Sie können damit auch in die entgegengesetzte Richtung gehen und journalctl anweisen, alle Informationen anzuzeigen, unabhängig davon, ob sie nicht druckbare Zeichen enthält. Wir können dies mit dem Flag -a tun:

      journalctl -a
      

      Ausgabe auf Standardausgabe

      Standardmäßig zeigt journalctl die Ausgabe in einem Pager an, um den Konsum zu erleichtern. Wenn Sie jedoch vorhaben, die Daten mit Textmanipulationswerkzeugen zu verarbeiten, möchten Sie wahrscheinlich in der Lage sein, auf die Standardausgabe auszugeben.

      Sie können dies mit der Option --no-pager tun:

      journalctl --no-pager
      

      Dies kann direkt in ein Verarbeitungsprogramm geleitet oder in eine Datei auf der Festplatte umgeleitet werden, je nach Ihren Bedürfnissen.

      Ausgabeformate

      Wenn Sie, wie oben erwähnt, Journaleinträge verarbeiten, wird es Ihnen die Analyse der Daten wahrscheinlich leichter fallen, wenn sie in einem besser konsumierbaren Format vorliegen. Glücklicherweise kann das Journal in einer Vielzahl von Formaten angezeigt werden, wenn es erforderlich ist. Dazu können Sie die Option -o mit einem Formatbezeichner verwenden.

      Sie können die Journaleinträge beispielsweise in JSON ausgeben, indem Sie eingeben:

      journalctl -b -u nginx -o json
      
      { "__CURSOR" : "s=13a21661cf4948289c63075db6c25c00;i=116f1;b=81b58db8fd9046ab9f847ddb82a2fa2d;m=19f0daa;t=50e33c33587ae;x=e307daadb4858635", "__REALTIME_TIMESTAMP" : "1422990364739502", "__MONOTONIC_TIMESTAMP" : "27200938", "_BOOT_ID" : "81b58db8fd9046ab9f847ddb82a2fa2d", "PRIORITY" : "6", "_UID" : "0", "_GID" : "0", "_CAP_EFFECTIVE" : "3fffffffff", "_MACHINE_ID" : "752737531a9d1a9c1e3cb52a4ab967ee", "_HOSTNAME" : "desktop", "SYSLOG_FACILITY" : "3", "CODE_FILE" : "src/core/unit.c", "CODE_LINE" : "1402", "CODE_FUNCTION" : "unit_status_log_starting_stopping_reloading", "SYSLOG_IDENTIFIER" : "systemd", "MESSAGE_ID" : "7d4958e842da4a758f6c1cdc7b36dcc5", "_TRANSPORT" : "journal", "_PID" : "1", "_COMM" : "systemd", "_EXE" : "/usr/lib/systemd/systemd", "_CMDLINE" : "/usr/lib/systemd/systemd", "_SYSTEMD_CGROUP" : "/", "UNIT" : "nginx.service", "MESSAGE" : "Starting A high performance web server and a reverse proxy server...", "_SOURCE_REALTIME_TIMESTAMP" : "1422990364737973" }
      
      . . .
      

      Dies ist nützlich für das Parsen mit Dienstprogrammen. Sie könnten das Format json-pretty verwenden, um die Datenstruktur besser in den Griff zu bekommen, bevor Sie sie an den JSON-Verbraucher übergeben:

      journalctl -b -u nginx -o json-pretty
      
      {
          "__CURSOR" : "s=13a21661cf4948289c63075db6c25c00;i=116f1;b=81b58db8fd9046ab9f847ddb82a2fa2d;m=19f0daa;t=50e33c33587ae;x=e307daadb4858635",
          "__REALTIME_TIMESTAMP" : "1422990364739502",
          "__MONOTONIC_TIMESTAMP" : "27200938",
          "_BOOT_ID" : "81b58db8fd9046ab9f847ddb82a2fa2d",
          "PRIORITY" : "6",
          "_UID" : "0",
          "_GID" : "0",
          "_CAP_EFFECTIVE" : "3fffffffff",
          "_MACHINE_ID" : "752737531a9d1a9c1e3cb52a4ab967ee",
          "_HOSTNAME" : "desktop",
          "SYSLOG_FACILITY" : "3",
          "CODE_FILE" : "src/core/unit.c",
          "CODE_LINE" : "1402",
          "CODE_FUNCTION" : "unit_status_log_starting_stopping_reloading",
          "SYSLOG_IDENTIFIER" : "systemd",
          "MESSAGE_ID" : "7d4958e842da4a758f6c1cdc7b36dcc5",
          "_TRANSPORT" : "journal",
          "_PID" : "1",
          "_COMM" : "systemd",
          "_EXE" : "/usr/lib/systemd/systemd",
          "_CMDLINE" : "/usr/lib/systemd/systemd",
          "_SYSTEMD_CGROUP" : "/",
          "UNIT" : "nginx.service",
          "MESSAGE" : "Starting A high performance web server and a reverse proxy server...",
          "_SOURCE_REALTIME_TIMESTAMP" : "1422990364737973"
      }
      
      . . .
      

      Die folgenden Formate können für die Anzeige verwendet werden:

      • cat: Zeigt nur das Meldungsfeld selbst an.
      • export: Ein Binärformat, das sich zum Übertragen oder Sichern eignet.
      • json: Standard-JSON mit einem Eintrag pro Zeile.
      • json-pretty: JSON, das für eine bessere menschliche Lesbarkeit formatiert ist.
      • json-sse: JSON-formatierte Ausgabe, die eingehüllt ist, um das Hinzufügen von vom Server gesendeten Ereignissen zu ermöglichen.
      • short: Die Standardausgabe im syslog-Stil.
      • short-iso: Das Standardformat, das zum Anzeigen von ISO-8601 Wallclock-Zeitstempeln erweitert wurde.
      • short-monotonic: Das Standardformat mit monotonen Zeitstempeln.
      • short-precise: Das Standardformat mit Mikrosekundengenauigkeit.
      • verbose: Zeigt jedes für den Eintrag verfügbare Journalfeld an, einschließlich derjenigen, die normalerweise intern verborgen sind.

      Mit diesen Optionen können Sie die Journaleinträge in dem Format anzeigen, das Ihren aktuellen Bedürfnissen am besten entspricht.

      Aktive Prozessüberwachung

      Der Befehl journalctl imitiert, wie viele Administratoren tail zur Überwachung der aktiven oder jüngsten Aktivität verwenden. Diese Funktionalität ist in journalctl eingebaut, sodass Sie auf diese Funktionen zugreifen können, ohne eine Pipe zu einem anderen Tool verwenden zu müssen.

      Anzeigen aktueller Protokolle

      Um eine bestimmte Anzahl von Datensätzen anzuzeigen, können Sie die Option -n verwenden, die genau wie tail -n funktioniert.

      Sie zeigt standardmäßig die letzten 10 Einträge an:

      journalctl -n
      

      Sie können die Anzahl der Einträge, die Sie sehen möchten, mit einer Zahl nach dem -n angeben:

      journalctl -n 20
      

      Verfolgen von Protokollen

      Um die Protokolle aktiv zu verfolgen, während sie geschrieben werden, können Sie das Flag -f verwenden. Auch dies funktioniert so, wie Sie es vielleicht erwarten, wenn Sie Erfahrung mit der Verwendung von tail -f haben:

      journalctl -f
      

      Journalwartung

      Vielleicht fragen Sie sich, was es kostet, all die Daten zu speichern, die wir bisher gesehen haben. Außerdem sind Sie vielleicht daran interessiert, einige ältere Protokolle aufzuräumen und Speicherplatz freizugeben.

      Ermitteln der aktuellen Festplattenbelegung

      Sie können herausfiden, wie viel Platz das Journal derzeit auf der Festplatte belegt, indem Sie das Flag --disk-usage verwenden:

      journalctl --disk-usage
      
      Journals take up 8.0M on disk.
      

      Löschen alter Protokolle

      Wenn Sie Ihr Journal verkleinern möchten, können Sie dies auf zwei verschiedene Arten tun (verfügbar mit systemd Version 218 und höher).

      Wenn Sie die Option --vacuum-size verwenden, können Sie Ihr Journal durch Angabe einer Größe verkleinern. Dadurch werden alte Einträge entfernt, bis der gesamte auf der Festplatte belegte Journal-Speicherplatz die angeforderte Größe erreicht hat:

      sudo journalctl --vacuum-size=1G
      

      Eine weitere Möglichkeit, das Journal zu verkleinern, ist die Angabe einer Sperrzeit mit der Option --vacuum-time. Alle Einträge, die über diese Zeit hinausgehen, werden gelöscht. Dadurch können Sie die Einträge behalten, die nach einer bestimmten Zeit erstellt wurden.

      Um beispielsweise Einträge aus dem letzten Jahr zu behalten, können Sie eingeben:

      sudo journalctl --vacuum-time=1years
      

      Begrenzen der Journal-Erweiterung

      Sie können Ihren Server so konfigurieren, dass er den Speicherplatz, den das Journal einnehmen kann, begrenzt. Dies kann durch die Bearbeitung der Datei /etc/systemd/journald.conf erfolgen.

      Die folgenden Einträge können verwendet werden, um das Wachstum des Journals zu begrenzen:

      • SystemMaxUse=: Gibt den maximalen Festplattenplatz an, den das Journal im permanenten Speicher belegen kann.
      • SystemKeepFree=: Gibt den Speicherplatz an, den das Journal beim Hinzufügen von Journaleinträgen im permanenten Speicher frei lassen soll.
      • SystemMaxFileSize=: Kontrolliert, wie große einzelne Journaldateien im persistenten Speicher werden können, bevor sie rotiert werden.
      • RuntimeMaxUse=: Gibt den maximalen Festplattenspeicher an, der im flüchtigen Speicher (innerhalb des Dateisystems /run) verwendet werden kann.
      • RuntimeKeepFree=: Gibt an, wie viel Speicherplatz beim Schreiben von Daten in den flüchtigen Speicher (innerhalb des Dateisystems /run) für andere Verwendungen freigehalten werden soll.
      • RuntimeMaxFileSize=: Gibt an, wie viel Speicherplatz eine einzelne Journaldatei im flüchtigen Speicher (innerhalb des Dateisystems /run) einnehmen kann, bevor sie rotiert wird.

      Durch die Einstellung dieser Werte können Sie kontrollieren, wie journald den Speicherplatz auf Ihrem Server verbraucht und bewahrt. Denken Sie daran, dass SystemMaxFileSize und RuntimeMaxFileSize darauf abzielen, dass archivierte Dateien die angegebenen Grenzen erreichen. Dies ist wichtig zu bedenken, wenn Sie Dateizählungen nach einer Vakuum-Operation interpretieren.

      Zusammenfassung

      Wie Sie sehen können, ist das Journal systemd unglaublich nützlich für das Erfassen und Verwalten Ihrer System- und Anwendungsdaten. Die meiste Flexibilität ergibt sich aus den umfangreichen Metadaten, die automatisch aufgezeichnet werden, und der zentralisierten Natur des Protokolls. Der Befehl journalctl macht es einfach, die erweiterten Funktionen des Journals zu nutzen und umfangreiche Analysen und relationales Debugging verschiedener Anwendungskomponenten durchzuführen.



      Source link