
Dans cet article, je vais configurer un environnement de travail pour le développement du jeu «Bylines», et je vais également découper le jeu en parties pouvant être utilisées dans OpenFaaS. Toutes les manipulations se feront sur Linux, et je déploierai Kubernetes avec minikube en utilisant VirtualBox. Ma machine possède 2 cœurs de processeur et 12 Go de RAM, et j'utilise un SSD comme disque système. Pour le développement, je vais utiliser Debian 8, avec les paquets emacs, sudo, git et virtualbox installés, et tout le reste sera téléchargé depuis GitHub et d'autres sources. Ces applications seront installées dans /usr/local/bin, sauf indication contraire. Commençons !
Préparation de l'environnement de travail
Installation de Go
Suivez les instructions sur le site officiel :
$ 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' >> ~/.profileVérifions le bon fonctionnement :
$ 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, worldInstallation de faas-cli
Suivez les instructions sur le site officiel :
$ curl -sSL https://cli.openfaas.com | sudo -E sh
x86_64
Téléchargement du package https://github.com/openfaas/faas-cli/releases/download/0.11.3/faas-cli vers /tmp/faas-cli
Téléchargement terminé.
Exécution avec suffisamment de permissions pour tenter de déplacer faas-cli vers /usr/local/bin
Nouvelle version de faas-cli installée dans /usr/local/bin
Création d'un alias 'faas' pour 'faas-cli'.
___ _____ ____
/ _ _ __ ___ _ __ | ___|_ _ __ _/ ___|
| | | | '_ / _ '_ | |_ / _` |/ _` ___
| |_| | |_) | __/ | | | _| (_| | (_| |___) |
___/| .__/_ ___|_| |_|_| __,_|__,_|____/
|_|
CLI:
commit: 73004c23e5a4d3fdb7352f953247473477477a64
version: 0.11.3Il est également possible d'activer l'achèvement bash :
faas-cli completion --shell bash | sudo tee /etc/bash_completion.d/faas-cliInstallation et configuration de Kubernetes
Pour le développement, il suffit de minikube, alors installons-le avec kubelet dans /usr/local/bin, et pour l'installation des applications, nous allons également installer 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/binDémarrons minikube :
$ minikube start
minikube v1.6.2 sur Debian 8.11
Le driver 'virtualbox' a été sélectionné automatiquement (alternatives : [])
Téléchargement de l'image de démarrage de la VM ...
> 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
Création de la VM virtualbox (CPUs=2, Mémoire=8192MB, Disque=20000MB) ...
Préparation de Kubernetes v1.17.0 sur Docker '19.03.5' ...
Téléchargement de kubeadm v1.17.0
Téléchargement de kubelet v1.17.0
Récupération des images ...
Lancement de Kubernetes ... Attente de l'activation du cluster ...
Fait ! kubectl est maintenant configuré pour utiliser "minikube"Vérifions :
$ kubectl get pods --all-namespaces
NAMESPACE NOM PRÊT STATUT RESTARTS ÂGE
kube-system coredns-6955765f44-knlcb 1/1 En cours 0 29m
kube-system coredns-6955765f44-t9cpn 1/1 En cours 0 29m
kube-system etcd-minikube 1/1 En cours 0 28m
kube-system kube-addon-manager-minikube 1/1 En cours 0 28m
kube-system kube-apiserver-minikube 1/1 En cours 0 28m
kube-system kube-controller-manager-minikube 1/1 En cours 0 28m
kube-system kube-proxy-hv2wc 1/1 En cours 0 29m
kube-system kube-scheduler-minikube 1/1 En cours 0 28m
kube-system storage-provisioner 1/1 En cours 1 29mInstallation d'OpenFaaS
Les développeurs recommandent de créer 2 namespaces pour le travail :
$ kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
namespace/openfaas créé
namespace/openfaas-fn crééAjoutons le dépôt pour helm :
$ helm repo add openfaas https://openfaas.github.io/faas-netes/
"openfaas" a été ajouté à vos dépôtsLe chart offre la possibilité de définir un mot de passe avant l'installation, utilisons-le et sauvegardons les données d'accès sous forme de secret k8s :
$ PASSWORD=verysecurerandompasswordstring
$ kubectl -n openfaas create secret generic basic-auth --from-literal=basic-auth-user=admin --from-literal=basic-auth-password="$PASSWORD"
secret/basic-auth crééExécutons le déploiement :
$ helm repo update
Accrochez-vous pendant que nous récupérons les dernières mises à jour de vos dépôts de chartes...
...Successfully got an update from the "openfaas" chart repository
Mise à jour terminée. Bon Helming !
$ helm upgrade openfaas --install openfaas/openfaas --namespace openfaas --set functionNamespace=openfaas-fn --set generateBasicAuth=false
La release "openfaas" n'existe pas. Installation en cours.
NOM : openfaas
DERNIER DEPLOIEMENT : ven. 25 déc. 2019 10:28:22
NAMESPACE : openfaas
STATUT : déployé
RÉVISION : 1
SUITE DE TEST : Aucune
NOTES :
Pour vérifier qu'openfaas a démarré, exécutez :
kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"Après un certain temps, exécutons la commande proposée :
$ kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"
NOM PRÊT UP-TO-DATE DISPONIBLE ÂGE
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 114sVérifions le bon fonctionnement :
$ kubectl rollout status -n openfaas deploy/gateway
deployment "gateway" successfully rolled out
$ kubectl port-forward -n openfaas svc/gateway 8080:8080 &
[1] 6985
Forwarding from 127.0.0.1:8080 -> 8080
$ echo -n $PASSWORD | faas-cli login --username admin --password-stdin
Calling the OpenFaaS server to validate the credentials...
Handling connection for 8080
WARNING! Communication is not secure, please consider using HTTPS. Letsencrypt.org offers free SSL/TLS certificates.
credentials saved for admin http://127.0.0.1:8080
$ faas-cli list
Function Invocations ReplicasInstallation de Mongodb
Nous installons tout en utilisant helm :
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
"stable" has been added to your repositories
$ helm install stable/mongodb --generate-name
NAME: mongodb-1577466908
LAST DEPLOYED: Fri Dec 25 11:15:11 2019
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
** Please be patient while the chart is being deployed **
MongoDB peut être accessible via le port 27017 sous le nom DNS suivant depuis votre cluster :
mongodb-1577466908.default.svc.cluster.local
Pour obtenir le mot de passe root, exécutez :
export MONGODB_ROOT_PASSWORD=$(kubectl get secret --namespace default mongodb-1577466908 -o jsonpath="{.data.mongodb-root-password}" | base64 --decode)
Pour vous connecter à votre base de données, exécutez la commande suivante :
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
Pour vous connecter à votre base de données depuis l'extérieur du cluster, exécutez les commandes suivantes :
kubectl port-forward --namespace default svc/mongodb-1577466908 27017:27017 &
mongo --host 127.0.0.1 --authenticationDatabase admin -p $MONGODB_ROOT_PASSWORDVérifions :
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)
Si vous ne voyez pas une invite de commande, essayez d'appuyer sur entrée.
> db.version();
4.0.14Appuyez sur ctrl+D pour sortir du conteneur.
Configuration de emacs
En principe, tout était déjà configuré par , donc je ne vais pas détailler.
Découpage du jeu en fonctions
L'interaction avec les fonctions se fait via le protocole http, l'authentification transversale entre différentes fonctions étant assurée par JWT. Pour stocker les tokens, ainsi que l'état du jeu, les données des joueurs, les séquences de mouvements de tous les jeux et d'autres informations, on utilise mongodb. Examinons de plus près les fonctions les plus intéressantes.
Inscription
En entrée de cette fonction — JSON avec le pseudo du jeu et le mot de passe. Lors de l'appel de cette fonction, une vérification est effectuée pour s'assurer que ce pseudo n'est pas déjà dans la base de données ; si la vérification est réussie, le pseudo et le hash du mot de passe sont insérés dans la base. L'inscription est nécessaire pour participer activement au jeu.
Connexion
À l'entrée de la fonction se trouve un JSON avec un pseudo de jeu et un mot de passe. Si le pseudo est présent dans la base de données et que la vérification du mot de passe avec celui enregistré est réussie, un JWT est renvoyé, qui doit être transmis aux autres fonctions lors de leur appel. Des enregistrements divers, tels que l'heure de la dernière connexion, sont également insérés dans la base.
Visualiser la liste des jeux
Tout utilisateur non autorisé peut demander la liste de tous les jeux, sauf les actifs. Un utilisateur autorisé voit également la liste des jeux actifs. Le résultat de la fonction est un JSON contenant des listes de jeux (identifiant du jeu, nom lisible par l'homme, etc.).
Création de jeu
La fonction ne fonctionne qu'avec des utilisateurs autorisés. À l'entrée, elle prend le nombre maximum de joueurs ainsi que les paramètres du jeu (par exemple, quels personnages activer dans ce jeu, le nombre maximum de joueurs, etc.). Un paramètre distinct du jeu est la présence d'un mot de passe pour rejoindre, ce qui permet de créer des jeux non publics. Par défaut, un jeu public est créé. Le résultat de l'exécution de la fonction est un JSON comportant un champ indiquant le succès de la création, un identifiant unique du jeu, ainsi que d'autres paramètres.
Rejoindre un jeu
La fonction ne fonctionne qu'avec des utilisateurs autorisés. À l'entrée, elle prend l'identifiant du jeu et son mot de passe, si c'est un jeu non public, et à la sortie, un JSON contenant les paramètres du jeu. L'utilisateur autorisé qui a rejoint le jeu ainsi que le créateur du jeu sont appelés les participants au jeu.
Visualiser les événements du jeu
Tout utilisateur non autorisé peut demander la liste des événements des jeux inactifs, tandis qu'un utilisateur autorisé peut obtenir la liste des événements de n'importe quel jeu actif. Un paramètre supplémentaire de la fonction peut inclure le numéro d'un événement que l'utilisateur a déjà. Dans ce cas, seule la liste des événements survenus après sera renvoyée. En lançant périodiquement cette fonction, l'utilisateur autorisé peut voir ce qui se passe dans le jeu. Cette fonction renvoie également une demande d'action à laquelle l'utilisateur peut réagir en envoyant un événement de jeu.
Envoyer un événement de jeu
La fonctionnalité ne fonctionne que pour les participants au jeu : elle permet de lancer le jeu, de faire un coup, de voter, d'écrire un message texte qui s'affiche dans la liste des événements du jeu, etc.
L'utilisateur autorisé qui a créé le jeu distribue les rôles à tous les participants, y compris lui-même, qui doivent confirmer leur rôle grâce à cette même fonctionnalité. Une fois que tous les rôles sont confirmés, le jeu passe automatiquement en mode nuit.
Statistiques du jeu
La fonctionnalité ne fonctionne que pour les participants au jeu, affichant l'état du jeu, la liste et le nombre de joueurs (pseudo), les rôles et leur statut (coup joué ou non), ainsi que d'autres informations. Comme pour la fonctionnalité précédente, tout cela ne fonctionne que pour les participants au jeu.
Fonctions lancées périodiquement
Si le jeu n'a pas été lancé pendant un certain temps, comme spécifié lors de la création du jeu, il sera automatiquement supprimé de la liste des jeux actifs par la fonction de nettoyage.
Une autre tâche périodique consiste à forcer le passage du mode nuit au mode jour et vice versa pour les jeux qui n'ont pas réalisé ce passage pendant un tour (par exemple, un joueur qui devait réagir à un événement de jeu n'a pas soumis sa décision pour diverses raisons).
Annonce
- Configuration de l'environnement de développement, décomposition de la tâche en fonctions
- Travaux sur le backend
- Travaux sur le frontend
- Configuration du CICD, organisation des tests
- Lancement d'une session d'essai du jeu
- Résultats
Source : habr.com
