«Нови Былины». Ядем слона на части

«Нови Былины». Ядем слона на части

В тази статия ще настроя работна среда за разработка на играта „Былины“ и ще разделя самата игра на части, които могат да се използват в OpenFaaS. Всички действия ще извършвам на Linux, а Kubernetes ще бъде инсталиран в minikube с помощта на VirtualBox. На моята работна машина има 2 процесорни ядра и 12 GB RAM, а за системен диск използвам SSD. Основната система за разработка ще бъде Debian 8, с инсталирани пакети emacs, sudo, git и virtualbox, а всичко останало ще инсталирам чрез изтегляне от GitHub и други източници. Тези приложения ще инсталираме в /usr/local/bin, освен ако не е указано друго. Начинат да действаме!

Подготовка на работната среда

Инсталиране на Go

Следваме инструкциите от официалния сайт:

$ 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

Проверка на функционирането:

$ 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

Инсталиране на faas-cli

Следваме инструкциите от официалния сайт:

$ curl -sSL https://cli.openfaas.com | sudo -E sh
x86_64
Изтегляне на пакета https://github.com/openfaas/faas-cli/releases/download/0.11.3/faas-cli като /tmp/faas-cli
Изтеглянето е завършено.

Изпълнение с достатъчни права за преместване на faas-cli в /usr/local/bin
Нова версия на faas-cli е инсталирана в /usr/local/bin
Създаване на алиас 'faas' за 'faas-cli'.
  ___                   _____           ____
 / _  _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_  / _  '_ | |_ / _` |/ _` ___ 
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 ___/| .__/% ___|_| |_|_|  __,_|__,_|____/
      |_|

CLI:
 commit:  73004c23e5a4d3fdb7352f953247473477477a64
 версия: 0.11.3

Допълнително, може да активирате работа с bash-completion:

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

Инсталиране и настройка на Kubernetes

За разработка, minikube е достатъчен, така че ще го инсталираме, както и kubelet в /usr/local/bin, за инсталиране на приложения ще инсталираме и 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

Стартиране на minikube:

$ minikube start
  minikube v1.6.2 на Debian 8.11
  Автоматично избран драйвер 'virtualbox' (алтернативи: [])
  Изтегляне на изображения за стартиране на 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
  Създаване на virtualbox VM (CPUs=2, Памет=8192MB, Диск=20000MB) ...
  Подготовка на Kubernetes v1.17.0 на Docker '19.03.5' ...
  Изтегляне на kubeadm v1.17.0
  Изтегляне на kubelet v1.17.0
  Изтегляне на изображения ...
  Стартиране на Kubernetes ... Изчакване на кластера да се включи ...
  Готово! kubectl е сега конфигуриран да използва "minikube"

Проверяваме:

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

Инсталиране на OpenFaaS

Разработчиците препоръчват да се създадат 2 namespace за работа:

$ kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
namespace/openfaas създаден
namespace/openfaas-fn създаден

Добавяме репозиторий за helm:

$ helm repo add openfaas https://openfaas.github.io/faas-netes/
"openfaas" е добавен към вашите репозитории

В чарта има възможност за задаване на парола преди инсталацията, ще я използваме и ще съхраним данните за достъп като секрет k8s:

$ PASSWORD=многосигуренслучайнапароларечени
$ kubectl -n openfaas create secret generic basic-auth --from-literal=basic-auth-user=admin --from-literal=basic-auth-password="$PASSWORD"
secret/basic-auth създаден

Извършваме разгръщане:

$ helm repo update
Изчакайте докато вземем най-новото от вашите хранилища за чартове...
...Успешно получено обновление от репозитория на "openfaas"
Актуализацията е завършена. Приятно хелминг!
$ helm upgrade openfaas --install openfaas/openfaas --namespace openfaas --set functionNamespace=openfaas-fn --set generateBasicAuth=false
Release "openfaas" не съществува. Инсталира се сега.
NAME: openfaas
LAST DEPLOYED: Пет Дек 25 10:28:22 2019
NAMESPACE: openfaas
STATUS: инсталиран
REVISION: 1
ТЕСТОВА ГРУПА: Няма
ЗАБЕЛЕЖКИ:
За да проверите, че openfaas е стартирал, изпълнете:

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

След известно време стартирайте предложената команда:

$ kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"
NAME                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

Проверка на функционирането:

$ 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     Replicas

Инсталиране на Mongodb

Инсталираме всичко с помощта на helm:

$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
"stable" е добавен към вашите хранилища
$ 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:
** Моля, бъдете търпеливи, докато графикът се инсталира **

MongoDB може да се достъпи на порт 27017 с помощта на следното име на DNS от вашия клъстер:

    mongodb-1577466908.default.svc.cluster.local

За да получите паролата на root, изпълнете:

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

За да се свържете с вашата база данни, изпълнете следната команда:

    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

За да се свържете с вашата база данни от външната страна на клъстера, изпълнете следните команди:

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

Проверяваме:

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)
Ако не виждате команден прозорец, опитайте да натиснете enter.

> db.version();
4.0.14

Натиснете ctrl+D за да излезете от контейнера.

Настройка на emacs

В принцип, всичко вече беше настроено по тази статия, така че няма да описвам подробно.

Разделяне на играта на функции

Взаимодействието с функциите се осъществява чрез http протокол, а съвместната аутентификация между различните функции се осигурява от JWT. За съхранение на токени, състоянието на играта, данните на играчите, последователностите на ходовете на всички игри и друга информация се използва mongodb. Нека разгледаме по-подробно най-интересните функции.

Регистрация

На входа на тази функция се подава JSON с игровия псевдоним и паролата. При извикване на тази функция се проверява дали този псевдоним не съществува в базата данни, а при успешна проверка — се въвежда псевдонима и хешираната парола в базата. Регистрацията е необходима за активно участие в играта.

Вход

На входа на функцията се подават JSON с игровия псевдоним и паролата. При наличието на псевдоним в базата данни и успешна проверка на паролата, връща се JWT, който трябва да се предава на другите функции при техния извик. Освен това, се извършва вмъкване в базата на различни служебни записи, например времето на последно влизане и т.н.

Преглед на списъка с игри

Всеки неавторизиран потребител може да поиска списък на всички игри, с изключение на активните. Авторизираният потребител също така вижда и списъка с активни игри. Резултатът от функцията е JSON, съдържащ списъци с игри (идентификатор на играта, четимо име и т.н.).

Създаване на игра

Функцията работи само с авторизирани потребители, на входа се приема максималният брой играчи, както и параметри на играта (например, кои персонажи да се активират в тази игра, максимален брой играчи и т.н.). Отделен параметър на играта е наличието на парола за присъединяване, което позволява създаването на непублични игри. По подразбиране се създава публична игра. Резултатът от изпълнението на функцията е JSON, в който има поле за успешност на създаването, уникален идентификатор на играта, както и други параметри.

Присъединяване към игра

Функцията работи само с авторизирани потребители, на входа — идентификатор на играта и нейния парола, ако това е непублична игра, на изхода — JSON с параметрите на играта. Авторизираният потребител, който се присъедини към играта, заедно с нейния създател, след това се наричат участници в играта.

Преглед на събитията на играта

Всеки неавторизиран потребител може да поиска списък с събития на неактивни игри, а авторизираният — да получи списък с събития на всяка активна игра. Допълнителният параметър на функцията може да предава номера на събитието, което потребителят вече има. В този случай в списъка ще бъдат върнати само тези събития, които са се случили по-късно. Периодично стартиране на тази функция позволява на авторизирания потребител да следи какво се случва в играта. Освен това, тази функция връща запитване за действие, на което потребителят може да реагира чрез функцията за изпращане на събитието на играта.

Изпращане на събитието на играта

Функцията работи само за участници в играта: реализира се възможност за стартиране на игра, правене на ход, гласуване, написване на текстово съобщение, което се показва в списъка на събитията в играта и т.н.
Авторизираният потребител, създал играта, стартира разпределението на роли на всички участници в играта, включително и на себе си, които трябва да потвърдят своята роля с помощта на същата функция. След като всички роли бъдат потвърдени, играта автоматично преминава в режим нощ.

Статистика на играта

Функцията работи само за участници в играта, показва състоянието на играта, списъка и броя на играчите (псевдоними), ролите и техния статус (дали е направен ход или не), както и друга информация. Както и за предишната функция, всичко работи само за участниците в играта.

Периодично стартирани функции

Ако играта не е била стартирана през определен период от време, посочен при създаването на играта — тя ще бъде автоматично премахната от списъка с активни игри с помощта на функция за почистване.

Още една периодична задача — принудително преминаване на режима на играта от нощ в ден и обратно за игри, при които това не се е случило по време на хода (например, играч, който трябва да реагира на игрово събитие, не е изпратил своето решение поради каквито и да е причини).

Анонс

  • Въведение
  • Настройка на среда за разработка, разделяне на задачите на функции
  • Работа по backend
  • Работа по frontend
  • Настройка на CICD, организиране на тестове
  • Стартиране на пробна сесия на играта
  • Резюме

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster