Esercizio - Ospitare un nuovo database con Azure Cosmos DB

Completato

Dopo aver esaminato i concetti di base degli stati esterni e come gestirli usando Kubernetes, è possibile creare le risorse che supportano l'applicazione della società di trasporto e quindi creare l'applicazione stessa.

Creare un gruppo di risorse

Importante

Per completare questo esercizio è necessaria una sottoscrizione di Azure propria e potrebbero essere applicati costi. Se non hai ancora una sottoscrizione di Azure, crea un account gratuito prima di iniziare.

  1. Accedere al portale di Azure usando la propria sottoscrizione.

  2. Aprire Cloud Shell e selezionare Bash.

  3. Creare un gruppo di risorse di Azure usando il az group create comando e specificare un'area. Questo esempio crea un gruppo di risorse denominato rg-ship-manager nell'area eastus :

    az group create --name rg-ship-manager --location eastus
    

    Il completamento del processo di creazione può richiedere alcuni istanti.

Creare lo stato

Come descritto in precedenza, è possibile ma non consigliabile gestire lo stato in Kubernetes. La gestione di uno stato dell'applicazione a disponibilità elevata può diventare troppo difficile quando è necessario gestire manualmente lo stato.

Per risolvere il problema, lo stato viene esternalizzato a un'applicazione specializzata nella gestione dello stato esterno: Azure Cosmos DB.

Annotazioni

Anche se si sta creando un'istanza di Azure Cosmos DB come parte delle risorse necessarie per eseguire l'applicazione, il servizio Azure Kubernetes e Azure Cosmos DB non sono correlati tra loro.

  1. Per Azure Cosmos DB, verificare che il provider delle risorse Microsoft.DocumentDB sia registrato nella sottoscrizione.

    az provider show --namespace Microsoft.DocumentDB --query "registrationState"
    

    Se l'output è NotRegistered, registrare il provider di risorse.

    az provider register --namespace Microsoft.DocumentDB
    
  2. Creare variabili Bash per archiviare il nome dell'account Azure Cosmos DB e il nome del gruppo di risorse da usare nel resto del modulo.

    export RESOURCE_GROUP=rg-ship-manager
    export COSMOSDB_ACCOUNT_NAME=contoso-ship-manager-$RANDOM
    
  3. Creare un nuovo account Azure Cosmos DB usando il az cosmosdb create comando .

    az cosmosdb create \
      --name $COSMOSDB_ACCOUNT_NAME \
      --resource-group $RESOURCE_GROUP \
      --kind MongoDB
    

    Il completamento del processo di creazione può richiedere alcuni istanti.

  4. Creare un nuovo database usando il az cosmosdb mongodb database create comando . In questo esempio il database è denominato contoso-ship-manager.

    az cosmosdb mongodb database create \
      --account-name $COSMOSDB_ACCOUNT_NAME \
      --resource-group $RESOURCE_GROUP \
      --name contoso-ship-manager
    
  5. Verificare che il database sia stato creato correttamente usando il az cosmosdb mongodb database list comando .

    az cosmosdb mongodb database list \
      --account-name $COSMOSDB_ACCOUNT_NAME \
      --resource-group $RESOURCE_GROUP \
      --output table
    

    L'output dovrebbe essere simile all'esempio di output seguente:

    Name                  ResourceGroup
    --------------------  ---------------
    contoso-ship-manager  rg-ship-manager
    

Dopo aver creato uno stato esterno per archiviare tutti i dati dall'applicazione di gestione delle navi, creiamo la risorsa AKS per archiviare l'applicazione stessa.

Creare il cluster del servizio Azure Kubernetes

  1. Per AKS, verificare che il provider di risorse Microsoft.ContainerService sia registrato nella sottoscrizione.

    az provider show --namespace Microsoft.ContainerService --query "registrationState"
    

    Se l'output è NotRegistered, registrare il provider di risorse.

    az provider register --namespace Microsoft.ContainerService
    
  2. Creare una variabile Bash per archiviare il nome del cluster da usare nel resto del modulo.

    AKS_CLUSTER_NAME=ship-manager-cluster
    
  3. Creare un cluster AKS usando il comando az aks create.

    az aks create --resource-group $RESOURCE_GROUP \
        --name $AKS_CLUSTER_NAME  \
        --node-count 3 \
        --generate-ssh-keys \
        --node-vm-size Standard_B2s \
        --enable-app-routing
    

    Il completamento del processo di creazione può richiedere alcuni istanti.

    Annotazioni

    Tutti i servizi di Azure impostano limiti e quote predefiniti per risorse e funzionalità, incluse le restrizioni di utilizzo per determinati SKU di macchine virtuali. Se si verifica un errore che suggerisce che lo SKU di macchina virtuale desiderato non è disponibile nell'area selezionata, è più probabile che sia necessario aumentare questa quota tramite una richiesta di supporto di Azure (per Tipo di problema selezionare Quota).

  4. Scaricare la configurazione di kubectl usando il az aks get-credentials comando .

    az aks get-credentials --name $AKS_CLUSTER_NAME --resource-group $RESOURCE_GROUP
    

    Se si ricevono messaggi relativi ai cluster esistenti, ad esempio:

    A different object named ship-manager-cluster already exists in your kubeconfig file.
    Overwrite? (y/n):
    

    Immettere y per sovrascrivere.

  5. Testare la configurazione usando il kubectl get nodes comando .

    kubectl get nodes
    

    L'output dovrebbe essere simile all'esempio di output seguente:

    NAME                                STATUS   ROLES    AGE    VERSION
    aks-nodepool1-12345678-vmss000000   Ready    <none>   107s   v1.33.7
    aks-nodepool1-12345678-vmss000001   Ready    <none>   104s   v1.33.7
    aks-nodepool1-12345678-vmss000002   Ready    <none>   107s   v1.33.7
    

