Questo esempio avanzato mostra come creare un'app di logbook che utilizza Node.js per il frontend e MySQL per il backend. Il modello crea e collega anche un bilanciatore del carico HTTP che esegue il bilanciamento del carico su due zone e un adeguamento automatico per scalare automaticamente l'app.
Questo esempio presuppone che tu abbia dimestichezza con i contenitori Docker e con le risorse Compute Engine, in particolare con il bilanciamento del carico HTTP, la scalabilità automatica, i gruppi di istanze gestite e i modelli di istanze.
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.
- Conoscenza del bilanciamento del carico HTTP di Compute Engine.
- Conoscenza dei 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 contenente queste risorse:
- Una singola istanza 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 frontend Node.js.
- 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 tra i 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 contenitori. Assegna il nome container_vm.[py|jinja]
al file:
Jinja
Python
Il modello definisce una serie di variabili, come containerImage
e manifest
, che verranno compilate quando definisci la configurazione. Questo modello da solo crea solo un'unica istanza di macchina virtuale (VM).
Quando utilizzi immagini contenitore nelle istanze Compute Engine, devi anche fornire un file manifest (diverso da un manifest di Deployment Manager) per descrivere a Compute Engine quale immagine contenitore utilizzare. Crea un metodo di supporto chiamato container_helper.[py|jinja]
per definire dinamicamente il manifest del contenitore:
Jinja
Python
Creazione dei modelli frontend
Il frontend di questa app esegue Node.js e consente agli utenti di pubblicare messaggi sulla pagina web. Saranno presenti due gruppi di istanze gestite contenenti ciascuna due istanze: 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, ovvero 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 node.js frontend, 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 lo utilizzi per creare un gruppo di istanze gestite a 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. Utilizza questi modelli per definire 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 cosa viene creato da questo modello:
Due gruppi di istanze gestite, uno principale e uno secondario.
Il modello utilizza il modello
autoscaled_group.[py|jinja]
per creare un gruppo di istanze gestite a scalabilità automatica principale e secondario.Successivamente, il modello crea un servizio di backend e un controllo di integrità. Per il bilanciamento del carico HTTP è necessario un servizio di backend che definisce la capacità di gestione dei gruppi di istanze in quel servizio di backend. In questo caso, i gruppi di istanze gestite principali e secondari 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 eseguire il bilanciamento del carico in base alle richieste al secondo (RPS).
Nota:un controllo di integrità è sempre obbligatorio quando crei un servizio di backend.
Creazione di un modello unificante
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 principali e secondarie. Questo servizio statico pubblica una pagina web 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é il bilanciamento del carico dell'app avviene su due zone distinte, è necessaria una regola di forwarding globale che indirizzi un singolo indirizzo IP esterno. Inoltre, per la configurazione del bilanciamento del carico HTTP è necessario un proxy HTTP di destinazione.
Una regola firewall che consenta il traffico tramite la porta 8080.
Creazione della configurazione
Ora che hai a disposizione i modelli e gli schemi correlati, puoi creare una configurazione che esegue 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 principali e secondarie che preferisci.
Jinja
Python
Deployment della configurazione
Ora esegui il deployment delle risorse. Utilizzando Google Cloud CLI, esegui il seguente comando, eventualmente scegliendo di sostituire advanced-configuration-l7
con un nome di deployment a tua scelta. Tieni presente che il nome del deployment verrà utilizzato automaticamente per assegnare un nome alle risorse.
In questo esempio, il nome del deployment è advanced-configuration-l7
. Se scegli di cambiare il nome del deployment, assicurati di utilizzarlo in tutti i seguenti esempi.
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
Quindi, specifica le etichette dei servizi appropriate per i gruppi di istanze gestite. Le etichette dei servizi sono metadati utilizzati dal servizio di bilanciamento del carico per raggruppare le risorse.
Per aggiungere le etichette dei servizi, esegui i seguenti comandi, associando le zone principali e secondarie a quelle selezionate nel file di configurazione del deployment:
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 indirizzo IP esterno è 107.178.249.126
, l'URL sarà:
http://107.178.249.126:8080
Dovresti visualizzare una pagina vuota, come previsto. Poi, 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. Nella pagina dovrebbe essere visualizzato 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
Complimenti, hai eseguito il deployment della configurazione.
(Facoltativo) Creazione di immagini Docker
Docker ti consente di automatizzare ed eseguire software all'interno di 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 Creare i modelli di risorse.
Per creare l'immagine Docker che serve 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 i seguenti contenuti: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 i seguenti contenuti: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 di 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 relativi nomi. 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.