Esercitazione: Distribuire un'applicazione Spring Boot nel cluster del servizio Azure Kubernetes con Database di Azure per MySQL - Server flessibile in una rete virtuale

SI APPLICA A: Database di Azure per MySQL - Server flessibile

In questa esercitazione si apprenderà come distribuire un'applicazione Spring Boot in un cluster servizio Azure Kubernetes (AKS) con 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 servizio 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. Si creerà ora un gruppo di risorse rg-mysqlaksdemo usando il comando az group create nella località 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 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 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 
    
  2. 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. Questa subnet non deve avere altre risorse distribuite e verrà delegata a Microsoft.DBforMySQL/flexibleServers.

  3. 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 esegue 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. Se si vuole andare più velocemente, è possibile scaricare l'applicazione codificata disponibile all'indirizzo 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.

  1. Generare l'applicazione usando 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 springboot-mysql-aks cartella 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 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 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 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.

  3. Creare lo schema del database.

    Spring Boot verrà eseguito src/main/resources/schema.sql automaticamente 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 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 <properties> raccolta nel file pom.xml con il nome del Registro di sistema per il Registro Azure Container e la versione più recente di jib-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>
    
  7. Aggiornare la <plugins> raccolta nel file pom.xml in modo che sia presente un elemento contenente una <plugin> voce per jib-maven-plugin, come illustrato di seguito. Si noti che si sta usando un'immagine di base di Microsoft Container Registry, mcr.microsoft.com/java/jdk:8-zulu-alpine, che contiene una versione di JDK supportata ufficialmente per Azure. Per altre immagini di base MCR con JDK supportati ufficialmente, vedere l'hub Docker.

    <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 di sistema.

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. Per configurare invece la rete kubenet, vedere Usare la rete kubenet nel servizio Azure Kubenet.

  1. Creare un servizio Azure Kubernetes subnet per il cluster 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
    
  2. 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)
    
  3. Creare un cluster del servizio Azure Kubernetes nella rete virtuale, con Registro Azure Container (ACR) 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.

    • L'indirizzo --docker-bridge-address è l'indirizzo di rete del bridge Docker che rappresenta l'indirizzo di rete bridge docker0 predefinito presente in tutte le installazioni Docker. È necessario selezionare uno spazio indirizzi che non si scontra 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

  1. Passare alla risorsa cluster del servizio Azure Kubernetes 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 servizio Azure Kubernetes visualizzazione delle risorse in portale di Azure.

  3. 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
    
  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 portale di Azure visualizzazione dell'indirizzo IP esterno del servizio cluster Azure Kubernetes.

Testare l'applicazione

Per testare l'applicazione, è possibile usare cURL.

Creare prima di tutto un nuovo elemento "todo" nel database usando 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 o immettendo l'indirizzo IP esterno del cluster nel browser.

curl http://<AKS-service-external-ip>

Questo comando restituirà l'elenco di elementi "todo", incluso l'elemento 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. È stata distribuita correttamente un'applicazione Spring Boot in servizio Azure Kubernetes cluster del servizio Azure Kubernetes 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.

Passaggi successivi