Distribuire l'applicazione

Per creare l'applicazione, è necessario creare i file YAML da distribuire in Kubernetes. È possibile creare i file nel computer e quindi caricarli nella sessione Bash in Cloud Shell. Nella sessione di Cloud Shell selezionare Gestisci file>Carica.

Distribuire l'API back-end

  1. Esporta la stringa di connessione del database di Azure Cosmos DB in una variabile usando il comando az cosmosdb keys list.

    export COSMOS_CONNECTION_STRING=$(az cosmosdb keys list \
      --type connection-strings \
      --resource-group $RESOURCE_GROUP \
      --name $COSMOSDB_ACCOUNT_NAME \
      --query "connectionStrings[0].connectionString" --output tsv)
    

    Importante

    Non usare stringhe di connessione per un ambiente di produzione perché la stringa di connessione contiene informazioni riservate. Per altre informazioni, vedere la panoramica della sicurezza per Azure Cosmos DB.

  2. Creare un nuovo file denominato backend-deploy.yml e incollare la specifica di distribuzione seguente:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ship-manager-backend
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ship-manager-backend
      template:
        metadata:
          labels:
            app: ship-manager-backend
        spec:
          containers:
            - image: mcr.microsoft.com/mslearn/samples/contoso-ship-manager:backend
              name: ship-manager-backend
              resources:
                requests:
                  cpu: 100m
                  memory: 128Mi
                limits:
                  cpu: 250m
                  memory: 256Mi
              ports:
                - containerPort: 3000
                  name: http
              env:
                - name: DATABASE_MONGODB_URI
                  value: "${COSMOS_CONNECTION_STRING}"
                - name: DATABASE_MONGODB_DBNAME
                  value: contoso-ship-manager
    
  3. Salvare il file e caricarlo nella sessione di Cloud Shell selezionando Gestisci file>Carica.

  4. Applicare la distribuzione dell'API back-end usando il kubectl apply comando .

    envsubst '${COSMOS_CONNECTION_STRING}' < backend-deploy.yml | kubectl apply -f -
    

    Il comando usa envsubst per sostituire il ${COSMOS_CONNECTION_STRING} segnaposto nel file YAML con il valore della COSMOS_CONNECTION_STRING variabile di ambiente. Il trattino (-) alla fine del comando indica kubectl di leggere l'input dal flusso di input standard. Il valore della COSMOS_CONNECTION_STRING variabile non viene salvato nel file caricato in Cloud Shell.

    Verrà visualizzato un messaggio simile all'output di esempio seguente:

    deployment.apps/ship-manager-backend created
    

Per rendere disponibile questa applicazione a tutti, è necessario creare un servizio e un ingresso per gestire il traffico.

  1. Creare un nuovo file denominato backend-network.yml e incollarlo nella specifica di rete seguente:

    apiVersion: v1
    kind: Service
    metadata:
      name: ship-manager-backend
    spec:
      type: ClusterIP
      ports:
      - port: 80
        targetPort: 3000
      selector:
        app: ship-manager-backend
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ship-manager-backend
    spec:
      ingressClassName: webapprouting.kubernetes.azure.com
      rules:
      - host:
        http:
          paths:
          - backend:
              service:
                name: ship-manager-backend
                port:
                  number: 80
            path: /api
            pathType: Prefix
    
  2. Salvare il file e caricarlo nella sessione di Cloud Shell selezionando Gestisci file>Carica.

  3. Applica la distribuzione di rete back-end usando il comando kubectl apply.

    kubectl apply -f backend-network.yml
    

    L'output dovrebbe essere simile all'esempio di output seguente:

    service/ship-manager-backend created
    ingress.networking.k8s.io/ship-manager-backend created
    

    Questo ingresso instrada le richieste all'API back-end sul percorso /api.

  4. Controllare lo stato degli ingressi eseguendo una query su Kubernetes per gli ingressi disponibili usando il comando kubectl get ingress.

    kubectl get ingress
    

    Dopo aver compilato il campo ADDRESS nell'output, significa che l'ingresso è stato distribuito ed è pronto per l'accesso, come illustrato nell'output di esempio seguente:

    NAME                   CLASS                                HOSTS   ADDRESS        PORTS   AGE
    ship-manager-backend   webapprouting.kubernetes.azure.com   *       xx.xx.xx.xx    80      2m40s
    

    Il HOSTS valore è * dovuto al fatto che questo ingresso non specifica una host: regola. I nomi host in ingresso sono facoltativi. Quando si omette host:, l'ingress corrisponde alle richieste per qualsiasi nome host e si accede all'app utilizzando l'indirizzo dell'ingress ADDRESS.

  5. Archiviare l'indirizzo di ingresso in una variabile. Userai questo per la configurazione front-end.

    export HOST_NAME=$(kubectl get ingress ship-manager-backend -o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}')
    

Distribuire l'interfaccia front-end

  1. Creare un nuovo file denominato frontend-deploy.yml e incollarlo nella specifica di distribuzione seguente:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ship-manager-frontend
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ship-manager-frontend
      template:
        metadata:
          labels:
            app: ship-manager-frontend
        spec:
          containers:
            - image: mcr.microsoft.com/mslearn/samples/contoso-ship-manager:frontend
              name: ship-manager-frontend
              imagePullPolicy: Always
              resources:
                requests:
                  cpu: 100m
                  memory: 128Mi
                limits:
                  cpu: 250m
                  memory: 256Mi
              ports:
                - containerPort: 80
              volumeMounts:
                - name: config
                  mountPath: /usr/src/app/dist/config.js
                  subPath: config.js
          volumes:
            - name: config
              configMap:
                name: frontend-config
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: frontend-config
    data:
      config.js: |
        const config = (() => {
          return {
            'VUE_APP_BACKEND_BASE_URL': 'http://${HOST_NAME}',
          }
        })()
    
  2. Salvare il file e caricarlo nella sessione di Cloud Shell selezionando Gestisci file>Carica.

  3. Applicare la distribuzione front-end usando il comando kubectl apply.

    envsubst '${HOST_NAME}' < frontend-deploy.yml | kubectl apply -f -
    

    L'output dovrebbe essere simile all'esempio di output seguente:

    deployment.apps/ship-manager-frontend created
    configmap/frontend-config created
    

Successivamente, è possibile creare le risorse di rete necessarie per aprire l'applicazione al Web.

  1. Creare un nuovo file denominato frontend-network.yml e incollarlo nella specifica di rete seguente:

    apiVersion: v1
    kind: Service
    metadata:
      name: ship-manager-frontend
    spec:
      type: ClusterIP
      ports:
      - port: 80
        targetPort: 80
      selector:
        app: ship-manager-frontend
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ship-manager-frontend
    spec:
      ingressClassName: webapprouting.kubernetes.azure.com
      rules:
      - host:
        http:
          paths:
          - backend:
              service:
                name: ship-manager-frontend
                port:
                  number: 80
            path: /
            pathType: Prefix
    
  2. Salvare il file e caricarlo nella sessione di Cloud Shell selezionando Gestisci file>Carica.

  3. Applicare la distribuzione di rete front-end usando il kubectl apply comando .

    kubectl apply -f frontend-network.yml
    

    L'output dovrebbe essere simile all'esempio di output seguente:

    service/ship-manager-frontend created
    ingress.networking.k8s.io/ship-manager-frontend created
    

    È possibile accedere all'applicazione nel browser usando http://$HOST_NAME. Eseguire echo $HOST_NAME per visualizzare il valore della HOST_NAME variabile.

  4. Controllare lo stato degli ingressi eseguendo una query su Kubernetes per gli ingressi disponibili usando il comando kubectl get ingress.

    kubectl get ingress
    

    Quando viene compilato il campo ADDRESS nell'output, significa che l'ingresso è stato distribuito ed è pronto per l'accesso, come illustrato nell'output di esempio seguente:

    NAME                   CLASS                                HOSTS   ADDRESS        PORTS   AGE
    ship-manager-backend   webapprouting.kubernetes.azure.com   *       xx.xx.xx.xx    80      2m40s
    ship-manager-frontend  webapprouting.kubernetes.azure.com   *       xx.xx.xx.xx    80      100s
    

    È ora possibile accedere all'applicazione all'indirizzo http://$HOST_NAME.

Ripristinare le variabili

È consigliabile cancellare i valori delle variabili, soprattutto quando contengono dati sensibili come la stringa di connessione del database.

unset COSMOS_CONNECTION_STRING