«Nuove Bylyny». Mangiamo l'elefante a pezzi

«Nuove Bylyny». Mangiamo l'elefante a pezzi

In questo articolo, configurerò l'ambiente di lavoro per lo sviluppo del gioco «Bylyny», oltre a suddividere il gioco stesso in parti utilizzabili in OpenFaaS. Eseguirò tutte le operazioni su Linux, distribuendo Kubernetes in minikube utilizzando VirtualBox. La mia macchina di lavoro ha 2 core di processore e 12 GB di RAM, e utilizzo un SSD come disco di sistema. Come sistema principale per lo sviluppo utilizzerò Debian 8, con i pacchetti emacs, sudo, git e virtualbox installati, e installerò tutto il resto scaricandolo da GitHub e altre fonti. Installeremo queste applicazioni in /usr/local/bin, a meno che non sia indicato diversamente. Iniziamo!

Preparazione dell'ambiente di lavoro

Installazione di Go

Seguiamo le istruzioni dal sito ufficiale:

$ curl -L0 https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz -o go.tar.gz
$ sudo tar -C /usr/local -xzf go.tar.gz
$ echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile

Verifichiamo il funzionamento:

$ mkdir -p ~/go/src/hello && cd ~/go/src/hello
$ echo 'package main

import "fmt"

func main() {
fmt.Printf("hello, worldn")
}' > hello.go
$ go build
$ ./hello
hello, world

Installazione di faas-cli

Seguiamo le istruzioni dal sito ufficiale:

$ curl -sSL https://cli.openfaas.com | sudo -E sh
x86_64
Scaricamento del pacchetto https://github.com/openfaas/faas-cli/releases/download/0.11.3/faas-cli in /tmp/faas-cli
Download completato.

Esecuzione con permessi sufficienti per tentare di spostare faas-cli in /usr/local/bin
Nuova versione di faas-cli installata in /usr/local/bin
Creazione dell'alias 'faas' per 'faas-cli'.
  ___                   _____           ____
 / _  _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_  / _  '_ | |_ / _` |/ _` ___ 
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 ___/| .__/ ___|_| |_|_|  __,_|__,_|____/
      |_|

CLI:
 commit:  73004c23e5a4d3fdb7352f953247473477477a64
 version: 0.11.3

È possibile anche abilitare il completamento bash:

faas-cli completion --shell bash | sudo tee /etc/bash_completion.d/faas-cli

Installazione e configurazione di Kubernetes

Per lo sviluppo è sufficiente minikube, quindi installiamolo e kubelet in /usr/local/bin; per installare le applicazioni, installeremo anche helm:

$ curl https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 -o minikube && chmod +x minikube && sudo mv minikube /usr/local/bin/
$ curl https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl -o kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/
$ curl https://get.helm.sh/helm-v3.0.2-linux-amd64.tar.gz | tar -xzvf - linux-amd64/helm --strip-components=1; sudo mv helm /usr/local/bin

Avviamo minikube:

$ minikube start
  minikube v1.6.2 su Debian 8.11
  Driver 'virtualbox' selezionato automaticamente (alternative: [])
  Downloading VM boot image ...
    > minikube-v1.6.0.iso.sha256: 65 B / 65 B [--------------] 100.00% ? p/s 0s
    > minikube-v1.6.0.iso: 150.93 MiB / 150.93 MiB [-] 100.00% 5.67 MiB p/s 27s
  Creazione della VM virtualbox (CPUs=2, Memoria=8192MB, Disco=20000MB) ...
  Preparazione di Kubernetes v1.17.0 su Docker '19.03.5' ...
  Downloading kubeadm v1.17.0
  Downloading kubelet v1.17.0
  Pulling images ...
  Lancio di Kubernetes ...  In attesa che il cluster si metta online ...
  Fatto! kubectl è ora configurato per usare "minikube"

Controllando:

$ kubectl get pods --all-namespaces
NAMESPACE     NAME                               READY   STATUS    RESTARTS   AGE
kube-system   coredns-6955765f44-knlcb           1/1     In esecuzione   0          29m
kube-system   coredns-6955765f44-t9cpn           1/1     In esecuzione   0          29m
kube-system   etcd-minikube                      1/1     In esecuzione   0          28m
kube-system   kube-addon-manager-minikube        1/1     In esecuzione   0          28m
kube-system   kube-apiserver-minikube            1/1     In esecuzione   0          28m
kube-system   kube-controller-manager-minikube   1/1     In esecuzione   0          28m
kube-system   kube-proxy-hv2wc                   1/1     In esecuzione   0          29m
kube-system   kube-scheduler-minikube            1/1     In esecuzione   0          28m
kube-system   storage-provisioner                1/1     In esecuzione   1          29m

