Esercitazione: Distribuire un'applicazione Spring Boot nel cluster del servizio Azure Kubernetes con Database di Azure per MySQL - Server flessibile in una rete virtuale
In questa esercitazione si apprenderà come distribuire un'applicazione Spring Boot in un cluster servizio Azure Kubernetes (AKS) con Che cos'è Database di Azure per MySQL - Server flessibile? nel back-end, comunicando in modo sicuro tra loro all'interno di una rete virtuale di Azure.
Nota
Questa esercitazione presuppone una conoscenza di base dei concetti di Kubernetes, Java Spring Boot e MySQL. Per le applicazioni Spring Boot, è consigliabile usare Azure Spring Apps. Tuttavia, è comunque possibile usare i servizi Azure Kubernetes come destinazione. Per consigli, vedere Indicazioni sulla destinazione del carico di lavoro Java.
Prerequisiti
- Una sottoscrizione di Azure Se non si ha una sottoscrizione di Azure, creare un account gratuito di Azure prima di iniziare. Attualmente, con un account gratuito di Azure, è possibile provare il server flessibile di Database MySQL di Azure gratuitamente per 12 mesi. Per altre informazioni, vedere Usare un account gratuito di Azure per provare gratuitamente Database di Azure per MySQL - Server flessibile.
- Interfaccia della riga di comando di Azure.
- Un'istanza supportata di Java Development Kit, versione 8 (inclusa in Azure Cloud Shell).
- Strumento di compilazione di Apache Maven.
- Un client Git.
- Un client Docker.
Creare un server flessibile di Database di Azure per MySQL
Creare un gruppo di risorse
Un gruppo di risorse di Azure è un gruppo logico in cui le risorse di Azure vengono distribuite e gestite. Verrà ora creato un gruppo di risorse rg-mysqlaksdemo usando il comando az group create nella posizione eastus.
Aprire il prompt dei comandi.
Accedere all'account di Azure.
az login
Scegliere la sottoscrizione di Azure.
az account set -s <your-subscription-ID>
Creare il gruppo di risorse.
az group create --name rg-mysqlaksdemo --location eastus
Creare un'istanza del server flessibile di Database di Azure per MySQL
Verrà ora creata un'istanza del server flessibile Database di Azure per MySQL in una rete virtuale (metodo di connettività di accesso privato).
Creare una rete virtuale di Azure vnet-mysqlaksdemo per tutte le risorse in questa esercitazione e una subnet subnet-mysql per l'istanza del server flessibile Database di Azure per MySQL.
az network vnet create \ --resource-group rg-mysqlaksdemo \ --name vnet-mysqlaksdemo \ --address-prefixes 155.55.0.0/16 \ --subnet-name subnet-mysql \ --subnet-prefix 155.55.1.0/24
Creare un'istanza del server flessibile Database di Azure per MySQL mysql-mysqlaksdemo nella subnet creata in precedenza usando il comando az mysql flexible-server create. Sostituire i valori per nome utente e password amministratore.
az mysql flexible-server create \ --name mysql-mysqlaksdemo \ --resource-group rg-mysqlaksdemo \ --location eastus \ --admin-user <your-admin-username> \ --admin-password <your-admin-password> \ --vnet vnet-mysqlaksdemo \ --subnet subnet-mysql
È stata creata un'istanza del server flessibile Database di Azure per MySQL nell'area eastus con risorse di calcolo B1MS con burstable B1MS, archiviazione da 32 GB, periodo di conservazione dei backup di 7 giorni e nella subnet fornita subnet-mysql. In questa subnet non devono essere distribuite altre risorse e verrà delegata a Microsoft.DBforMySQL/flexibleServers.
Configurare un nuovo database
demo
server flessibile Database di Azure per MySQL da usare con l'applicazione Spring Boot.az mysql flexible-server db create \ --resource-group rg-mysqlaksdemo \ --server-name mysql-mysqlaksdemo \ --database-name demo
Creare un Registro Azure Container
Creare un Registro Azure Container privato nel gruppo di risorse. Questa esercitazione effettua il push dell'app di esempio come immagine Docker in questo registro nei passaggi successivi. Sostituire mysqlaksdemoregistry
con un nome univoco da assegnare al registro.
az acr create --resource-group rg-mysqlaksdemo \
--location eastus \
--name mysqlaksdemoregistry \
--sku Basic
Codice dell'applicazione
In questa sezione verrà codificata l'applicazione demo. Per andare più velocemente, è possibile scaricare l'applicazione codificata disponibile in https://github.com/Azure-Samples/tutorial-springboot-mysql-aks e passare alla sezione successiva - Compilare l'immagine ed eseguire il push in Registro Azure Container.
Generare l'applicazione con Spring Initializr.
curl https://start.spring.io/starter.tgz \ -d dependencies=web,data-jdbc,mysql \ -d baseDir=springboot-mysql-aks \ -d bootVersion=2.5.6.RELEASE \ -d artifactId=springboot-mysql-aks \ -d description="Spring Boot on AKS connecting to Azure DB for MySQL" \ -d javaVersion=1.8 | tar -xzvf -
All'interno della cartella
springboot-mysql-aks
verrà generata un'applicazione Spring Boot di base.Usare l'editor di testo preferito, ad esempio VSCode o qualsiasi IDE per la procedura seguente.
Configurare Spring Boot per l'uso di Database di Azure per MySQL server flessibile.
Aprire il file src/main/resources/application.properties e aggiungere il frammento di codice seguente. Questo codice legge l'host del database, il nome del database, il nome utente e la password dal file manifesto Kubernetes.
logging.level.org.springframework.jdbc.core=DEBUG spring.datasource.url=jdbc:mysql://${DATABASE_HOST}:3306/${DATABASE_NAME}?serverTimezone=UTC spring.datasource.username=${DATABASE_USERNAME} spring.datasource.password=${DATABASE_PASSWORD} spring.datasource.initialization-mode=always
Avviso
La proprietà di configurazione
spring.datasource.initialization-mode=always
indica che Spring Boot genererà automaticamente a ogni avvio del server uno schema di database, usando il fileschema.sql
che verrà creato in un secondo momento. Questa proprietà è particolarmente adatta in un ambiente di test, ma è necessario ricordare che comporta l'eliminazione dei dati a ogni riavvio e quindi non dovrebbe essere usata nell'ambiente di produzione.Nota
Alla proprietà di configurazione
spring.datasource.url
verrà aggiunto?serverTimezone=UTC
, per indicare al driver JDBC di usare il formato di data UTC (o Coordinated Universal Time) per la connessione al database. In caso contrario, il server Java non userà lo stesso formato di data del database, causando un errore.Creare lo schema del database.
Spring Boot eseguirà automaticamente
src/main/resources/schema.sql
per creare uno schema di database. Creare tale file con il contenuto seguente:DROP TABLE IF EXISTS todo; CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);
Scrivere il codice dell'applicazione Java Spring Boot.
Aggiungere il codice Java che userà JDBC per archiviare e recuperare i dati dal server MySQL. Creare una nuova classe Java
Todo
accanto alla classeDemoApplication
e aggiungere il codice seguente:package com.example.springbootmysqlaks; import org.springframework.data.annotation.Id; public class Todo { public Todo() { } public Todo(String description, String details, boolean done) { this.description = description; this.details = details; this.done = done; } @Id private Long id; private String description; private String details; private boolean done; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getDetails() { return details; } public void setDetails(String details) { this.details = details; } public boolean isDone() { return done; } public void setDone(boolean done) { this.done = done; } }
Questa classe è un modello di dominio mappato alla tabella
todo
creata in precedenza.Per gestire tale classe, è necessario un repository. Definire una nuova interfaccia
TodoRepository
nello stesso pacchetto:package com.example.springbootmysqlaks; import org.springframework.data.repository.CrudRepository; public interface TodoRepository extends CrudRepository<Todo, Long> { }
Questo repository è un repository gestito da Spring Data JDBC.
Completare l'applicazione creando un controller in grado di archiviare e recuperare dati. Implementare una classe
TodoController
nello stesso pacchetto e aggiungere il codice seguente:package com.example.springbootmysqlaks; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/") public class TodoController { private final TodoRepository todoRepository; public TodoController(TodoRepository todoRepository) { this.todoRepository = todoRepository; } @PostMapping("/") @ResponseStatus(HttpStatus.CREATED) public Todo createTodo(@RequestBody Todo todo) { return todoRepository.save(todo); } @GetMapping("/") public Iterable<Todo> getTodos() { return todoRepository.findAll(); } }
Creare un nuovo Dockerfile nella directory di base springboot-mysql-aks e copiare questo frammento di codice.
FROM openjdk:8-jdk-alpine RUN addgroup -S spring && adduser -S spring -G spring USER spring:spring ARG DEPENDENCY=target/dependency COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib COPY ${DEPENDENCY}/META-INF /app/META-INF COPY ${DEPENDENCY}/BOOT-INF/classes /app ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.springbootmysqlaks.DemoApplication"]
Passare al file pom.xml e aggiornare la raccolta di
<properties>
nel file pom.xml con il nome del Registro Azure Container e la versione più recente dijib-maven-plugin
. Nota: se il nome del Registro Azure Container contiene caratteri maiuscoli, assicurarsi di convertirli in caratteri minuscoli.<properties> <docker.image.prefix>mysqlaksdemoregistry.azurecr.io</docker.image.prefix> <jib-maven-plugin.version>3.1.4</jib-maven-plugin.version> <java.version>1.8</java.version> </properties>
Aggiornare la raccolta
<plugins>
nel file pom.xml in modo che sia presente un elemento<plugin>
contenente una voce perjib-maven-plugin
, come illustrato di seguito. Viene usata un'immagine di base del Registro Contenitori Microsoft (MCR):mcr.microsoft.com/java/jdk:8-zulu-alpine
, che contiene un JDK ufficialmente supportato per Azure. Per altre immagini di base MCR con JDK supportati ufficialmente, vedere il Docker Hub.<plugin> <artifactId>jib-maven-plugin</artifactId> <groupId>com.google.cloud.tools</groupId> <version>${jib-maven-plugin.version}</version> <configuration> <from> <image>mcr.microsoft.com/java/jdk:8-zulu-alpine</image> </from> <to> <image>${docker.image.prefix}/${project.artifactId}</image> </to> </configuration> </plugin>
Compilare l'immagine ed eseguire il push in Registro Azure Container
Nel prompt dei comandi passare alla cartella springboot-mysql-aks ed eseguire i comandi seguenti per impostare prima il nome predefinito per Registro Azure Container (in caso contrario è necessario specificare il nome in az acr login
), compilare l'immagine e quindi eseguire il push dell'immagine nel registro.
Assicurarsi che il daemon Docker sia in esecuzione durante l'esecuzione di questo passaggio.
az config set defaults.acr=mysqlaksdemoregistry
az acr login && mvn compile jib:build
Creare un cluster Kubernetes nel servizio Azure Kubernetes
Verrà ora creato un cluster del servizio Azure Kubernetes nella rete virtuale vnet-mysqlaksdemo.
In questa esercitazione si userà la rete CNI di Azure nel servizio Azure Kubernetes. Se invece si vuole configurare la rete kubenet, vedere Usare la rete kubenet nel servizio Azure Kubernetes.
Creare una subnet subnet-aks del servizio Azure Kubernetes da usare.
az network vnet subnet create \ --resource-group rg-mysqlaksdemo \ --vnet-name vnet-mysqlaksdemo \ --name subnet-aks \ --address-prefixes 155.55.2.0/24
Ottenere l'ID risorsa della subnet.
SUBNET_ID=$(az network vnet subnet show --resource-group rg-mysqlaksdemo --vnet-name vnet-mysqlaksdemo --name subnet-aks --query id -o tsv)
Creare un cluster del servizio Azure Kubernetes nella rete virtuale, con Registro Azure Container mysqlaksdemoregistry collegato.
az aks create \ --resource-group rg-mysqlaksdemo \ --name aks-mysqlaksdemo \ --network-plugin azure \ --service-cidr 10.0.0.0/16 \ --dns-service-ip 10.0.0.10 \ --docker-bridge-address 172.17.0.1/16 \ --vnet-subnet-id $SUBNET_ID \ --attach-acr mysqlaksdemoregistry \ --dns-name-prefix aks-mysqlaksdemo \ --generate-ssh-keys
Durante il processo di creazione del cluster vengono definiti anche gli intervalli di indirizzi IP seguenti:
--service-cidr viene usato per assegnare un indirizzo IP ai servizi interni nel cluster del servizio Azure Kubernetes. È possibile usare qualsiasi intervallo di indirizzi privati che soddisfi i requisiti seguenti:
- Non deve essere compreso nell'intervallo di indirizzi IP della rete virtuale del cluster
- Non deve sovrapporsi ad altre reti virtuali con cui la rete virtuale del cluster effettua il peering
- Non deve sovrapporsi ad altri IP locali
- Non deve essere compreso negli intervalli 169.254.0.0/16, 172.30.0.0/16, 172.31.0.0/16 o 192.0.2.0/24
L'indirizzo --dns-service-ip è l'indirizzo IP per il servizio DNS del cluster. Questo indirizzo deve essere compreso nell'intervallo degli indirizzi del servizio Kubernetes. Non usare il primo indirizzo IP nell'intervallo di indirizzi. Il primo indirizzo nell'intervallo della subnet è usato per l'indirizzo kubernetes.default.svc.cluster.local.
--docker-bridge-address è l'indirizzo di rete del bridge Docker che rappresenta l'indirizzo di rete docker0 predefinito presente in tutte le installazioni Docker. È necessario selezionare uno spazio indirizzi che non si scontri con il resto dei CIDR nelle reti, incluso il CIDR del servizio del cluster e il CIDR del pod.
Distribuire l'applicazione nel cluster del servizio Azure Kubernetes
Passare alla risorsa cluster del servizio Azure Kubernetes nel portale di Azure.
Selezionare Aggiungi e Aggiungi con YAML da una delle visualizzazioni delle risorse (spazio dei nomi, carichi di lavoro, servizi e ingresso, archiviazione o configurazione).
Incollare il codice YAML seguente. Sostituire i valori per Database di Azure per MySQL nome utente e password dell'amministratore del server flessibile.
apiVersion: apps/v1 kind: Deployment metadata: name: springboot-mysql-aks spec: replicas: 1 selector: matchLabels: app: springboot-mysql-aks template: metadata: labels: app: springboot-mysql-aks spec: containers: - name: springboot-mysql-aks image: mysqlaksdemoregistry.azurecr.io/springboot-mysql-aks:latest env: - name: DATABASE_HOST value: "mysql-mysqlaksdemo.mysql.database.azure.com" - name: DATABASE_USERNAME value: "<your-admin-username>" - name: DATABASE_PASSWORD value: "<your-admin-password>" - name: DATABASE_NAME value: "demo" --- apiVersion: v1 kind: Service metadata: name: springboot-mysql-aks spec: type: LoadBalancer ports: - port: 80 targetPort: 8080 selector: app: springboot-mysql-aks
Selezionare Aggiungi nella parte inferiore dell'editor YAML per distribuire l'applicazione.
Dopo aver aggiunto il file YAML, il visualizzatore risorse mostra l'applicazione Spring Boot. Prendere nota dell'indirizzo IP esterno collegato incluso nel servizio esterno.
Testare l'applicazione
Per testare l'applicazione, è possibile usare cURL.
Creare prima di tutto un elemento "todo" nel database con il comando seguente.
curl --header "Content-Type: application/json" \
--request POST \
--data '{"description":"configuration","details":"congratulations, you have deployed your application correctly!","done": "true"}' \
http://<AKS-service-external-ip>
Recuperare quindi i dati usando una nuova richiesta cURL oppure immettendo il cluster IP esterno nel browser.
curl http://<AKS-service-external-ip>
Questo comando restituirà l'elenco di elementi "todo", incluso quello creato.
[{"id":1,"description":"configuration","details":"congratulations, you have deployed your application correctly!","done":true}]
Ecco uno screenshot di queste richieste cURL:
È possibile visualizzare un output simile tramite il browser:
Complimenti. È stata distribuita correttamente un'applicazione Spring Boot nel cluster servizio Azure Kubernetes (AKS) con Database di Azure per MySQL server flessibile nel back-end.
Pulire le risorse
Per evitare addebiti per Azure, è necessario eliminare le risorse non necessarie. Quando il cluster non è più necessario, usare il comando az group delete per rimuovere il gruppo di risorse, il servizio contenitore e tutte le risorse correlate.
az group delete --name rg-mysqlaksdemo
Nota
Quando si elimina il cluster, l'entità servizio Microsoft Entra usata dal cluster del servizio Azure Kubernetes non viene rimossa. Per istruzioni su come rimuovere l'entità servizio, vedere le considerazioni sull'entità servizio servizio Azure Kubernetes e la sua eliminazione. Se è stata usata un'identità gestita, l'identità viene gestita dalla piattaforma e non richiede la rimozione.