Tutorial: Distribuire un'applicazione Spring Boot in un cluster AKS con Database di Azure per MySQL - Flexible Server in una VNet

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

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.

  1. Aprire il prompt dei comandi.

  2. Accedere all'account di Azure.

    az login
    
  3. Scegliere la sottoscrizione di Azure.

    az account set -s <your-subscription-ID>
    
  4. 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).

  1. Creare una rete virtuale di Azure vnet-mysqlaksdemo per tutte le risorse di questa esercitazione e una subnet subnet-mysql per l'istanza di Database di Azure per MySQL Flexible Server.

    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
    
  2. Creare un'istanza di Database di Azure per MySQL - Server flessibile mysql-mysqlaksdemo nella subnet creata in precedenza, usando il comando az mysql flexible-server create. Sostituisci i valori di nome utente e la password dell'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 ora creata un'istanza di Database di Azure per MySQL - Flexible Server nell'area eastus con calcolo Burstable B1MS, 32 GB di archiviazione, un 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.

  3. Configurare un nuovo database demo del Server flessibile Database di Azure per MySQL da utilizzare 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 contenitori di Azure

Creare un Registro Azure Container privato nel gruppo di risorse. Questa esercitazione carica l'app di esempio come immagine Docker in questo registro nei passaggi seguenti. 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. Se vuoi fare più in fretta, puoi scaricare l'applicazione già pronta disponibile all'indirizzo https://github.com/Azure-Samples/tutorial-springboot-mysql-aks e passare alla sezione successiva: Creare l'immagine e inviarla ad Azure Container Registry.

  1. 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.

  2. Configurare Spring Boot per usare Database di Azure per MySQL - Flexible Server.

    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 file schema.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 ?serverTimezone=UTC verrà aggiunto spring.datasource.url, 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.

  3. 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);
    
  4. 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 classe DemoApplication 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();
        }
    }
    
  5. 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"]
    
  6. 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 di jib-maven-plugin. Nota: se il nome dell'ACR 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>
    
  7. Aggiornare la raccolta <plugins> nel file pom.xml in modo che sia presente un elemento <plugin> contenente una voce per jib-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>
    

Creare l'immagine e pubblicarla in Azure Container Registry

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 in AKS

Ora creeremo un cluster AKS nella rete virtuale vnet-mysqlaksdemo.

In questa esercitazione useremo la rete Azure CNI in AKS. Se si desidera invece configurare la rete kubenet, vedere Usare la rete kubenet in AKS.

  1. Creare una subnet subnet-aks da utilizzare per il cluster AKS.

    az network vnet subnet create \
    --resource-group rg-mysqlaksdemo \
    --vnet-name vnet-mysqlaksdemo \
    --name subnet-aks \
    --address-prefixes 155.55.2.0/24
    
  2. Ottieni l'ID della risorsa subnet.

    SUBNET_ID=$(az network vnet subnet show --resource-group rg-mysqlaksdemo --vnet-name vnet-mysqlaksdemo --name subnet-aks --query id -o tsv)
    
  3. Creare un cluster AKS nella rete virtuale, con Registro Azure Container (ACR) mysqlaksdemoregistry associato.

        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 utilizzato per assegnare un indirizzo IP ai servizi interni nel cluster AKS. È 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 di subnet viene utilizzato 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 di indirizzamento che non entri in conflitto con il resto dei CIDR nelle tue reti, inclusi il CIDR dei servizi del cluster e il CIDR dei pod.

Distribuisci l'applicazione nel cluster AKS

  1. Passa alla risorsa del cluster AKS nel portale di Azure.

  2. Selezionare Aggiungi e Aggiungi con YAML da una delle visualizzazioni delle risorse (spazio dei nomi, carichi di lavoro, servizi e ingresso, archiviazione o configurazione).

    Screenshot che mostra la visualizzazione delle risorse del servizio Azure Kubernetes nel portale di Azure.

  3. Incollare il codice YAML seguente. Sostituisci i valori con il nome utente amministratore e la password di Database di Azure per MySQL - Flexible Server.

    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
    
  4. Selezionare Aggiungi nella parte inferiore dell'editor YAML per distribuire l'applicazione.

    Screenshot che mostra l'opzione Aggiungi con l'editor YAML.

  5. 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.

    Screenshot che mostra la visualizzazione del portale di Azure dell'indirizzo IP esterno del servizio cluster Azure Kubernetes.

Testare l'applicazione

Per testare l'applicazione, è possibile usare cURL.

Per prima cosa, crea una nuova voce "todo" nel database utilizzando 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 degli elementi "todo", incluso quello che hai creato.

[{"id":1,"description":"configuration","details":"congratulations, you have deployed your application correctly!","done":true}]

Ecco uno screenshot di queste richieste cURL: Screenshot che mostra l'output della riga di comando delle richieste cURL.

È possibile visualizzare un output simile tramite il browser: Screenshot che mostra l'output della richiesta del browser.

Complimenti. Hai distribuito correttamente un'applicazione Spring Boot in un cluster di Servizio Azure Kubernetes (AKS) con Database di Azure per MySQL - Server flessibile come 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 di Microsoft Entra usata dal cluster AKS non viene rimossa. Per i passaggi su come rimuovere l'entità servizio, vedere Considerazioni ed eliminazione dell'entità servizio di AKS. Se è stata usata un'identità gestita, l'identità viene gestita dalla piattaforma e non richiede la rimozione.