Installazione di OpenFaaS

Gli sviluppatori consigliano di creare 2 namespace per il lavoro:

$ kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
namespace/openfaas creato
namespace/openfaas-fn creato

Aggiungiamo il repository per helm:

$ helm repo add openfaas https://openfaas.github.io/faas-netes/
"openfaas" è stato aggiunto ai tuoi repository

Nella chart c'è la possibilità di impostare una password prima dell'installazione, utilizziamola e salviamo i dati di accesso come segreto k8s:

$ PASSWORD=verysecurerandompasswordstring
$ kubectl -n openfaas create secret generic basic-auth --from-literal=basic-auth-user=admin --from-literal=basic-auth-password="$PASSWORD"
segreto/basic-auth creato

Eseguiamo il deployment:

$ helm repo update
Attendere mentre recuperiamo l'ultimo aggiornamento dai tuoi repository chart...
...Aggiornamento riuscito dal repository chart "openfaas"
Aggiornamento completato. Buon Helming!
$ helm upgrade openfaas --install openfaas/openfaas --namespace openfaas --set functionNamespace=openfaas-fn --set generateBasicAuth=false
Il rilascio "openfaas" non esiste. Installandolo ora.
NOME: openfaas
ULTIMO DISTRIBUITO: Fri Dec 25 10:28:22 2019
NAMESPACE: openfaas
STATO: distribuito
REVISIONE: 1
SUITE DI TEST: Nessuna
NOTE:
Per verificare che openfaas sia avviato, esegui:

  kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"

Dopo un po' di tempo, eseguiamo il comando suggerito:

$ kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"
NOME                PRONTO   UP-TO-DATE   DISPONIBILE   ETA
alertmanager        1/1     1            1           114s
basic-auth-plugin   1/1     1            1           114s
faas-idler          1/1     1            1           114s
gateway             1/1     1            1           114s
nats                1/1     1            1           114s
prometheus          1/1     1            1           114s
queue-worker        1/1     1            1           114s

Verifichiamo il funzionamento:

$ kubectl rollout status -n openfaas deploy/gateway
deployment "gateway" distribuito con successo
$ kubectl port-forward -n openfaas svc/gateway 8080:8080 &
[1] 6985
Inoltro da 127.0.0.1:8080 -> 8080
$ echo -n $PASSWORD | faas-cli login --username admin --password-stdin
Chiamando il server OpenFaaS per convalidare le credenziali...
Gestione connessione per 8080
ATTENZIONE! La comunicazione non è sicura, si prega di considerare l'uso di HTTPS. Letsencrypt.org offre certificati SSL/TLS gratuiti.
credenziali salvate per admin http://127.0.0.1:8080
$ faas-cli list
Funzione                        Invocazioni     Repliche

Installazione di Mongodb

Installiamo tutto utilizzando helm:

$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
"stable" è stato aggiunto ai tuoi repository
$ helm install stable/mongodb --generate-name
NOME: mongodb-1577466908
ULTIMA INSTALLAZIONE: Ven Dec 25 11:15:11 2019
NAMESPACE: default
STATO: installato
REVISIONE: 1
SUITE DI TEST: Nessuna
NOTE:
** Ti preghiamo di avere pazienza mentre il chart viene installato **

MongoDB può essere accessibile tramite la porta 27017 sul seguente nome DNS all'interno del tuo cluster:

    mongodb-1577466908.default.svc.cluster.local

Per ottenere la password di root eseguire:

    export MONGODB_ROOT_PASSWORD=$(kubectl get secret --namespace default mongodb-1577466908 -o jsonpath="{.data.mongodb-root-password}" | base64 --decode)

Per connettersi al tuo database, eseguire il seguente comando:

    kubectl run --namespace default mongodb-1577466908-client --rm --tty -i --restart='Never' --image bitnami/mongodb --command -- mongo admin --host mongodb-1577466908 --authenticationDatabase admin -u root -p $MONGODB_ROOT_PASSWORD

Per connettersi al tuo database dall'esterno del cluster, eseguire i seguenti comandi:

    kubectl port-forward --namespace default svc/mongodb-1577466908 27017:27017 &
    mongo --host 127.0.0.1 --authenticationDatabase admin -p $MONGODB_ROOT_PASSWORD

Controllando:

kubectl run --namespace default mongodb-1577466908-client --rm --tty -i --restart='Never' --image bitnami/mongodb --command -- mongo admin --host mongodb-1577466908 --authenticationDatabase admin -u root -p $(kubectl get secret --namespace default mongodb-1577466908 -o jsonpath="{.data.mongodb-root-password}" | base64 --decode)
Se non vedi un prompt dei comandi, prova a premere invio.

> db.version();
4.0.14

Premiamo ctrl+D per uscire dal contenitore.

Configurazione di emacs

In linea di principio, era già tutto configurato secondo questo articolo, quindi non entrerò nei dettagli.

Suddivisione del gioco in funzioni

L'interazione con le funzioni avviene tramite il protocollo http, l'autenticazione continua tra diverse funzioni è garantita da JWT. Per memorizzare i token, così come lo stato del gioco, i dati dei giocatori, le sequenze di mosse di tutti i giochi e altre informazioni, si utilizza mongodb. Esaminiamo più in dettaglio le funzioni più interessanti.

Registrazione

In ingresso a questa funzione — JSON con il soprannome di gioco e la password. Quando viene chiamata questa funzione, viene effettuato un controllo per verificare l'assenza di questo soprannome nel database; se la verifica ha esito positivo, il soprannome e l'hash della password vengono inseriti nel database. La registrazione è necessaria per partecipare attivamente al gioco.

Accesso

La funzione accetta un JSON contenente un nickname di gioco e una password. Se il nickname è presente nel database e la password viene verificata correttamente, viene restituito un JWT da utilizzare nelle chiamate a altre funzioni. Inoltre, vengono inseriti nel database vari record di servizio, come l'orario dell'ultimo accesso, ecc.

Visualizza l'elenco dei giochi

Qualsiasi utente non autorizzato può richiedere un elenco di tutti i giochi, escluse le partite attive. Gli utenti autorizzati vedono anche l'elenco dei giochi attivi. Il risultato della funzione è un JSON contenente gli elenchi di giochi (identificativo del gioco, nome leggibile dall'uomo, ecc.).

Creazione di un gioco

La funzione è disponibile solo per gli utenti autenticati. Sono accettati il numero massimo di giocatori e le impostazioni del gioco (ad esempio, quali personaggi attivare in questo gioco, il numero massimo di giocatori, ecc.). Un parametro separato è la presenza di una password per accedere, che consente di creare giochi privati. Per default, viene creata una partita pubblica. Il risultato della funzione è un JSON che include un campo per il successo della creazione, un identificatore unico del gioco e altri parametri.

Unisciti al gioco

La funzione è disponibile solo per gli utenti autenticati. Gli input comprendono l'identificatore del gioco e la sua password, se si tratta di un gioco privato; l'output è un JSON con i parametri del gioco. Un utente autenticato che si unisce al gioco, insieme al creatore del gioco, è considerato un partecipante.

Visualizza eventi del gioco

Qualsiasi utente non autorizzato può richiedere un elenco di eventi di giochi inattivi, mentre un utente autorizzato può ricevere un elenco di eventi di qualsiasi gioco attivo. Un ulteriore parametro della funzione può includere il numero di evento già presente per l'utente. In questo caso, l'elenco restituirà solo quegli eventi che sono avvenuti successivamente. Eseguendo periodicamente questa funzione, l'utente autorizzato controlla cosa sta accadendo nel gioco. Inoltre, questa funzione restituisce una richiesta di azione a cui l'utente può rispondere tramite la funzione di invio dell'evento di gioco.

Invio dell'evento di gioco

La funzione funziona solo per i partecipanti al gioco: è possibile avviare il gioco, fare una mossa, votare, inviare un messaggio di testo che appare nell'elenco degli eventi del gioco, ecc.
L'utente autorizzato che ha creato il gioco avvia la distribuzione dei ruoli a tutti i partecipanti, incluso se stesso; devono confermare il proprio ruolo utilizzando la stessa funzione. Una volta confermati tutti i ruoli, il gioco passa automaticamente alla modalità notte.

Statistiche del gioco

La funzione è attiva solo per i partecipanti al gioco, mostra lo stato del gioco, l'elenco e il numero dei giocatori (soprannomi), i ruoli e il loro stato (è stata fatta una mossa o meno), oltre ad altre informazioni. Come per la funzione precedente, tutto funziona solo per i partecipanti al gioco.

Funzioni eseguite periodicamente

Se il gioco non è stato avviato per un certo periodo di tempo, come specificato durante la creazione del gioco, sarà automaticamente rimosso dall'elenco dei giochi attivi attraverso la funzione di pulizia.

Un'altra attività periodica è il passaggio forzato della modalità di gioco da notte a giorno e viceversa per i giochi in cui ciò non è avvenuto durante il turno (ad esempio, un giocatore che deve rispondere a un evento di gioco non ha inviato la propria decisione per vari motivi).

Annuncio

  • Introduzione
  • Impostazione dell'ambiente di sviluppo, suddivisione del compito in funzioni
  • Lavori sul backend
  • Lavori sul frontend
  • Configurazione del CICD, organizzazione dei test
  • Avvio di una sessione di prova del gioco
  • Risultati

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster