‘Nuevas Byliny’. Comemos al elefante por partes.

‘Nuevas Byliny’. Comemos al elefante por partes.

En este artículo configuraré el entorno de trabajo para desarrollar el juego 'Byliny', así como descomponer el propio juego en partes adecuadas para usar en OpenFaaS. Realizaré todas las manipulaciones en Linux, y desplegaré Kubernetes en minikube utilizando VirtualBox. Mi máquina de trabajo tiene 2 núcleos de procesador y 12 GB de RAM, y utilizo un SSD como disco del sistema. La principal sistema para el desarrollo que utilizaré será Debian 8, con paquetes instalados como emacs, sudo, git y virtualbox; todo lo demás lo instalaré descargándolo de GitHub y otras fuentes. Estas aplicaciones se instalarán en /usr/local/bin, a menos que se indique lo contrario. ¡Empecemos!

Preparación del entorno de trabajo

Instalación de Go

Sigamos las instrucciones del sitio oficial:

$ 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

Verificamos el funcionamiento:

$ 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

Instalación de faas-cli

Sigamos las instrucciones del sitio oficial:

$ curl -sSL https://cli.openfaas.com | sudo -E sh
x86_64
Descargando paquete https://github.com/openfaas/faas-cli/releases/download/0.11.3/faas-cli como /tmp/faas-cli
Descarga completa.

Ejecutando con los permisos suficientes para intentar mover faas-cli a /usr/local/bin
Nueva versión de faas-cli instalada en /usr/local/bin
Creando un alias 'faas' para 'faas-cli'.
  ___                   _____           ____
 / _  _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_  / _  '_ | |_ / _` |/ _` ___ 
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 ___/| .__ / ___|_| |_|_|  __,_|__,_|____/
      |_|

CLI:
 commit:  73004c23e5a4d3fdb7352f953247473477477a64
 versión: 0.11.3

Adicionalmente, se puede habilitar la función de finalización de bash:

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

Instalación y configuración de Kubernetes

Para el desarrollo, minikube es suficiente, así que lo instalaremos junto con kubelet en /usr/local/bin, y también instalaremos helm para la instalación de aplicaciones:

$ 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

Iniciamos minikube:

$ minikube start
  minikube v1.6.2 en Debian 8.11
  Controlador 'virtualbox' seleccionado automáticamente (alternativas: [])
  Descargando imagen de arranque de 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
  Creando VM de virtualbox (CPUs=2, Memoria=8192MB, Disco=20000MB) ...
  Preparando Kubernetes v1.17.0 en Docker '19.03.5' ...
  Descargando kubeadm v1.17.0
  Descargando kubelet v1.17.0
  Extrayendo imágenes ...
  Lanzando Kubernetes ...  Esperando a que el clúster esté en línea ...
  ¡Listo! kubectl ahora está configurado para usar "minikube"

Verificando:

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

Instalación de OpenFaaS

Los desarrolladores recomiendan crear 2 namespaces para trabajar:

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

Agregamos el repositorio para helm:

$ helm repo add openfaas https://openfaas.github.io/faas-netes/
"openfaas" se ha añadido a tus repositorios

En el chart se puede establecer una contraseña antes de la instalación, utilizaremos esta opción y guardaremos los datos de acceso como un secreto de 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 creado

Ejecutamos el despliegue:

$ helm repo update
Espera mientras obtenemos lo último de tus repositorios de charts...
...Actualización exitosa desde el repositorio de charts "openfaas"
Actualización completa. ¡Feliz Helm!
$ helm upgrade openfaas --install openfaas/openfaas --namespace openfaas --set functionNamespace=openfaas-fn --set generateBasicAuth=false
La liberación "openfaas" no existe. Instalándola ahora.
NOMBRE: openfaas
ULTIMA IMPLEMENTACIÓN: Vie Dic 25 10:28:22 2019
NAMESPACE: openfaas
ESTADO: desplegado
REVISION: 1
CONJUNTO DE PRUEBAS: Ninguno
NOTAS:
Para verificar que openfaas ha comenzado, ejecuta:

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

Después de un tiempo, ejecutamos el comando sugerido:

$ kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"
NOMBRE                READY   UP-TO-DATE   AVAILABLE   AGE
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

Verificamos el funcionamiento:

$ kubectl rollout status -n openfaas deploy/gateway
deployment "gateway" se implementó correctamente
$ kubectl port-forward -n openfaas svc/gateway 8080:8080 &
[1] 6985
Redirigiendo desde 127.0.0.1:8080 -> 8080
$ echo -n $PASSWORD | faas-cli login --username admin --password-stdin
Llamando al servidor OpenFaaS para validar las credenciales...
Manejando conexión para 8080
ADVERTENCIA! La comunicación no es segura, considere usar HTTPS. Letsencrypt.org ofrece certificados SSL/TLS gratuitos.
credenciales guardadas para admin http://127.0.0.1:8080
$ faas-cli list
Función                        Invocaciones     Réplicas

Instalación de Mongodb

Instalamos todo utilizando helm:

