Öffne eine Containershell (SSH) und führe Befehle in Azure App Service aus

App Service bietet authentifizierten Zugriff auf laufende App-Container für Fehlersuche und administrative Aufgaben. Behandle den Containerzugriff als privilegierte Operation und gewähre den Zugriff nur Nutzern, die ihn benötigen.

App Service bietet browserbasierten SSH-Zugriff auf Apps, die in benutzerdefinierten Windows-Containern gehostet werden. Für die Browsersitzung ist keine spezielle Image-Konfiguration erforderlich.

Der Azure CLI-Befehl az webapp exec wird nur für Linux-Webanwendungen unterstützt. Verwenden Sie die in diesem Artikel enthaltenen Linux-CLI-Beispiele für Windows-App Service-Pläne nicht.

Für integrierte und benutzerdefinierte Linux-Container verwenden das neuere Browserterminal und az webapp exec Kudu als authentifizierten Proxy, um eine Verbindung mit dem laufenden Container herzustellen. Diese Optionen erfordern nicht, dass du einen SSH-Server installierst, kein SSH-Passwort einbettest, keinen SSH-Port freigibst oder einen SSH-Daemon in deinem eigenen Image startest. Legacy Kudu WebSSH und az webapp ssh Zugriff erfordern möglicherweise weiterhin einen SSH-Server in einem benutzerdefinierten Image.

Verwenden Sie das Azure-Portal für eine Browsersitzung, oder verwenden Sie den Preview-Befehl az webapp exec für eine lokale Terminalsitzung oder eine detached Command-Ausführung. Das Browser-Terminal setzt /bin/bash im Image voraus und unterstützt derzeit nicht, eine andere Shell auszuwählen. Wenn das Bild eine andere Shell hat, verwenden Sie az webapp exec --shell /bin/sh stattdessen. Images ohne Shell, einschließlich distroless Images, können keine interaktive Sitzung öffnen.

Prerequisites

  • Für die CLI-Beispiele installieren Sie Azure CLI 2.90.0 oder später und melden Sie sich an. Überprüfen Sie Ihre Version mit az version. Du kannst auch Azure Cloud Shell verwenden, wenn die CLI diese Anforderung erfüllt.
  • Für eine interaktive CLI-Sitzung verwenden Sie ein interaktives Terminal und eine Shell, die in Ihrem Image vorhanden ist. Die Standardeinstellung ist /bin/bash; für ein Image ohne Bash gib --shell /bin/sh an, wenn diese Shell verfügbar ist.

Öffnen einer SSH-Sitzung im Browser

Deine App und ihr Container müssen laufen, bevor du eine Browsersitzung öffnest.

Öffne im Azure-Portal deine App Service App. Unter Entwicklungstools wählen Sie SSH aus und dann Go aus. Melden Sie sich mit Ihrem Azure-Konto an, wenn Sie aufgefordert werden.

Die Sitzung öffnet sich in deinem Browser, wo du Befehle im App-Container ausführen kannst.

SSH-Verbindung

Öffnen einer SSH-Sitzung mit Azure CLI

Der Vorschaubefehl az webapp exec öffnet eine interaktive Shell im Hauptcontainer Ihrer App. Die Sitzung verwendet dein lokales Terminal unter Windows, macOS und Linux; sie öffnet keinen Browser.

az webapp exec --resource-group <resource-group-name> --name <app-name>

Für ein Bild, das /bin/sh statt bash verwendet:

az webapp exec --resource-group <resource-group-name> --name <app-name> --shell /bin/sh

Du kannst in dieser Sitzung Befehle ausführen und deren Ausgabe überprüfen. Verwenden Sie zum Beispiel top, wenn es im Image installiert ist. Um den SCM/Kudu-Container statt des App-Containers zu inspizieren:

az webapp exec --resource-group <resource-group-name> --name <app-name> --target kudu

Die App- und Kudu-Container sind unterschiedliche Umgebungen. Führe Befehle, die von der Laufzeit, den Abhängigkeiten oder der Netzwerkverbindung deiner App abhängen, im App-Container aus.

Wählen Sie eine Instanz oder einen Deployment-Slot

Standardmäßig verbindet sich die CLI mit einer App-Instanz. So finden Sie Instanz-IDs:

az webapp list-instances --resource-group <resource-group-name> --name <app-name> --output table

Um eine Verbindung zu einer bestimmten Instanz herzustellen:

az webapp exec --resource-group <resource-group-name> --name <app-name> --instance <instance-id>

Fügen Sie --slot <slot-name> hinzu, um auf einen Deployment-Slot zuzugreifen. Füge beim Auswählen der Instanz eines Slots auch --slot zu az webapp list-instances hinzu.

Der interaktive Shell-Modus unterstützt jeweils nur eine Instanz.

Befehle ohne interaktive Sitzung ausführen

Verwenden Sie --mode execute, um einen Befehl an den Haupt-App-Container zu senden, ohne eine Terminalsitzung zu öffnen. Der Befehl wird im Hintergrund ausgeführt. Dieser Modus ist nützlich für Hintergrunddiagnosen oder andere Arbeiten, die keine sofortige Ausgabe erfordern.

Important

Der Execute-Modus ist fire-and-forget. Ein Ergebnis mit Status accepted bestätigt lediglich, dass die Anfrage akzeptiert wurde, nicht, dass der Befehl ausgeführt, abgeschlossen oder erfolgreich ausgeführt wurde. Die CLI liefert weder die Standardausgabe noch die Standardfehlerausgabe oder den Exit-Code des entfernten Befehls zurück. Eine fehlgeschlagene Übermittlung führt zu einem CLI-Fehler, aber ein erfolgreicher CLI-Aufruf ist kein Beweis für eine erfolgreiche Fernausführung. Verwenden Sie eine interaktive Shell, wenn Sie das Ergebnis sofort beobachten möchten.

Führe ein Programm direkt aus

Verwenden --command Sie, um ein Programm und seine Argumente zu spezifizieren. Zitieren Sie den gesamten Befehl:

az webapp exec --resource-group <resource-group-name> --name <app-name> --mode execute --command "python3 /home/site/wwwroot/scripts/diagnostics.py" --working-directory /home/site/wwwroot --instance <instance-id>

Ersetzen Sie den Skriptpfad durch ein in Ihrer App bereitgestelltes Skript. Die ausführbare Datei und ihre Abhängigkeiten müssen im Container vorhanden sein.

--command interpretiert keine Shell-Operatoren wie >, | oder &&. Benutze sie --shell-command stattdessen, wenn du eine Shell brauchst. Diese beiden Optionen schließen sich gegenseitig aus.

Ausgabe erfassen und Abschluss prüfen

Das folgende Beispiel verwendet Bash-Client-Quoting, wie zum Beispiel in Cloud Shell. Er sendet einen schreibgeschützten Diagnosebefehl an eine einzelne Instanz und zeichnet dessen Ausgabe- und Exit-Status getrennt auf. Ersetzen Sie <run-id> durch eine neue Kennung für jede Invocation und <instance-id> durch eine ID aus az webapp list-instances.

az webapp exec --resource-group <resource-group-name> --name <app-name> \
  --mode execute --instance <instance-id> --shell /bin/sh \
  --shell-command 'uname -a > /home/LogFiles/diagnostics-<run-id>.log 2>&1; result=$?; printf "%s\n" "$result" > /home/LogFiles/diagnostics-<run-id>.exit'

Stellen Sie sicher, dass /bin/sh und der Diagnosebefehl existieren und dass /home/LogFiles existiert und beschreibbar ist. Die Persistenz in /home benutzerdefinierten Containern hängt von der Speicherkonfiguration der App ab. Die einzelnen Anführungszeichen verhindern, dass die Client-Shell $? und $result expandiert, bevor die Anfrage den Container erreicht.

Nach dem Absenden öffne eine interaktive App-Shell auf derselben Instanz und inspiziere die Dateien:

cat /home/LogFiles/diagnostics-<run-id>.log
cat /home/LogFiles/diagnostics-<run-id>.exit

Ein aufgezeichneter Exit-Status von 0 zeigt an, dass der Diagnosebefehl erfolgreich war. Ein Status ungleich null zeigt einen Fehler an; inspizieren Sie das Protokoll. Wenn die Statusdatei nicht existiert, wurde der Abschluss nicht festgestellt: Der Befehl könnte noch laufen, könnte nicht gestartet worden sein oder könnte unterbrochen worden sein. Leiten Sie den Erfolg nicht aus Akzeptanz oder aus dem Vorhandensein eines teilweisen Logbuchs ab. Verwenden Sie eine frische Lauf-Kennung, damit eine ältere Statusdatei nicht mit dem aktuellen Ergebnis verwechselt werden kann.

Die CLI bietet keine API zum Abfragen des Abschlussstatus. Das Weiterleiten der Ausgabe auf eine Datei macht sie nicht automatisch im App Service Log-Streaming verfügbar.

Bei Datenbankmigrationen oder anderen Operationen, die den geteilten Zustand ändern, wählen Sie eine Instanz aus, prüfen Sie den Abschluss separat und führen Sie die Operation nicht nur deshalb erneut aus, weil die Einreichung keine Ausgabe zurückgegeben hat. Behalten Sie den interaktiven Workflow bei, wenn Sie den Erfolg überprüfen müssen, bevor Sie weitermachen.

Führe unabhängige Befehle auf mehreren Instanzen aus

Der Ausführungsmodus akzeptiert außerdem eine komma-getrennte Liste von Instanz-IDs oder --instance all. Anfragen für mehrere Instanzen werden parallel eingereicht. Zum Beispiel führen Sie auf jeder Instanz ein bereitgestelltes pro-instanzliches Diagnoseskript aus:

az webapp exec --resource-group <resource-group-name> --name <app-name> --mode execute --command "python3 /home/site/wwwroot/scripts/diagnostics.py" --instance all

Das Skript muss seine eigenen Ergebnisse erfassen. Verwenden Sie unterschiedliche Ausgabepfade pro Instanz und pro Lauf, wenn der Speicher gemeinsam genutzt wird. Verwenden Sie all nicht für Migrationen für gemeinsam genutzte Datenbanken oder andere Operationen, die nur einmal ausgeführt werden müssen. Wenn einige Übermittlungen fehlschlagen, meldet die CLI einen Fehler, obwohl andere Instanzen den Befehl möglicherweise akzeptiert haben.

Fügen Sie --slot <slot-name> hinzu, um die Ausführung für einen Bereitstellungsslot durchzuführen.

Limitations

  • Der Ausführungsmodus zielt nur auf den Haupt-App-Container. Du kannst --target kudu nur im interaktiven Shell-Modus verwenden.
  • Nutze --working-directory oder --cwd nur im Execute-Modus und gib einen absoluten Pfad an.
  • Geben Sie einen absoluten Pfad für --shell an. Im Ausführungsmodus kannst du es nur mit --shell-commandverwenden.
  • Diese Vorschau bietet keine Dateiübertragung, keine Portweiterleitung und keine Möglichkeit, beliebige Sidecar-Container auszuwählen. Verwenden Sie unterstützte Bereitstellungsmethoden , um Dateien hochzuladen.
  • Detached Execution ist kein dauerhafter Job-Scheduler. Ein Container-Neustart oder -Austausch kann die Arbeit unterbrechen. Gehen Sie nicht von automatischen Neuversuchen oder einer genau einmaligen Ausführung aus.

SSH-Zugriff steuern

Deaktivieren Sie SSH-Zugriff bei Apps, die ihn nicht benötigen, indem Sie die sshEnabled Konfigurationseigenschaft der App auf falsesetzen. Die folgenden Beispiele verwenden Bash-JSON-Quoting:

az webapp config set --resource-group <resource-group-name> --name <app-name> \
  --generic-configurations '{"sshEnabled": false}'

Um den SSH-Zugriff erneut zu aktivieren:

az webapp config set --resource-group <resource-group-name> --name <app-name> \
  --generic-configurations '{"sshEnabled": true}'

Zur Inspektion der Konfiguration:

az webapp config show --resource-group <resource-group-name> --name <app-name> --query sshEnabled

Fügen Sie einen Deployment-Slot hinzu--slot <slot-name>, um ihn zu konfigurieren oder zu inspizieren.

Für die Governance über Apps und Slots hinweg verwenden Sie die integrierten Richtlinien App Service-Apps sollten SSH deaktivieren und App Service-App-Slots sollten SSH deaktivieren. Siehe die App Service Policy Reference für Zuweisungslinks.

Beide Richtlinien verwenden standardmäßig Audit und unterstützen auch Deny und Disabled. Sie bewerten einen fehlenden oder nicht falschen sshEnabled Wert als nicht konform. Audit meldet Verstöße; es deaktiviert SSH nicht. Deny verhindert nicht konforme Ressourcenänderungen; es konfiguriert bestehende Apps nicht automatisch neu. Sie können Richtlinien im Abonnement- oder Managementgruppenbereich zuweisen, einschließlich der Stammverwaltungsgruppe des Mandanten für mandantenweite Governance.

SSH-Konfiguration und Richtlinieneinhaltung sind kein Ersatz für die Absicherung des Zugriffs auf SCM/Kudu. Verwenden Sie die entsprechenden RBAC-Berechtigungen und Netzwerkzugriffsbeschränkungen.

Fehlerbehebung beim Container-Zugriff

  • Bestätige, dass die App erfolgreich startet. Überprüfen Sie die Diagnoseprotokolle auf Startfehler.
  • Für den CLI-Zugriff überprüfen Sie die CLI-Version, die ausgewählte App, den Slot und die Instanz sowie ob die gewünschte ausführbare Datei oder Shell existiert.
  • Überprüfen Sie die Autorisierung und die Netzwerkverbindung zum SCM-Endpunkt. Du musst keine grundlegende Publishing-Authentifizierung aktivieren; die CLI unterstützt Microsoft Entra-Authentifizierung, wenn die SCM-Basisauthentifizierung deaktiviert ist. Siehe Basisauthentifizierung deaktivieren.
  • Änderungen, die du im Container vornimmst, ersetzen nicht das Aktualisieren und Neudeployen der App oder des Images. Container-Neustarts können Dateien außerhalb des persistenten Speichers entfernen.