Questo esempio avanzato mostra come creare un'app di registro che utilizza Node.js per il frontend e MySQL per il backend. Il modello crea e connette anche un bilanciatore del carico HTTP che bilancia il carico su due zone e uno strumento di scalabilità automatica per scalare automaticamente l'app.
Questo esempio presuppone che tu abbia familiarità con i container Docker, nonché con le risorse di Compute Engine, in particolare il bilanciamento del carico HTTP, la scalabilità automatica, i gruppi di istanze gestite e i modelli di istanza.
Per altri tutorial introduttivi, consulta la Guida introduttiva o la Guida passo passo.
Prima di iniziare
- Se vuoi utilizzare gli esempi di riga di comando in questa guida, installa lo strumento a riga di comando`gcloud`.
- Se vuoi utilizzare gli esempi di API in questa guida, configura l'accesso API.
- Familiarità con il bilanciamento del carico HTTP di Compute Engine.
- Avere familiarità con i container Docker.
Creare i modelli
Questo esempio avvia un deployment con diversi tipi di risorse. Per iniziare, crea modelli riutilizzabili che definiscono queste risorse separatamente. In un secondo momento, utilizzerai questi modelli nella configurazione finale.
Al termine di questo esempio, avrai un deployment che contiene queste risorse:
- Una singola istanza di Compute Engine per la macchina virtuale MySQL di backend.
- Un modello di istanza che utilizza un'immagine Docker.
- Due gruppi di istanze gestite con scalabilità automatica in due zone diverse, che eseguono il servizio Node.js frontend.
- Altri due gruppo di istanze gestite con scalabilità automatica che pubblicano dati statici.
- Un controllo di integrità e un bilanciatore del carico HTTP per distribuire il traffico nei rispettivi gruppi di istanze gestite.
Creazione dei modelli di backend
Il backend di questa app è una singola istanza Compute Engine che esegue un container Docker MySQL. Crea un modello che definisce un'istanza Compute Engine
che utilizza un'immagine ottimizzata per i container. Assegna al file il nome container_vm.[py|jinja]
:
Jinja
Python
Il modello definisce una serie di variabili, come containerImage
e
manifest
, che verranno compilate quando definisci la
configurazione. Questo modello crea una sola istanza di macchina virtuale (VM).
Quando utilizzi immagini container sulle istanze Compute Engine, devi anche
fornire un file manifest (diverso da un manifest Deployment Manager) per
descrivere a Compute Engine quale immagine container utilizzare. Crea un metodo helper
denominato container_helper.[py|jinja]
per definire dinamicamente il manifest
del contenitore:
Jinja
Python
Creazione dei modelli di frontend
Il frontend di questa app esegue Node.js e consente agli utenti di pubblicare messaggi sulla pagina web. Ci saranno due gruppi di istanze gestite contenenti due istanze ciascuno: un gruppo di istanze gestite principale e un gruppo di istanze gestite secondario per il bilanciamento del carico.
Per creare questi modelli frontend, segui le istruzioni riportate di seguito.
Creare un modello di istanza.
Per creare un gruppo di istanze gestite, che è un gruppo di istanze VM identiche gestite centralmente, è necessaria una risorsa modello di istanza. Questo esempio crea un gruppo di istanze gestite per le istanze frontend di Node.js, ma prima devi creare il modello di istanza.
Definisci un file denominato
container_instance_template.[py|jinja]
:Jinja
Python
Crea un gruppo di istanze gestite con scalabilità automatica.
Ora che hai un modello di istanza, puoi definire un modello che utilizza il modello di istanza per creare un gruppo di istanze gestite con scalabilità automatica. Crea un nuovo file denominato
autoscaled_group.[py|jinja]
con i seguenti contenuti:Jinja
Python
Crea il file dello schema corrispondente:
Jinja
Python
Crea risorse utilizzando questi modelli.
Fino a questo punto, hai definito i modelli di base che determinano le proprietà delle tue risorse. Utilizzando questi modelli, definisci la configurazione del frontend. Crea un nuovo file denominato
service.[py|jinja]
con i seguenti contenuti:Jinja
Python
Crea il file dello schema corrispondente:
Jinja
Python
Analizziamo nel dettaglio cosa crea questo modello:
Due gruppi di istanze gestite, uno primario e uno secondario.
Il modello utilizza il modello
autoscaled_group.[py|jinja]
per creare un gruppo di istanze gestite con scalabilità automatica primario e secondario.Successivamente, il modello crea un servizio di backend e un controllo di integrità. Un servizio di backend è necessario per il bilanciamento del carico HTTP e definisce la capacità di gestione dei gruppi di istanze in quel servizio di backend. In questo caso, i gruppi di istanze gestite primario e secondario fanno parte di questo backend e vengono applicate le proprietà predefinite del servizio di backend.
Per impostazione predefinita, un servizio di backend esegue il bilanciamento del carico in base all'utilizzo della CPU dei gruppi di istanze associati, ma puoi anche bilanciare il carico in base alle richieste al secondo (RPS).
Nota:un controllo di integrità è sempre necessario quando si crea un servizio di backend.
Creazione di un modello unificato
Infine, crea un modello unificato che combini i modelli di backend e frontend. Crea un nuovo file denominato application.[py|jinja]
:
Jinja
Python
Crea un file di schema corrispondente:
Jinja
Python
Oltre al frontend e al backend, il modello definisce anche alcune risorse aggiuntive:
Un servizio statico con gruppi di istanze gestite primari e secondari. Questo servizio statico pubblica una pagina web che si trova nel percorso
/static
della tua app.Una risorsa mappa URL. Il bilanciamento del carico HTTP richiede una mappa URL per mappare i diversi URL ai percorsi corretti. In questo caso, il percorso predefinito, indicato dalla proprietà
defaultService
, è il servizio di backend che hai creato in precedenza. Se un utente accede a/static
, la mappa URL mapperà questo percorso al servizio statico, come definito nella sezionepathMatchers
.Una regola di forwarding globale e un proxy HTTP di destinazione. Poiché l'app viene bilanciata in due zone separate, avrai bisogno di una regola di forwarding globale che gestisca un singolo indirizzo IP esterno. Inoltre, per la configurazione del bilanciamento del carico HTTP è necessario un proxy HTTP di destinazione.
Una regola firewall che consente il traffico attraverso la porta 8080.
Creazione della configurazione
Ora che hai preparato i modelli e gli schemi correlati, puoi creare una configurazione che esegua il deployment di queste risorse. Crea un file di configurazione denominato
application.yaml
con i seguenti contenuti e sostituisci ZONE_TO_RUN
e
SECONDARY_ZONE_TO_RUN
con le zone primaria e secondaria che preferisci.
Jinja
Python
Deployment della configurazione
Ora eseguiamo il deployment delle risorse. Utilizzando Google Cloud CLI, esegui il
comando seguente, scegliendo facoltativamente di sostituire advanced-configuration-l7
con un nome di deployment a tua scelta. Tieni presente che il nome del deployment
verrà utilizzato automaticamente per denominare le risorse.
In questo esempio, il nome del deployment è advanced-configuration-l7
. Se scegli
di modificare il nome del deployment, assicurati di utilizzarlo in tutti
gli esempi seguenti.
gcloud deployment-manager deployments create advanced-configuration-l7 --config application.yaml
La risposta dovrebbe essere simile alle seguenti risorse:
Waiting for create operation-1469468950934-5387966d431f0-49b11bc4-1421b2f0...done. Create operation operation-1469468950934-5387966d431f0-49b11bc4-1421b2f0 completed successfully. NAME TYPE STATE ERRORS advanced-configuration-l7-application-fw compute.v1.firewall COMPLETED [] advanced-configuration-l7-application-l7lb compute.v1.globalForwardingRule COMPLETED [] advanced-configuration-l7-application-targetproxy compute.v1.targetHttpProxy COMPLETED [] advanced-configuration-l7-application-urlmap compute.v1.urlMap COMPLETED [] advanced-configuration-l7-backend compute.v1.instance COMPLETED [] advanced-configuration-l7-frontend-bes compute.v1.backendService COMPLETED [] advanced-configuration-l7-frontend-hc compute.v1.httpHealthCheck COMPLETED [] advanced-configuration-l7-frontend-it compute.v1.instanceTemplate COMPLETED [] advanced-configuration-l7-frontend-pri-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-frontend-pri-igm compute.v1.instanceGroupManager COMPLETED [] advanced-configuration-l7-frontend-sec-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-frontend-sec-igm compute.v1.instanceGroupManager COMPLETED [] advanced-configuration-l7-static-service-bes compute.v1.backendService COMPLETED [] advanced-configuration-l7-static-service-hc compute.v1.httpHealthCheck COMPLETED [] advanced-configuration-l7-static-service-it compute.v1.instanceTemplate COMPLETED [] advanced-configuration-l7-static-service-pri-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-static-service-pri-igm compute.v1.instanceGroupManager COMPLETED [] advanced-configuration-l7-static-service-sec-as compute.v1.autoscaler COMPLETED [] advanced-configuration-l7-static-service-sec-igm compute.v1.instanceGroupManager COMPLETED []
Aggiunta di etichette di servizio
Successivamente, specifica le etichette di servizio appropriate per i tuoi gruppi di istanze gestite. Le etichette di servizio sono metadati utilizzati dal servizio di bilanciamento del carico per raggruppare le risorse.
Per aggiungere etichette di servizio, esegui i seguenti comandi, abbinando le zone primaria e secondaria alle zone selezionate nel file di configurazione della distribuzione:
gcloud compute instance-groups unmanaged set-named-ports advanced-configuration-l7-frontend-pri-igm \
--named-ports http:8080,httpstatic:8080 \
--zone [PRIMARY_ZONE]
gcloud compute instance-groups unmanaged set-named-ports advanced-configuration-l7-frontend-sec-igm \
--named-ports http:8080,httpstatic:8080 \
--zone [SECONDARY_ZONE]
Testare la configurazione
Per testare la configurazione, recupera l'indirizzo IP esterno che gestisce il traffico eseguendo una query sulla regola di forwarding:
gcloud compute forwarding-rules list | grep advanced-configuration-l7-l7lb advanced-configuration-l7-l7lb 107.178.249.126 TCP advanced-configuration-l7-targetproxy
In questo caso, l'IP esterno è 107.178.249.126
.
In un browser, visita l'indirizzo IP esterno sulla porta 8080. Ad esempio,
se il tuo IP esterno è 107.178.249.126
, l'URL sarà:
http://107.178.249.126:8080
Dovresti visualizzare una pagina vuota, come previsto. Dopodiché, pubblica un messaggio sulla pagina. Vai al seguente URL:
http://107.178.249.126:8080?msg=hello_world!
Verrà visualizzata la conferma dell'aggiunta del messaggio. Torna all'URL principale e ora la pagina dovrebbe contenere il messaggio:
hello_world!
Puoi anche visitare la pagina statica che hai creato o controllare l'integrità della tua app visitando i seguenti URL:
# Static web page
http://107.178.249.126:8080/static
# Health check
http://107.178.249.126:8080/_ah/health
Congratulazioni, il deployment della configurazione è stato eseguito correttamente.
(Facoltativo) Creazione di immagini Docker
Docker ti consente di automatizzare ed eseguire software all'interno dei container. I container consentono di isolare diversi servizi all'interno di container che possono essere eseguiti su una singola istanza Linux.
Questo esempio ha utilizzato alcune immagini Docker esistenti, ma puoi anche creare le tue versioni di queste immagini Docker. Puoi trovare le istruzioni per creare le immagini di backend MySQL e le immagini di frontend Node.js nella sezione Creazione dei modelli di risorse.
Per creare l'immagine Docker che gestisce la pagina web statica:
Crea una nuova istanza VM con un'immagine ottimizzata per i container:
gcloud compute instances create docker-playground \ --image-family container-vm \ --image-project google-containers \ --zone us-central1-a \ --machine-type f1-micro
Connettiti all'istanza:
gcloud compute ssh --zone us-central1-a docker-playground
Crea un file denominato
Dockerfile
con il seguente contenuto:FROM node:latest RUN mkdir /var/www/ ADD service.js /var/www/service.js WORKDIR /var/www/ RUN npm install mysql CMD ["node", "service.js"]
Crea un file denominato
service.js
con il seguente contenuto:var http = require('http'); var url = require('url'); console.log('Started static node server') http.createServer(function (req, res) { reqUrl = url.parse(req.url, true); res.useChunkedEncodingByDefault = false; res.writeHead(200, {'Content-Type': 'text/html'}); if (reqUrl.pathname == '/_ah/health') { res.end('ok'); } else if (reqUrl.pathname == '/exit') { process.exit(-1) } else { res.end('static server'); } }).listen(8080, '0.0.0.0'); console.log('Static server running at http://127.0.0.1:8080/');
Crea l'immagine Docker, sostituendo
username
con il tuo nome utente Docker Hub. Se non hai un nome utente Docker Hub, creane uno prima di creare l'immagine Docker.sudo docker build --no-cache -t username/nodejsservicestatic .
Esegui il push delle immagini nel repository Docker:
sudo docker push username/nodejsservicestatic
Ora hai le immagini Docker per eseguire Node.js e MySQL. Puoi visualizzare queste immagini nel repository cercando i nomi delle immagini. Per provare le immagini, puoi sostituire tutte le occorrenze di
gcr.io/deployment-manager-examples/mysql
e
gcr.io/deployment-manager-examples/nodejsservice
con le rispettive immagini.
Passaggi successivi
Una volta completato questo esempio, puoi:
- Continua a sviluppare questo esempio creando una pagina web più solida o aggiungendo altri servizi al server web.
- Scopri di più sulle configurazioni o sui deployment.
- Prova a creare le tue configurazioni.