Freigeben über


Bereitstellen einer Java-Anwendung mit Quarkus in einem Azure Kubernetes Service-Cluster

In diesem Artikel erfahren Sie, wie Sie Red Hat Quarkus mit einer einfachen CRUD-Anwendung schnell in Azure Kubernetes Service (AKS) bereitstellen. Die Anwendung ist eine Aufgabenliste („Todo“) mit einem JavaScript-Front-End und einem REST-Endpunkt. Azure Database for PostgreSQL – Flexible Server stellt die Persistenzebene für die App bereit. In diesem Artikel erfahren Sie, wie Sie Ihre App lokal testen und in AKS bereitstellen.

Voraussetzungen

  • Wenn Sie kein Azure-Abonnement haben, erstellen Sie ein kostenloses Azure-Konto, bevor Sie beginnen.
  • Bereiten Sie einen lokalen Computer mit einem installierten UNIX-ähnlichen Betriebssystem (z. B. Ubuntu, macOS, Windows-Subsystem für Linux) vor.
  • Installieren Sie eine Java SE-Implementierung Version 17 oder später (z. B den Microsoft-Build von OpenJDK).
  • Installieren Sie Maven, Version 3.9.8 oder höher
  • Installieren Sie Docker für Ihr Betriebssystem.
  • Installieren Sie jq.
  • Installieren Sie cURL.
  • Installieren Sie Quarkus CLI, Version 3.12.1 oder höher.
  • Azure CLI für Unix-ähnliche Umgebungen. In diesem Artikel wird nur die Bash-Variante der Azure CLI benötigt.
    • Ein Entwickler sollte die Azure CLI installieren und sich interaktiv mit dem Befehl az login bei Azure anmelden, bevor er „DefaultAzureCredential“ im Code verwendet.
      az login
      
    • Für diesen Artikel ist mindestens Version 2.61.0 der Azure CLI erforderlich.

Erstellen des App-Projekts

Verwenden Sie den folgenden Befehl, um das Java-Beispielprojekt für diesen Artikel zu klonen. Das Beispiel befindet sich auf GitHub.

git clone https://github.com/Azure-Samples/quarkus-azure
cd quarkus-azure
git checkout 2024-12-16
cd aks-quarkus

Wenn eine Meldung darüber angezeigt wird, dass Sie sich in einem Zustand HEAD getrennt befinden, kann diese Nachricht problemlos ignoriert werden. Da in diesem Artikel keine Commits erforderlich sind, eignet sich der Status „detached HEAD“ (losgelöster Head).

Lokales Testen Ihrer Quarkus-App

Anhand der Schritte in diesem Abschnitt erfahren Sie, wie Sie die App lokal ausführen.

Quarkus unterstützt die automatische Bereitstellung nicht konfigurierter Dienste im Entwicklungs- und Testmodus. Diese Funktion von Quarkus wird als „Dev Services“ bezeichnet. Angenommen, Sie beziehen eine Quarkus-Funktion ein (z. B. das Herstellen einer Verbindung mit einem Datenbankdienst). Sie möchten die App testen, haben aber die Verbindung zu einer echten Datenbank noch nicht vollständig konfiguriert. Quarkus startet automatisch eine containerisierte Stubversion des relevanten Diensts und verbindet Ihre Anwendung mit diesem. Weitere Informationen finden Sie unter Übersicht über Dev Services in der Quarkus-Dokumentation.

Stellen Sie sicher, dass Ihre Containerumgebung ausgeführt wird, und verwenden Sie den folgenden Befehl, um in den Quarkus-Entwicklungsmodus zu wechseln:

quarkus dev

Anstelle von quarkus dev können Sie dasselbe Ergebnis mit Maven und der Verwendung von mvn quarkus:dev erzielen.

Sie werden möglicherweise gefragt, ob Sie Telemetriedaten zu Ihrer Nutzung des Quarkus-Entwicklermodus senden möchten. Beantworten Sie diese Frage nach Ihrem Belieben.

Mit dem Quarkus-Entwicklungsmodus wird Live Reload mit Hintergrundkompilierung aktiviert. Wenn Sie einen Aspekt Ihres App-Quellcodes ändern und Ihren Browser aktualisieren, können Sie die Änderungen erkennen. Wenn Probleme bei der Kompilierung oder Bereitstellung auftreten, werden Sie auf einer Fehlerseite darüber informiert. Der Quarkus-Entwicklungsmodus lauscht an Port 5005 auf einen Debugger. Wenn Sie vor dem Ausführen auf das Anfügen des Debuggers warten möchten, übergeben Sie -Dsuspend an der Befehlszeile. Wenn Sie den Debugger gar nicht wollen, können Sie -Ddebug=false verwenden.

Die Ausgabe sollte wie im folgenden Beispiel aussehen:

__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
INFO  [io.quarkus] (Quarkus Main Thread) quarkus-todo-demo-app-aks 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.2.0.Final) started in 3.377s. Listening on: http://localhost:8080

INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, hibernate-orm, hibernate-orm-panache, hibernate-validator, jdbc-postgresql, narayana-jta, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, vertx]

--
Tests paused
Press [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>

Drücken Sie w auf dem Terminal, auf dem der Quarkus-Entwicklungsmodus ausgeführt wird. Mit der w-Taste wird Ihr Standardwebbrowser geöffnet, um die Anwendung Todo anzuzeigen. Sie können über http://localhost:8080 auch direkt auf die grafische Benutzeroberfläche (GUI) der Anwendung zugreifen.

Screenshot: Beispiel-App „Todo“.

Versuchen Sie, einige Aufgabenelemente in der Aufgabenliste auszuwählen. Auf der Benutzeroberfläche wird die Auswahl im Textformat „durchgestrichen“ angezeigt. Sie können der Aufgabenliste auch ein neues Aufgabenelement hinzufügen, indem Sie Verify Todo apps (Todo-Apps überprüfen) eingeben und die EINGABETASTE drücken, wie im folgenden Screenshot gezeigt:

Screenshot: Beispiel-App „Todo“ mit neu hinzugefügten Elementen.

Greifen Sie auf die RESTful-API (/api) zu, um alle Aufgabenelemente abzurufen, die in der lokalen PostgreSQL-Datenbank gespeichert sind:

curl --verbose http://localhost:8080/api | jq .

Die Ausgabe sollte wie im folgenden Beispiel aussehen:

* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /api HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
< content-length: 664
< Content-Type: application/json;charset=UTF-8
<
{ [664 bytes data]
100   664  100   664    0     0  13278      0 --:--:-- --:--:-- --:--:-- 15441
* Connection #0 to host localhost left intact
[
  {
    "id": 1,
    "title": "Introduction to Quarkus Todo App",
    "completed": false,
    "order": 0,
    "url": null
  },
  {
    "id": 2,
    "title": "Quarkus on Azure App Service",
    "completed": false,
    "order": 1,
    "url": "https://learn.microsoft.com/en-us/azure/developer/java/eclipse-microprofile/deploy-microprofile-quarkus-java-app-with-maven-plugin"
  },
  {
    "id": 3,
    "title": "Quarkus on Azure Container Apps",
    "completed": false,
    "order": 2,
    "url": "https://learn.microsoft.com/en-us/training/modules/deploy-java-quarkus-azure-container-app-postgres/"
  },
  {
    "id": 4,
    "title": "Quarkus on Azure Functions",
    "completed": false,
    "order": 3,
    "url": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-first-quarkus"
  },
  {
    "id": 5,
    "title": "Verify Todo apps",
    "completed": false,
    "order": 5,
    "url": null
  }
]

Drücken Sie q, um den Quarkus-Entwicklungsmodus zu beenden.

Erstellen der Azure-Ressourcen zum Ausführen der Quarkus-App

Anhand der Schritte in diesem Abschnitt erfahren Sie, wie Sie die folgenden Azure-Ressourcen zum Ausführen der Quarkus-Beispiel-App erstellen:

  • Azure Database for PostgreSQL – Flexibler Server
  • Azure Container Registry
  • Azure Kubernetes Service (AKS)

Hinweis

In diesem Artikel wird die PostgreSQL-Authentifizierung deaktiviert, um bewährte Sicherheitsmethoden zu veranschaulichen. Microsoft Entra ID wird verwendet, um die Verbindung mit dem Server zu authentifizieren. Wenn Sie die PostgreSQL-Authentifizierung aktivieren müssen, lesen Sie Schnellstart: Verwenden von Java und JDBC mit Azure Database for PostgreSQL – Flexible Server und wählen Sie die Registerkarte Kennwort aus.

Einige dieser Ressourcen müssen im Geltungsbereich des Azure-Abonnements eindeutige Namen aufweisen. Um diese Eindeutigkeit sicherzustellen, können Sie das Muster Initialen, Sequenz, Datum, Suffix verwenden. Um dieses Muster anzuwenden, benennen Sie Ihre Ressourcen in folgender Reihenfolge: Ihre Initialen, eine Sequenznummer, heutiges Datum und eine Art ressourcenspezifisches Suffix (z. B. rg für „Ressourcengruppe“). Die folgenden Umgebungsvariablen verwenden dieses Muster. Ersetzen Sie die Platzhalterwerte UNIQUE_VALUE und LOCATION durch Ihre eigenen Werte, und führen Sie dann die folgenden Befehle in Ihrem Terminal aus:

export UNIQUE_VALUE=<your unique value, such as ejb010717>
export RESOURCE_GROUP_NAME=${UNIQUE_VALUE}rg
export LOCATION=<your desired Azure region for deploying your resources - for example, northeurope>
export REGISTRY_NAME=${UNIQUE_VALUE}reg
export DB_SERVER_NAME=${UNIQUE_VALUE}db
export DB_NAME=demodb
export CLUSTER_NAME=${UNIQUE_VALUE}aks
export AKS_NS=${UNIQUE_VALUE}ns

Erstellen eines flexiblen Azure Database for PostgreSQL-Servers

Azure Database for PostgreSQL Flexible Server ist ein vollständig verwalteter Datenbankdienst, der eine differenziertere Steuerung und mehr Flexibilität bei den Verwaltungsfunktionen und Konfigurationseinstellungen der Datenbank bietet. In diesem Abschnitt wird das Erstellen einer flexiblen Azure-Datenbank für PostgreSQL-Serverinstanz mithilfe der Azure CLI gezeigt.

Erstellen Sie zunächst eine Ressourcengruppe, die den Datenbankserver und andere Ressourcen enthält, indem Sie den folgenden Befehl verwenden:

az group create \
    --name $RESOURCE_GROUP_NAME \
    --location $LOCATION

Erstellen Sie dann eine flexible Azure Database for PostgreSQL-Serverinstanz anhand des folgenden Befehls:

az postgres flexible-server create \
    --name $DB_SERVER_NAME \
    --database-name $DB_NAME \
    --resource-group $RESOURCE_GROUP_NAME \
    --location $LOCATION \
    --public-access 0.0.0.0 \
    --sku-name Standard_B1ms \
    --tier Burstable \
    --active-directory-auth Enabled \
    --yes

Es dauert ein paar Minuten, den Server, die Datenbank, den Administratorbenutzer und die Firewallregeln zu erstellen. Wenn der Befehl erfolgreich ist, sieht die Ausgabe in etwa wie im folgenden Beispiel aus:

{
  "connectionString": "postgresql://REDACTED@ejb011212qdb.postgres.database.azure.com/demodb?sslmode=require",
  "databaseName": "demodb",
  "firewallName": "AllowAllAzureServicesAndResourcesWithinAzureIps_2024-12-12_14-30-22",
  "host": "ejb011212qdb.postgres.database.azure.com",
  "id": "/subscriptions/c7844e91-b11d-4a7f-ac6f-996308fbcdb9/resourceGroups/ejb011211sfi/providers/Microsoft.DBforPostgreSQL/flexibleServers/ejb011212qdb",
  "location": "East US 2",
  "password": "REDACTED",
  "resourceGroup": "ejb011211sfi",
  "skuname": "Standard_B1ms",
  "username": "sorrycamel2",
  "version": "16"
}

Lokales Testen der App mit Azure Database for PostgreSQL – Flexibler Server

Im vorherigen Abschnitt haben Sie die Quarkus-App lokal im Entwicklungsmodus mit einer PostgreSQL-Datenbank getestet, die als Docker-Container bereitgestellt wird. Testen Sie jetzt die Verbindung mit der Azure Database for PostgreSQL – Flexibler Server-Instanz lokal.

Fügen Sie zunächst den aktuell angemeldeten Benutzer als Microsoft Entra-Administrator zur Azure Database for PostgreSQL – Flexibler Server-Instanz hinzu, indem Sie die folgenden Befehle verwenden:

ENTRA_ADMIN_NAME=$(az account show --query user.name --output tsv)
az postgres flexible-server ad-admin create \
    --resource-group $RESOURCE_GROUP_NAME \
    --server-name $DB_SERVER_NAME \
    --display-name $ENTRA_ADMIN_NAME \
    --object-id $(az ad signed-in-user show --query id --output tsv)

Die erfolgreiche Ausgabe ist ein JSON-Objekt, einschließlich der Eigenschaft "type": "Microsoft.DBforPostgreSQL/flexibleServers/administrators".

Fügen Sie als Nächstes die lokale IP-Adresse zu den Firewallregeln der Azure Database for PostgreSQL – Flexibler Server-Instanz hinzu, indem Sie die folgenden Schritte ausführen:

  1. Rufen Sie die lokale IP-Adresse Ihres Computers ab, auf dem Sie die Quarkus-App lokal ausführen. Besuchen Sie z. B. https://whatismyipaddress.com, um Ihre öffentliche IP v4-Adresse abzurufen.

  2. Definieren Sie eine Umgebungsvariable mit der lokalen IP-Adresse, die Sie im vorherigen Schritt erhalten haben.

    export AZ_LOCAL_IP_ADDRESS=<your local IP address>
    
  3. Führen Sie den folgenden Befehl aus, um die lokale IP-Adresse zu den Firewallregeln der Azure Database for PostgreSQL – Flexibler Server-Instanz hinzuzufügen:

    az postgres flexible-server firewall-rule create \
        --resource-group $RESOURCE_GROUP_NAME \
        --name $DB_SERVER_NAME \
        --rule-name $DB_SERVER_NAME-database-allow-local-ip \
        --start-ip-address $AZ_LOCAL_IP_ADDRESS \
        --end-ip-address $AZ_LOCAL_IP_ADDRESS
    

Legen Sie dann die folgenden Umgebungsvariablen in Ihrem vorherigen Terminal fest. Diese Umgebungsvariablen werden verwendet, um eine Verbindung mit der Azure Database for PostgreSQL Flexibler Server-Instanz aus der lokal ausgeführten Quarkus-App herzustellen:

export AZURE_POSTGRESQL_HOST=${DB_SERVER_NAME}.postgres.database.azure.com
export AZURE_POSTGRESQL_PORT=5432
export AZURE_POSTGRESQL_DATABASE=${DB_NAME}
export AZURE_POSTGRESQL_USERNAME=${ENTRA_ADMIN_NAME}

Hinweis

Die Werte der Umgebungsvariablen AZURE_POSTGRESQL_HOST, AZURE_POSTGRESQL_PORT, AZURE_POSTGRESQL_DATABASE und AZURE_POSTGRESQL_USERNAME werden von Datenbankkonfigurationseigenschaften gelesen, die im vorherigen Abschnitt in der Datei src/main/resources/application.properties definiert wurden. Diese Werte werden mithilfe der kennwortlosen Service Connector-Erweiterung zur Laufzeit automatisch in die App eingefügt, wenn Sie die Quarkus-App später in diesem Artikel im AKS-Cluster bereitstellen.

Führen Sie jetzt die Quarkus-App lokal aus, um die Verbindung mit der Azure Database for PostgreSQL – Flexibler Server-Instanz zu testen. Verwenden Sie den folgenden Befehl aus, um die App im Produktionsmodus zu starten:

quarkus build
java -jar target/quarkus-app/quarkus-run.jar

Hinweis

Wenn die App aufgrund einer Fehlermeldung wie ERROR [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread) Acquisition timeout while waiting for new connection nicht gestartet werden kann, liegt dies wahrscheinlich an der Netzwerkeinstellung Ihres lokalen Computers. Wählen Sie Aktuelle Client-IP-Adresse hinzufügen erneut über das Azure-Portal aus. Weitere Informationen finden Sie im Abschnitt Erstellen einer Firewallregel, nachdem der Server erstellt wurde in Erstellen und Verwalten von Firewallregeln für Azure Database for PostgreSQL – Flexibler Server im Azure-Portal. Führen Sie die App dann erneut aus.

Öffnen Sie http://localhost:8080 in einem neuen Webbrowser, um auf die Todo-Anwendung zuzugreifen. Die Todo-App sollte ähnlich dem aussehen, was Sie beim lokalen Ausführen der App im Entwicklungsmodus gesehen haben.

Erstellen einer Azure Container Registry-Instanz

Da Quarkus eine cloudnative Technologie ist, bietet es integrierte Unterstützung für das Erstellen von Containern, die in Kubernetes ausgeführt werden. Kubernetes hängt vollständig von einer Containerregistrierung ab, in der nach den auszuführenden Containerimages sucht. In AKS ist Unterstützung für Azure Container Registry integriert.

Erstellen Sie mit dem Befehl az acr create die Container Registry-Instanz. Im folgenden Beispiel wird eine Container Registry-Instanz erstellt, die mit dem Wert Ihrer Umgebungsvariablen ${REGISTRY_NAME} benannt ist:

az acr create \
    --resource-group $RESOURCE_GROUP_NAME \
    --location ${LOCATION} \
    --name $REGISTRY_NAME \
    --sku Basic

Nach kurzer Zeit sollte eine JSON-Ausgabe mit folgenden Zeilen angezeigt werden:

  "provisioningState": "Succeeded",
  "publicNetworkAccess": "Enabled",
  "resourceGroup": "<YOUR_RESOURCE_GROUP>",

Rufen Sie den Anmeldeserver für die Container Registry-Instanz mithilfe des folgenden Befehls ab:

export LOGIN_SERVER=$(az acr show \
    --name $REGISTRY_NAME \
    --query 'loginServer' \
    --output tsv)
echo $LOGIN_SERVER

Verbinden von Docker mit der Container Registry-Instanz

Melden Sie sich bei der Container Registry-Instanz an. Mit der Anmeldung können Sie ein Image per Push übertragen. Verwenden Sie den folgenden Befehl aus, um sich bei der Registry anzumelden.

az acr login --name $REGISTRY_NAME

Wenn Sie sich erfolgreich bei der Container Registry-Instanz angemeldet haben, sollte Ihnen Login Succeeded am Ende der Befehlsausgabe angezeigt werden.

Erstellen eines AKS-Clusters

Erstellen Sie mithilfe des Befehls az aks create einen AKS-Cluster. Im folgenden Beispiel wird ein Cluster erstellt, der nach dem Wert Ihrer Umgebungsvariablen ${CLUSTER_NAME} mit einem Knoten benannt ist. Der Cluster ist mit der Container Registry-Instanz verbunden, die Sie weiter oben erstellt haben. Es dauert mehrere Minuten, bis dieser Befehl abgeschlossen ist. Der Cluster wird mit aktivierter verwalteter Identität gestartet. Dieser Schritt ist für die kennwortlose Datenbankverbindung erforderlich.

az aks create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --attach-acr $REGISTRY_NAME \
    --node-count 1 \
    --generate-ssh-keys \
    --enable-managed-identity

Nach wenigen Minuten ist die Ausführung des Befehls abgeschlossen, und es werden Informationen zum Cluster im JSON-Format einschließlich der folgenden Ausgabe zurückgegeben:

  "nodeResourceGroup": "MC_<your resource_group_name>_<your cluster name>_<your region>",
  "privateFqdn": null,
  "provisioningState": "Succeeded",
  "resourceGroup": "<your resource group name>",

Herstellen einer Verbindung mit dem AKS-Cluster

Verwenden Sie zum Verwalten eines Kubernetes-Clusters den Kubernetes-Befehlszeilenclient kubectl. Verwenden Sie zum lokalen Installieren von kubectl den Befehl az aks install-cli, wie im folgenden Beispiel gezeigt:

az aks install-cli

Weitere Informationen zu kubectl finden Sie unter Befehlszeilentool (kubectl) in der Kubernetes-Dokumentation.

Mit dem Befehl az aks get-credentials können Sie kubectl für die Verbindung mit Ihrem Kubernetes-Cluster konfigurieren, wie aus dem folgenden Beispiel hervorgeht. Mit diesem Befehl werden die Anmeldeinformationen heruntergeladen und die Kubernetes-CLI für ihre Verwendung konfiguriert.

az aks get-credentials \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --overwrite-existing \
    --admin

Bei erfolgreichem Abschluss enthält die Ausgabe einen Text, der mit dem im folgenden Beispiel vergleichbar ist:

Merged "ejb010718aks-admin" as current context in /Users/edburns/.kube/config

Manchmal kann es praktisch sein, für kubectl den Alias k zu verwenden. Verwenden Sie in diesem Fall den folgenden Befehl:

alias k=kubectl

Überprüfen Sie die Verbindung mit Ihrem Cluster mithilfe des Befehls kubectl get, um eine Liste der Clusterknoten zurückzugeben, wie im folgenden Beispiel gezeigt:

kubectl get nodes

Die folgende Beispielausgabe zeigt den in den vorherigen Schritten erstellten Knoten. Vergewissern Sie sich, dass der Knoten den Status Bereit hat:

NAME                                STATUS   ROLES   AGE     VERSION
aks-nodepool1-xxxxxxxx-yyyyyyyyyy   Ready    agent   76s     v1.28.9

Erstellen eines neuen Namespace in AKS

Verwenden Sie den folgenden Befehl, um einen neuen Namespace in Kubernetes Service für Ihre Quarkus-App zu erstellen:

kubectl create namespace ${AKS_NS}

Die Ausgabe sollte wie im folgenden Beispiel aussehen:

namespace/<your namespace> created

Erstellen einer Dienstverbindung in AKS mit Service Connector

In diesem Abschnitt erstellen Sie eine Dienstverbindung zwischen dem AKS-Cluster und Azure Database for PostgreSQL – Flexibler Server mithilfe von Microsoft Entra Workload ID mit Service Connector. Mit dieser Verbindung kann der AKS-Cluster ohne SQL-Authentifizierung auf Azure Database for PostgreSQL – Flexibler Server zugreifen.

Führen Sie die folgenden Befehle aus, um eine Verbindung zwischen dem AKS-Cluster und der PostgreSQL-Datenbank mithilfe von Microsoft Entra Workload ID mit Service Connector zu erstellen.

# Register the Service Connector and Kubernetes Configuration resource providers
az provider register --namespace Microsoft.ServiceLinker --wait
az provider register --namespace Microsoft.KubernetesConfiguration --wait

# Install the Service Connector passwordless extension
az extension add --name serviceconnector-passwordless --upgrade --allow-preview true

# Retrieve the AKS cluster and Azure SQL Server resource IDs
export AKS_CLUSTER_RESOURCE_ID=$(az aks show \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $CLUSTER_NAME \
    --query id \
    --output tsv)
export AZURE_POSTGRESQL_RESOURCE_ID=$(az postgres flexible-server show \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $DB_SERVER_NAME \
    --query id \
    --output tsv)

# Create a user-assigned managed identity used for workload identity
export USER_ASSIGNED_IDENTITY_NAME=workload-identity-uami
az identity create \
    --resource-group ${RESOURCE_GROUP_NAME} \
    --name ${USER_ASSIGNED_IDENTITY_NAME}

# Retrieve the user-assigned managed identity resource ID
export UAMI_RESOURCE_ID=$(az identity show \
    --resource-group ${RESOURCE_GROUP_NAME} \
    --name ${USER_ASSIGNED_IDENTITY_NAME} \
    --query id \
    --output tsv)

# Create a service connection between your AKS cluster and your PostgreSQL database using Microsoft Entra Workload ID
az aks connection create postgres-flexible \
    --connection akspostgresconn \
    --kube-namespace $AKS_NS \
    --source-id $AKS_CLUSTER_RESOURCE_ID \
    --target-id $AZURE_POSTGRESQL_RESOURCE_ID/databases/$DB_NAME \
    --workload-identity $UAMI_RESOURCE_ID

Das Vorhandensein der folgenden JSON in der Ausgabe des letzten Befehls in den vorherigen Schritten zeigt eine erfolgreiche Installation des Dienstconnectors an:

"name": "akspostgresconn",
"provisioningState": "Succeeded",

Hinweis

Wir empfehlen die Verwendung von Microsoft Entra Workload ID für den sicheren Zugriff auf Azure Database for PostgreSQL – Flexibler Server ohne Authentifizierung über Benutzername/Kennwort. Wenn Sie die Authentifizierung über Benutzername/Kennwort verwenden müssen, ignorieren Sie die vorherigen Schritte in diesem Abschnitt, und verwenden Sie den Benutzernamen und das Kennwort, um eine Verbindung mit der Datenbank herzustellen.

Abrufen eines von Service Connector erstellten Dienstkontos und geheimen Schlüssels

Um sich bei Azure Database for PostgreSQL – Flexibler Server zu authentifizieren, müssen Sie das von Service Connector erstellte Dienstkonto und den geheimen Kubernetes-Schlüssel abrufen. Folgen Sie den Anweisungen im Abschnitt Aktualisieren Ihres Containers im Tutorial: Verbinden einer AKS-App mit Azure SQL-Datenbank. Wählen Sie die Option Direkt eine Bereitstellung mithilfe des bereitgestellten YAML-Beispielcodeausschnitts erstellen aus, und führen Sie den folgenden Schritt aus:

  • Kopieren Sie aus den hervorgehobenen Abschnitten im Kubernetes-Bereitstellungs-YAML die Werte serviceAccountName und secretRef.name, die im folgenden Beispiel als <service-account-name> und <secret-name> angegeben sind:

    serviceAccountName: <service-account-name>
    containers:
    - name: raw-linux
        envFrom:
           - secretRef:
              name: <secret-name>
    

    Diese Werte werden im nächsten Abschnitt verwendet, um die Quarkus-Anwendung im AKS-Cluster bereitzustellen.

Anpassen der cloudnativen Konfiguration

Als cloudnative Technologie bietet Quarkus die Möglichkeit, Ressourcen für standardmäßiges Kubernetes, Red Hat OpenShift und Knative automatisch zu konfigurieren. Weitere Informationen finden Sie im Quarkus-Leitfaden für Kubernetes, im Quarkus-Leitfaden für OpenShift und im Quarkus-Leitfaden für Knative. Entwickler können die Anwendung in einem Kubernetes-Zielcluster bereitstellen, indem sie die generierten Manifeste anwenden.

Verwenden Sie den folgenden Befehl, um die entsprechenden Kubernetes-Ressourcen zu generieren und die Erweiterungen quarkus-kubernetes und container-image-jib in Ihrem lokalen Terminal hinzuzufügen:

quarkus ext add kubernetes container-image-jib

Quarkus ändert den POM, um sicherzustellen, dass diese Erweiterungen als <dependencies> aufgeführt werden. Wenn Sie aufgefordert werden, ein Tool namens JBang zu installieren, antworten Sie mit Ja, und erlauben Sie die Installation.

Die Ausgabe sollte wie im folgenden Beispiel aussehen:

[SUCCESS] ✅  Extension io.quarkus:quarkus-kubernetes has been installed
[SUCCESS] ✅  Extension io.quarkus:quarkus-container-image-jib has been installed

Um die hinzugefügten Erweiterungen zu überprüfen, können Sie git diff ausführen und die Ausgabe untersuchen.

Als cloudnative Technologie unterstützt Quarkus das Konzept von Konfigurationsprofilen. Quarkus verfügt über die folgenden drei integrierten Profile:

  • dev: Wird im Entwicklungsmodus aktiviert
  • test: Wird beim Ausführen von Tests aktiviert
  • prod: Standardprofil (weder im Entwicklungs- noch im Testmodus)

Quarkus unterstützt bei Bedarf eine beliebige Anzahl benannter Profile.

Die letzten Schritte in diesem Abschnitt sind dem Anpassen der Werte in der Datei src/main/resources/application.properties gewidmet.

Das Präfix prod. gibt an, dass diese Eigenschaften aktiv sind, wenn sie im Profil prod ausgeführt werden. Weitere Informationen zu Konfigurationsprofilen finden Sie in der Quarkus-Dokumentation.

Datenbankkonfiguration

Untersuchen Sie die folgenden Datenbank-Konfigurationsvariablen. Die datenbankverbindungsbezogenen Eigenschaften %prod.quarkus.datasource.jdbc.url und %prod.quarkus.datasource.username lesen Werte aus den entsprechenden Umgebungsvariablen AZURE_POSTGRESQL_HOST, AZURE_POSTGRESQL_PORT, AZURE_POSTGRESQL_DATABASE und AZURE_POSTGRESQL_USERNAME. Diese Umgebungsvariablen werden geheimen Werten zugeordnet, die die Datenbankverbindungsinformationen speichern. Aus Sicherheitsgründen werden sie automatisch mit der kennwortlosen Service Connector-Erweiterung generiert, wie an anderer Stelle in diesem Artikel gezeigt.

# Database configurations
%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://${AZURE_POSTGRESQL_HOST}:${AZURE_POSTGRESQL_PORT}/${AZURE_POSTGRESQL_DATABASE}?\
authenticationPluginClassName=com.azure.identity.extensions.jdbc.postgresql.AzurePostgresqlAuthenticationPlugin\
&sslmode=require
%prod.quarkus.datasource.username=${AZURE_POSTGRESQL_USERNAME}
%prod.quarkus.datasource.jdbc.acquisition-timeout=10
%prod.quarkus.hibernate-orm.database.generation=drop-and-create
%prod.quarkus.hibernate-orm.sql-load-script=import.sql

Kubernetes-Konfiguration

Untersuchen Sie die folgenden Kubernetes-Konfigurationsvariablen. service-type ist auf load-balancer festgelegt, um extern auf die App zuzugreifen. Ersetzen Sie die Werte <service-account-name> und <secret-name> durch die tatsächlichen Werte, die Sie im vorherigen Abschnitt kopiert haben.

# Kubernetes configurations
%prod.quarkus.kubernetes.deployment-target=kubernetes
%prod.quarkus.kubernetes.service-type=load-balancer
%prod.quarkus.kubernetes.labels."azure.workload.identity/use"=true
%prod.quarkus.kubernetes.service-account=<service-account-name>
%prod.quarkus.kubernetes.env.mapping.AZURE_CLIENT_ID.from-secret=<secret-name>
%prod.quarkus.kubernetes.env.mapping.AZURE_CLIENT_ID.with-key=AZURE_POSTGRESQL_CLIENTID
%prod.quarkus.kubernetes.env.mapping.AZURE_POSTGRESQL_HOST.from-secret=<secret-name>
%prod.quarkus.kubernetes.env.mapping.AZURE_POSTGRESQL_HOST.with-key=AZURE_POSTGRESQL_HOST
%prod.quarkus.kubernetes.env.mapping.AZURE_POSTGRESQL_PORT.from-secret=<secret-name>
%prod.quarkus.kubernetes.env.mapping.AZURE_POSTGRESQL_PORT.with-key=AZURE_POSTGRESQL_PORT
%prod.quarkus.kubernetes.env.mapping.AZURE_POSTGRESQL_DATABASE.from-secret=<secret-name>
%prod.quarkus.kubernetes.env.mapping.AZURE_POSTGRESQL_DATABASE.with-key=AZURE_POSTGRESQL_DATABASE
%prod.quarkus.kubernetes.env.mapping.AZURE_POSTGRESQL_USERNAME.from-secret=<secret-name>
%prod.quarkus.kubernetes.env.mapping.AZURE_POSTGRESQL_USERNAME.with-key=AZURE_POSTGRESQL_USERNAME

Die anderen Kubernetes-Konfigurationen geben die Zuordnung der geheimen Werte zu den Umgebungsvariablen in der Anwendung Quarkus an. Das <secret-name>-Geheimnis enthält die Datenbankverbindungsinformationen. Die Schlüssel AZURE_POSTGRESQL_CLIENTID, AZURE_POSTGRESQL_HOST, AZURE_POSTGRESQL_PORT, AZURE_POSTGRESQL_DATABASE und AZURE_POSTGRESQL_USERNAME in der Geheimniszuordnung zu den AZURE_CLIENT_ID-, AZURE_POSTGRESQL_HOST-, AZURE_POSTGRESQL_PORT-, AZURE_POSTGRESQL_DATABASE- und AZURE_POSTGRESQL_USERNAME-Umgebungsvariablen.

Verwenden Sie Befehle wie im folgenden Beispiel, um die geheimen Schlüssel direkt mit Kubectl zu untersuchen:

kubectl -n ${AKS_NS} get secret <secret-name> -o jsonpath="{.data.AZURE_POSTGRESQL_USERNAME}" | base64 --decode

Konfiguration von Containerimages

Als cloudnative Technologie unterstützt Quarkus das Generieren von OCI-Containerimages, die mit Docker kompatibel sind. Ersetzen Sie den Wert <LOGIN_SERVER_VALUE> durch den tatsächlichen Wert der ${LOGIN_SERVER}-Umgebungsvariable.

# Container Image Build
%prod.quarkus.container-image.build=true
%prod.quarkus.container-image.image=<LOGIN_SERVER_VALUE>/todo-quarkus-aks:1.0

Wenn Sie alle erforderlichen Ersetzungen in application.properties abgeschlossen haben, darf das <-Zeichen nicht mehr vorkommen. Wenn vorhanden, überprüfen Sie, ob Sie alle erforderlichen Ersetzungen abgeschlossen haben.

Erstellen des Containerimage und Pushen des Containerimages an Container Registry

Führen Sie jetzt den folgenden Befehl aus, um die eigentliche Anwendung zu erstellen. Dieser Befehl verwendet die Kubernetes- und Jib-Erweiterungen, um das Containerimage zu erstellen.

quarkus build --no-tests

Die Ausgabe sollte mit BUILD SUCCESS enden. Die Kubernetes-Manifestdateien werden in target/kubernetes generiert, wie im folgenden Beispiel gezeigt:

tree target/kubernetes
target/kubernetes
├── kubernetes.json
└── kubernetes.yml

0 directories, 2 files

Sie können mithilfe der docker-Befehlszeile (CLI) überprüfen, ob auch das Containerimage generiert wird. Die Ausgabe sieht etwa folgendermaßen aus:

docker images | grep todo-quarkus-aks
<LOGIN_SERVER_VALUE>/todo-quarkus-aks   1.0       b13c389896b7   18 minutes ago   422MB

Pushen Sie die Containerimages mit dem folgenden Befehl an die Container Registry:

export TODO_QUARKUS_TAG=$(docker images | grep todo-quarkus-aks | head -n1 | cut -d " " -f1)
echo ${TODO_QUARKUS_TAG}
docker push ${TODO_QUARKUS_TAG}:1.0

Die Ausgabe sollte in etwa wie im folgenden Beispiel aussehen:

The push refers to repository [<LOGIN_SERVER_VALUE>/todo-quarkus-aks]
dfd615499b3a: Pushed
56f5cf1aa271: Pushed
4218d39b228e: Pushed
b0538737ed64: Pushed
d13845d85ee5: Pushed
60609ec85f86: Pushed
1.0: digest: sha256:0ffd70d6d5bb3a4621c030df0d22cf1aa13990ca1880664d08967bd5bab1f2b6 size: 1995

Nachdem Sie die App an die Container Registry gepusht haben, können Sie AKS anweisen, die App auszuführen.

Bereitstellen der Quarkus-App in AKS

Anhand der Schritte in diesem Abschnitt erfahren Sie, wie Sie die Quarkus-Beispiel-App in den erstellten Azure-Ressourcen ausführen.

Bereitstellen der Quarkus-App in AKS mit „kubectl apply“

Stellen Sie die Kubernetes-Ressourcen über die Befehlszeile mit dem Befehl kubectl bereit, wie im folgenden Beispiel gezeigt:

kubectl apply -f target/kubernetes/kubernetes.yml -n ${AKS_NS}

Die Ausgabe sollte wie im folgenden Beispiel aussehen:

service/quarkus-todo-demo-app-aks created
deployment.apps/quarkus-todo-demo-app-aks created

Überprüfen Sie mit dem folgenden Befehl, ob die App ausgeführt wird:

kubectl -n $AKS_NS get pods

Wenn der Wert des Felds STATUS etwas anderes als Running enthält, suchen Sie nach dem Fehler, und beheben Sie das Problem, bevor Sie fortfahren. Es kann hilfreich sein, mit dem folgenden Befehl die Podprotokolle zu untersuchen:

kubectl -n $AKS_NS logs $(kubectl -n $AKS_NS get pods | grep quarkus-todo-demo-app-aks | cut -d " " -f1)

Rufen Sie die EXTERNAL-IP ab, um mit dem folgenden Befehl auf die „Todo“-Anwendung zuzugreifen:

kubectl get svc -n ${AKS_NS}

Die Ausgabe sollte wie im folgenden Beispiel aussehen:

NAME                        TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
quarkus-todo-demo-app-aks   LoadBalancer   10.0.236.101   20.12.126.200   80:30963/TCP   37s

Sie können den folgenden Befehl verwenden, um den Wert der EXTERNAL-IP in einer Umgebungsvariablen als vollqualifizierte URL zu speichern:

export QUARKUS_URL=http://$(kubectl get svc -n ${AKS_NS} | grep quarkus-todo-demo-app-aks | cut -d " " -f10)
echo $QUARKUS_URL

Öffnen Sie einen neuen Webbrowser mit dem Wert von ${QUARKUS_URL}. Fügen Sie dann ein neues Aufgabenelement mit dem Text Deployed the Todo app to AKS hinzu. Markieren Sie außerdem das Element Introduction to Quarkus Todo App als abgeschlossen.

Screenshot: In AKS ausgeführte Beispiel-App „Todo“.

Greifen Sie auf die RESTful-API (/api) zu, um alle Aufgabenelemente abzurufen, die in der Azure PostgreSQL-Datenbank gespeichert sind, wie im folgenden Beispiel gezeigt:

curl --verbose ${QUARKUS_URL}/api | jq .

Die Ausgabe sollte wie im folgenden Beispiel aussehen:

* Connected to 20.237.68.225 (20.237.68.225) port 80 (#0)
> GET /api HTTP/1.1
> Host: 20.237.68.225
> User-Agent: curl/7.88.1
> Accept: */*
>
< HTTP/1.1 200 OK
< content-length: 828
< Content-Type: application/json;charset=UTF-8
<
[
  {
    "id": 2,
    "title": "Quarkus on Azure App Service",
    "completed": false,
    "order": 1,
    "url": "https://learn.microsoft.com/en-us/azure/developer/java/eclipse-microprofile/deploy-microprofile-quarkus-java-app-with-maven-plugin"
  },
  {
    "id": 3,
    "title": "Quarkus on Azure Container Apps",
    "completed": false,
    "order": 2,
    "url": "https://learn.microsoft.com/en-us/training/modules/deploy-java-quarkus-azure-container-app-postgres/"
  },
  {
    "id": 4,
    "title": "Quarkus on Azure Functions",
    "completed": false,
    "order": 3,
    "url": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-first-quarkus"
  },
  {
    "id": 5,
    "title": "Deployed the Todo app to AKS",
    "completed": false,
    "order": 5,
    "url": null
  },
  {
    "id": 1,
    "title": "Introduction to Quarkus Todo App",
    "completed": true,
    "order": 0,
    "url": null
  }
]

Überprüfen Sie, ob die Datenbank aktualisiert wird.

Führen Sie den folgenden Befehl aus, um sicherzustellen, dass die Datenbank jetzt korrekt aktualisiert ist:

ACCESS_TOKEN=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken)
az postgres flexible-server execute \
    --admin-user $ENTRA_ADMIN_NAME \
    --admin-password $ACCESS_TOKEN \
    --name $DB_SERVER_NAME \
    --database-name $DB_NAME \
    --querytext "select * from todo;"

Wenn Sie aufgefordert werden, eine Erweiterung zu installieren, antworten Sie mit Y.

Die Ausgabe sollte ähnlich wie im folgenden Beispiel aussehen und dieselben Elemente enthalten, die zuvor auf der Oberfläche der App „Todo“ und in der Ausgabe des Befehls curl angezeigt wurden:

Successfully connected to <DB_SERVER_NAME>.
Ran Database Query: 'select * from todo;'
Retrieving first 30 rows of query output, if applicable.
Closed the connection to <DB_SERVER_NAME>
[
  {
    "completed": false,
    "id": 2,
    "ordering": 1,
    "title": "Quarkus on Azure App Service",
    "url": "https://learn.microsoft.com/en-us/azure/developer/java/eclipse-microprofile/deploy-microprofile-quarkus-java-app-with-maven-plugin"
  },
  {
    "completed": false,
    "id": 3,
    "ordering": 2,
    "title": "Quarkus on Azure Container Apps",
    "url": "https://learn.microsoft.com/en-us/training/modules/deploy-java-quarkus-azure-container-app-postgres/"
  },
  {
    "completed": false,
    "id": 4,
    "ordering": 3,
    "title": "Quarkus on Azure Functions",
    "url": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-first-quarkus"
  },
  {
    "completed": false,
    "id": 5,
    "ordering": 5,
    "title": "Deployed the Todo app to AKS",
    "url": null
  },
  {
    "completed": true,
    "id": 1,
    "ordering": 0,
    "title": "Introduction to Quarkus Todo App",
    "url": null
  }
]

Wenn Sie fertig sind, löschen Sie die Firewallregel, mit der Ihre lokale IP-Adresse auf die Azure Database for PostgreSQL – Flexibler Server-Instanz zugreifen kann, indem Sie den folgenden Befehl verwenden:

az postgres flexible-server firewall-rule delete \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $DB_SERVER_NAME \
    --rule-name $DB_SERVER_NAME-database-allow-local-ip \
    --yes

Bereinigen von Ressourcen

Zum Vermeiden von Azure-Gebühren sollten Sie nicht benötigte Ressourcen bereinigen. Wenn der Cluster nicht mehr benötigt wird, entfernen Sie mit dem Befehl az group delete die Ressourcengruppe, den Containerdienst, die Containerregistrierung und alle zugehörigen Ressourcen.

git reset --hard
docker rmi ${TODO_QUARKUS_TAG}:1.0
docker rmi postgres
az identity delete --ids ${UAMI_RESOURCE_ID}
az group delete --name $RESOURCE_GROUP_NAME --yes --no-wait

Mit docker rmi können Sie auch die Containerimages postgres und testcontainers löschen, die im Quarkus-Entwicklungsmodus generiert wurden.

Nächste Schritte