$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
"stable" se ha añadido a sus repositorios
$ helm install stable/mongodb --generate-name
NOMBRE: mongodb-1577466908
ULTIMA IMPLEMENTACIÓN: Vie Dic 25 11:15:11 2019
NAMESPACE: default
ESTADO: implementado
REVISION: 1
SUITE DE PRUEBA: Ninguna
NOTAS:
** Por favor, tenga paciencia mientras se realiza la implementación del chart **

MongoDB se puede acceder a través del puerto 27017 en el siguiente nombre DNS desde dentro de su clúster:

    mongodb-1577466908.default.svc.cluster.local

Para obtener la contraseña de root ejecute:

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

Para conectar a su base de datos ejecute el siguiente 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

Para conectar a su base de datos desde fuera del clúster ejecute los siguientes comandos:

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

Verificando:

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 no ve un símbolo del sistema, intente presionar enter.

> db.version();
4.0.14

Presione ctrl+D para salir del contenedor.

Configuración de emacs

En principio, ya estaba todo configurado según este artículo, así que no detallaré mucho.

División del juego en funciones

La interacción con las funciones se lleva a cabo a través del protocolo http, la autenticación entre diferentes funciones se asegura mediante JWT. Para almacenar tokens, así como el estado del juego, datos de los jugadores, secuencias de movimientos de todos los juegos y otra información se utiliza mongodb. Veamos más de cerca las funciones más interesantes.

Registro

La entrada de esta función es un JSON con un apodo de juego y una contraseña. Al llamar a esta función se verifica que este apodo no exista en la base de datos; tras la verificación exitosa, se inserta el apodo y el hash de la contraseña en la base de datos. El registro es necesario para participar activamente en el juego.

Entrada

La entrada de la función es un JSON con el apodo del jugador y la contraseña; si el apodo existe en la base de datos y la contraseña se valida correctamente con el registro guardado, se devuelve un JWT que debe ser pasado a otras funciones al ser llamadas. También se insertan diferentes registros de servicio en la base de datos, como la hora del último inicio de sesión, etc.

Ver lista de juegos

Cualquier usuario no autorizado puede solicitar la lista de todos los juegos, excepto los activos. El usuario autorizado también puede ver la lista de juegos activos. El resultado de la función es un JSON que contiene listas de juegos (identificador del juego, nombre legible para humanos, etc.).

Creación de un juego

La función solo funciona con usuarios autorizados, y recibe como entrada el número máximo de jugadores y los parámetros del juego (por ejemplo, qué personajes activar en este juego, el número máximo de jugadores, etc.). Un parámetro adicional del juego es la presencia de una contraseña para unirse, lo que permite crear juegos no públicos. Por defecto, se crea un juego público. El resultado de la función es un JSON que contiene un campo de éxito en la creación, un identificador único del juego, así como otros parámetros.

Unirse a un juego

La función solo funciona con usuarios autorizados; recibe como entrada el identificador del juego y su contraseña, si es un juego no público, y devuelve un JSON con los parámetros del juego. El usuario autorizado que se une al juego, así como el creador del juego, son llamados participantes del juego.

Ver eventos del juego

Cualquier usuario no autorizado puede solicitar la lista de eventos de juegos inactivos, mientras que un usuario autorizado puede obtener la lista de eventos de cualquier juego activo. Se puede pasar un parámetro adicional a la función que indique el número del evento que el usuario ya tiene. En este caso, en la lista se devolverán solo los eventos que ocurrieron después. Un usuario autorizado puede ver lo que está sucediendo en el juego al ejecutar periódicamente esta función. Además, esta función devuelve una solicitud de acción a la que el usuario puede reaccionar mediante la función de envío de eventos del juego.

Enviar evento del juego

La función solo funciona para los participantes del juego: se implementa la posibilidad de iniciar el juego, hacer un movimiento, votar, escribir un mensaje de texto que se muestra en la lista de eventos del juego, etc.
El usuario autorizado que creó el juego distribuye los roles a todos los participantes, incluido él mismo. Deben confirmar su rol utilizando esta misma función. Una vez que todos los roles están confirmados, el juego pasa automáticamente al modo noche.

Estadísticas del juego

La función solo funciona para los participantes del juego, muestra el estado del juego, la lista y el número de jugadores (seudónimos), roles y su estado (movimiento realizado o no), así como otra información. Al igual que para la función anterior, todo funciona solo para los participantes del juego.

Funciones ejecutadas periódicamente

Si el juego no ha sido iniciado durante un tiempo determinado al crear el juego, se eliminará automáticamente de la lista de juegos activos mediante la función de limpieza.

Otra tarea periódica es forzar el cambio del modo del juego de noche a día y viceversa para los juegos que no lo han hecho durante el movimiento (por ejemplo, un jugador que debe reaccionar a un evento del juego no ha enviado su decisión por alguna razón).

Anuncio

  • Introducción
  • Configuración del entorno de desarrollo, división de la tarea en funciones
  • Trabajo en el backend
  • Trabajo en el frontend
  • Configuración de CICD, organización de pruebas
  • Lanzamiento de una sesión de prueba del juego
  • Resultados

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster