Distribuisci l'immagine del container in servizio Azure Kubernetes
In questa unità si distribuisce un'immagine del contenitore in Servizio Azure Kubernetes (AKS). Con il servizio Azure Kubernetes si configura il cluster Kubernetes per l'esecuzione in uno stato desiderato tramite un Deployment, ovvero il processo di fornitura di aggiornamenti dichiarativi ai pod e ai set di repliche. Questa dichiarazione di stato è definita nel file YAML del manifesto e il controller Kubernetes modifica lo stato corrente nello stato dichiarato quando richiesto. Creare questo file manifest deployment.yml e indicare all'istanza di AKS di funzionare nello stato desiderato con pod configurati per eseguire il pull ed eseguire l'immagine flightbookingsystemsample del contenitore contenuta nel Registro Azure Container di cui è stato eseguito il push nell'unità precedente. Questo manifest definisce in modo dichiarativo un Deployment e un servizio. Kubernetes usa il controller Deployment per gestire i pod dell'applicazione; è anche possibile creare un Deployment in modo imperativo con kubectl create deployment.
Annotazioni
Se la sessione è inattiva o si esegue questo passaggio in un altro momento o da un'altra interfaccia della riga di comando, potrebbe essere necessario reinizializzare le variabili di ambiente e ripetere l'autenticazione usando i comandi seguenti:
Ripristinare i valori delle variabili di risorse usati nella configurazione. Sostituire <your-subscription-ID> di seguito con l'ID della sottoscrizione usata per questo modulo. Se l'accesso presenta un selettore di abbonamento, scegliere lo stesso abbonamento. Eseguire i comandi di autenticazione uno alla volta. Dopo az account show, verificare che la sottoscrizione attiva corrisponda alla configurazione prima di continuare. Se un comando non riesce, arrestare e risolvere l'errore.
export AZ_RESOURCE_GROUP=java-containerization-demo-rg
export AZ_CONTAINER_REGISTRY=<your-container-registry>
export AZ_KUBERNETES_CLUSTER=java-containerization-demo-aks
export AZ_LOCATION=<your-Azure-region>
export AZ_KUBERNETES_CLUSTER_DNS_PREFIX=<your-unique-DNS-prefix-to-access-your-AKS-cluster>
az login
az account set --subscription "<your-subscription-ID>"
az account show --output table
az acr login --name "$AZ_CONTAINER_REGISTRY"
Distribuire un'immagine del container
Ora si distribuisce l'immagine del flightbookingsystemsample contenitore nel cluster AKS. In containerize-and-deploy-Java-app-to-Azure/Project/Airlines, usare un editor di testo installato per creare un file denominato deployment.yml. Questo percorso è relativo alla directory padre in cui è stato clonato il repository. Se si è già in Project/Airlines, rimanere lì invece di passare nuovamente al percorso completo. Creare il file ed eseguire il comando seguente kubectl apply -f deployment.yml da questa directory.
Aggiungere il contenuto seguente a deployment.yml e quindi salvare il file. Sostituire il <AZ_CONTAINER_REGISTRY> segnaposto con il valore della AZ_CONTAINER_REGISTRY variabile di ambiente impostata in precedenza.
apiVersion: apps/v1
kind: Deployment
metadata:
name: flightbookingsystemsample
spec:
replicas: 1
selector:
matchLabels:
app: flightbookingsystemsample
template:
metadata:
labels:
app: flightbookingsystemsample
spec:
nodeSelector:
kubernetes.io/os: linux
kubernetes.io/arch: amd64
containers:
- name: flightbookingsystemsample
image: <AZ_CONTAINER_REGISTRY>.azurecr.io/flightbookingsystemsample:latest
resources:
requests:
cpu: "1"
memory: "1Gi"
limits:
cpu: "2"
memory: "2Gi"
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: flightbookingsystemsample
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: 8080
selector:
app: flightbookingsystemsample
Annotazioni
Se si usa il file deployment_solution.yml nella cartella radice del progetto come punto di partenza, aggiornarne l'immagine alla stessa immagine del registro e :latest tag allo stesso tag mostrato qui. Aggiungere anche lo stesso Linux AMD64 nodeSelector sotto spec.template.spec di Deployment, insieme a containers. Non usare l'alternativa non modificata: l'immagine e il selettore di nodi devono corrispondere alla piattaforma di compilazione di questo modulo.
Nel file deployment.yml precedente sono presenti un deployment e un servizio. Il Deployment viene usato per amministrare un set di pod e il servizio viene usato per consentire l'accesso di rete ai pod. I pod sono configurati per eseguire il pull di una singola immagine, <AZ_CONTAINER_REGISTRY>.azurecr.io/flightbookingsystemsample:latest, da Registro Azure Container. Il servizio è configurato per consentire il traffico HTTP in ingresso dei pod verso la porta 8080, in modo analogo al modo in cui hai eseguito localmente l'immagine del contenitore con l'argomento di porta -p.
Il selettore di nodo limita i pod ai nodi Linux AMD64, compatibili con l'immagine linux/amd64 compilata in precedenza. Appartiene al Deployment, non al Service. Un selettore limita la pianificazione; non fa eseguire un'immagine incompatibile su un'altra architettura.
Prima di configurare l'accesso al cluster, assicurarsi che la creazione del cluster AKS nell'unità di configurazione sia stata completata correttamente. Controllare il relativo stato di provisioning e la versione corrente di Kubernetes:
az aks show \
--resource-group "$AZ_RESOURCE_GROUP" \
--name "$AZ_KUBERNETES_CLUSTER" \
--query '{provisioningState:provisioningState,currentKubernetesVersion:currentKubernetesVersion}' \
--output table
Non continuare se il comando non riesce, provisioningState non è currentKubernetesVersion, o major.minor.patch non è una versione non vuota in formato Succeeded.
Le istruzioni dello strumento seguenti si applicano alla sessione locale di Linux, macOS o WSL Bash stabilita nell'installazione, non al Prompt dei comandi o PowerShell nativo. Se in quella sessione sono già presenti le installazioni kubectl e kubelogin, conservarle invece di reinstallarle. Controllarli con kubectl version --client e kubelogin --version, e assicurarsi che kubectl soddisfi i criteri supportati per la differenza di versione per il cluster.
In caso contrario, sostituire <control-plane-version> con l'oggetto restituito currentKubernetesVersion. Installare la versione corrispondente kubectl e kubelogin in percorsi scrivibili dall'utente:
KUBECTL_VERSION="<control-plane-version>"
if [[ "$KUBECTL_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
mkdir -p "$HOME/.local/bin" &&
az aks install-cli \
--client-version "$KUBECTL_VERSION" \
--install-location "$HOME/.local/bin/kubectl" \
--kubelogin-install-location "$HOME/.local/bin/kubelogin" &&
export PATH="$HOME/.local/bin:$PATH" &&
kubectl version --client &&
kubelogin --version
else
printf 'Stop: set KUBECTL_VERSION to the returned major.minor.patch version.\n' >&2
false
fi
Entrambi i percorsi di installazione includono il nome file eseguibile. L'esportazione PATH si applica solo alla shell corrente. Ripetere l'esportazione in una nuova sessione o aggiungerla alla configurazione di avvio Bash appropriata. Risolvere eventuali errori di installazione o controllo della versione prima di continuare.
Dopo che entrambi gli strumenti sono disponibili e verificati, configurare kubectl per connettersi al cluster del servizio Azure Kubernetes:
az aks get-credentials \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_KUBERNETES_CLUSTER
L'output seguente è tipico:
Merged AZ_KUBERNETES_CLUSTER as current context in ~/.kube/config
Controllare i sistemi operativi e le architetture dei nodi effettivi prima di applicare il manifest:
kubectl get nodes \
-o custom-columns='NAME:.metadata.name,OS:.status.nodeInfo.operatingSystem,ARCH:.status.nodeInfo.architecture'
Il percorso di compilazione di linux/amd64 questo modulo richiede nodi LINUX AMD64. Se non sono presenti nodi corrispondenti, arrestare e risolvere la mancata corrispondenza prima di continuare. Usare un pool di nodi AMD64 supportato o ricompilare, eseguire ed eseguire il push dell'immagine per un'altra architettura del nodo Linux supportata e aggiornare il selettore dell'architettura del Deployment in modo che corrisponda. L'opzione Docker --platform non crea né modifica un pool di nodi di AKS.
Da containerize-and-deploy-Java-app-to-Azure/Project/Airlines, applica deployment.yml al cluster:
kubectl apply -f deployment.yml
L'output seguente è tipico:
deployment.apps/flightbookingsystemsample created
service/flightbookingsystemsample created
Monitorare lo stato della distribuzione usando il comando seguente:
kubectl get all
L'output seguente è tipico:
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/flightbookingsystemsample-b7fd6684f-4j8vf 1/1 Running 0 37s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/flightbookingsystemsample LoadBalancer 10.0.62.153 <external-IP> 8080:30534/TCP 37s
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 11h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/flightbookingsystemsample 1/1 1 1 37s
NAME DESIRED CURRENT READY AGE
replicaset.apps/flightbookingsystemsample-b7fd6684f 1 1 1 37s
Lo stato di un pod Running non conferma che Tomcat abbia completato la distribuzione dell'applicazione o che le richieste HTTP abbiano esito positivo. Attendere il rollout del deployment, quindi seguire i log di avvio dell'applicazione:
kubectl rollout status deployment/flightbookingsystemsample --timeout=300s &&
kubectl logs deployment/flightbookingsystemsample --tail=100 --follow
Una distribuzione riuscita verifica la disponibilità di Kubernetes. Poiché questo manifest non dispone di probe di readiness dell'applicazione, la distribuzione non è un test di integrità HTTP. Seguire i log fino a quando Tomcat non segnala il completamento dell'avvio del server e che la distribuzione di AirlinesReservationSample.war sia stata completata senza errori. Quindi premi Ctrl+C per interrompere la visualizzazione dei log. In questo modo viene arrestato solo il flusso di log, non il contenitore. Se l'implementazione o l'avvio dell'applicazione ha esito negativo o non viene completato, esaminare i log e gli eventi del pod anziché continuare con il controllo del browser.
L'output storico seguente illustra i messaggi di avvio di un'immagine Tomcat 10.1.33 precedente. Non è l'output dell'immagine aggiornata in questo modulo; usare i propri log per verificare l'avvio anziché prevedere le stesse versioni, timestamp o dettagli dell'ambiente:
kubectl logs pod/flightbookingsystemsample-b7fd6684f-4j8vf
15-Nov-2024 12:31:51.208 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/10.1.33
15-Nov-2024 12:31:51.211 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Nov 7 2024 22:28:55 UTC
15-Nov-2024 12:31:51.212 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 10.1.33.0
15-Nov-2024 12:31:51.212 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Linux
15-Nov-2024 12:31:51.212 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 5.15.0-1074-azure
15-Nov-2024 12:31:51.212 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64
15-Nov-2024 12:31:51.216 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /usr/lib/jvm/msopenjdk-17
15-Nov-2024 12:31:51.216 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 17.0.13+11-LTS
15-Nov-2024 12:31:51.216 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Microsoft
15-Nov-2024 12:31:51.216 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /usr/local/tomcat
15-Nov-2024 12:31:51.216 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /usr/local/tomcat
15-Nov-2024 12:31:51.226 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
15-Nov-2024 12:31:51.226 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
15-Nov-2024 12:31:51.227 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
15-Nov-2024 12:31:51.227 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
15-Nov-2024 12:31:51.227 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
15-Nov-2024 12:31:51.227 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
15-Nov-2024 12:31:51.228 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
15-Nov-2024 12:31:51.228 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util=ALL-UNNAMED
15-Nov-2024 12:31:51.228 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
15-Nov-2024 12:31:51.229 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
15-Nov-2024 12:31:51.229 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
15-Nov-2024 12:31:51.229 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
15-Nov-2024 12:31:51.229 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
15-Nov-2024 12:31:51.231 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The Apache Tomcat Native library which allows using OpenSSL was not found on the java.library.path: [/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib]
15-Nov-2024 12:31:51.565 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
15-Nov-2024 12:31:51.602 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [616] milliseconds
15-Nov-2024 12:31:51.658 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
15-Nov-2024 12:31:51.659 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/10.1.33]
15-Nov-2024 12:31:51.689 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat/webapps/AirlinesReservationSample.war]
15-Nov-2024 12:31:53.264 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
15-Nov-2024 12:31:55.155 INFO [main] com.sun.xml.ws.server.MonitorBase.createRoot Metro monitoring rootname successfully set to: com.sun.metro:pp=/,type=WSEndpoint,name=/AirlinesReservationSample-PriceAndSeats-PriceAndSeatsPort
15-Nov-2024 12:31:55.347 INFO [main] com.sun.xml.ws.transport.http.servlet.WSServletDelegate.<init> WSSERVLET14: XML-WS servlet initializing
WARNING:Error in the metadata of the table SEATS: table's row count in the metadata is 5 but 6 records have been found and loaded by UCanAccess. All will work fine, but it's better to repair your database.
15-Nov-2024 12:31:56.248 INFO [main] com.sun.xml.ws.transport.http.servlet.WSServletContextListener.contextInitialized WSSERVLET12: XML-WS context listener initializing
15-Nov-2024 12:31:56.249 INFO [main] com.sun.xml.ws.transport.http.servlet.WSServletContextListener.contextInitialized WSSERVLET12: XML-WS context listener initializing
15-Nov-2024 12:31:56.284 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat/webapps/AirlinesReservationSample.war] has finished in [4,595] ms
15-Nov-2024 12:31:56.285 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/docs]
15-Nov-2024 12:31:56.315 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/docs] has finished in [30] ms
15-Nov-2024 12:31:56.316 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/examples]
15-Nov-2024 12:31:56.439 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/examples] has finished in [123] ms
15-Nov-2024 12:31:56.440 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/manager]
15-Nov-2024 12:31:56.456 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/manager] has finished in [16] ms
15-Nov-2024 12:31:56.457 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/ROOT]
15-Nov-2024 12:31:56.468 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/ROOT] has finished in [11] ms
15-Nov-2024 12:31:56.468 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/host-manager]
15-Nov-2024 12:31:56.481 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/host-manager] has finished in [13] ms
15-Nov-2024 12:31:56.484 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
15-Nov-2024 12:31:56.501 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [4897] milliseconds
Monitorare il servizio per il suo indirizzo esterno:
kubectl get service flightbookingsystemsample --watch
Il EXTERNAL-IP valore può essere <pending> inizialmente mentre Azure effettua il provisioning del servizio di bilanciamento del carico. L'operazione può richiedere alcuni minuti e non indica di per sé che la distribuzione non è riuscita. Quando viene visualizzato un indirizzo, premere Ctrl+C per interrompere il monitoraggio. Se il provisioning non viene completato, arrestare il watch ed esaminare gli eventi del servizio con kubectl describe service flightbookingsystemsample.
L'output illustrativo seguente mostra dove viene visualizzato l'indirizzo assegnato:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
flightbookingsystemsample LoadBalancer 10.0.62.153 <external-IP> 8080:30534/TCP 3m28s
Annotazioni
Sostituire l'indirizzo IP <external-IP> nell'URL seguente con il tuo valore EXTERNAL-IP del comando eseguito in precedenza:
Aprire un browser e visitare la pagina di destinazione Flight Booking System Sample all'indirizzo http://<external-IP>:8080/AirlinesReservationSample/. Verificare che la pagina dell'applicazione risponda; Un Running pod o un indirizzo IP assegnato da solo non dimostra l'idoneità dell'applicazione. Il browser dovrebbe essere simile allo screenshot seguente:
Facoltativamente, è possibile accedere con uno qualsiasi degli utenti definiti in tomcat-users.xml, ad esempio someuser@azure.com: password.
Risolvere i problemi relativi a un'incompatibilità tra immagine e piattaforma
Per gli errori di avvio dei pod, esaminare kubectl describe pods -l app=flightbookingsystemsample, kubectl logs deployment/flightbookingsystemsample --tail=100e kubectl get events --sort-by=.metadata.creationTimestamp. Uno CrashLoopBackOff stato può avere diverse cause, inclusi gli errori dell'applicazione. Non presupporre che ogni guasto sia una mancata corrispondenza dell'architettura.
Se si verifica che un'immagine già distribuita abbia la piattaforma errata, ripetere prima di tutto la compilazione, l'esecuzione locale, l'ispezione delle immagini, l'assegnazione di tag al registro e i passaggi di push con le impostazioni della piattaforma corrispondenti. Dopo che l'immagine corretta è stata ricompilata, a cui è stato riassegnato lo stesso :latest tag e pubblicata, sostituire in modo esplicito i pod in esecuzione:
kubectl rollout restart deployment/flightbookingsystemsample &&
kubectl rollout status deployment/flightbookingsystemsample --timeout=300s
Per questo manifest, :latest l'impostazione predefinita è imagePullPolicy: Always, quindi i pod sostitutivi risolvono il tag del registry corrente. La riapplicazione di un manifest non modificato da sola non attiva una distribuzione. Se è stato personalizzato il criterio di pull dell'immagine, usare un tag immagine aggiornato o un digest e aggiornare invece il Deployment. Ripetere i controlli del log di avvio e dell'URL dell'applicazione dopo l'implementazione.
Pulire le risorse
Le risorse create in questo modulo potrebbero comportare costi continui. Per pulire le risorse, eliminare il gruppo di risorse che li contiene usando il comando seguente:
az group delete --name $AZ_RESOURCE_GROUP