В этой статье я буду настраивать рабочее окружение для разработки игры «Былины», а также выполню разбиение самой игры на части, пригодные для использования в OpenFaaS. Все манипуляции буду делать на Linux, Kubernetes буду разворачивать в minikube с использованием VirtualBox. В моей рабочей машине 2 процессорных ядра и 12гб оперативной памяти, в качестве системного диска я применяю SSD. В качестве основной системы для разработки буду использовать debian 8, с установленными пакетами emacs, sudo, git и virtualbox, все остальное установлю путем скачивания из GitHub и других источников. Эти приложения будем устанавливать в /usr/local/bin, если не указано другое. Приступим!
Разработчики рекомендуют создать 2 namespace для работы:
$ kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
namespace/openfaas created
namespace/openfaas-fn created
Добавляем репозиторий для helm:
$ helm repo add openfaas https://openfaas.github.io/faas-netes/
"openfaas" has been added to your repositories
В чарте есть возможность задать пароль перед установкой, воспользуемся ею и сохраним данные доступа в виде секрета k8s:
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "openfaas" chart repository
Update Complete. Happy Helming!
$ helm upgrade openfaas --install openfaas/openfaas --namespace openfaas --set functionNamespace=openfaas-fn --set generateBasicAuth=false
Release "openfaas" does not exist. Installing it now.
NAME: openfaas
LAST DEPLOYED: Fri Dec 25 10:28:22 2019
NAMESPACE: openfaas
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
To verify that openfaas has started, run:
kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"
Спустя некоторое время запускаем предложенную команду:
$ 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" 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 can be accessed via port 27017 on the following DNS name from within your cluster:
mongodb-1577466908.default.svc.cluster.local
To get the root password run:
export MONGODB_ROOT_PASSWORD=$(kubectl get secret --namespace default mongodb-1577466908 -o jsonpath="{.data.mongodb-root-password}" | base64 --decode)
To connect to your database run the following command:
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
To connect to your database from outside the cluster execute the following commands:
kubectl port-forward --namespace default svc/mongodb-1577466908 27017:27017 &
mongo --host 127.0.0.1 --authenticationDatabase admin -p $MONGODB_ROOT_PASSWORD
Aħna niċċekkjaw:
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)
If you don't see a command prompt, try pressing enter.
> db.version();
4.0.14
Жмем ctrl+D для выхода из контейнера.
Настройка emacs
В принципе, все было уже настроено по Dan l-artikolu, так что не буду подробно расписывать.
Разбиение игры на функции
Взаимодействие с функциями осуществляется посредством протокола http, сквозная аутентификация между разными функциями обеспечивается JWT. Для хранения токенов, а также состояния игры, данных игроков, последовательностей ходов всех игр и другой информации используется mongodb. Давайте рассмотрим детальнее наиболее интересные функции.
Reġistrazzjoni
На входе этой функции — JSON с игровым псевдонимом и паролем. При вызове этой функции выполняется проверка отсутствия этого псевдонима в базе данных, при успешной проверке — вставка псевдонима и хэша пароля в базу. Регистрация необходима для активного участия в игре.
Input
На входе функции — JSON с игровым псевдонимом и паролем, при наличии псевдонима в базе и успешной проверке пароля с сохраненным ранее в базе возвращается JWT, который надо передавать другим функциям при их вызове. Также выполняется вставка в базу разных служебных записей, к примеру времени последнего входа и т.п.
Просмотр списка игр
Любой неавторизованный пользователь может запросить список всех игр, кроме активных. Авторизованный пользователь также видит и список активных игр. Результат функции — JSON, содержащий списки игр (идентификатор игры, человекочитаемое имя и т.п.).
Ħolqien tal-logħob
Функция работает только с авторизованными пользователями, на входе принимается максимальное число игроков, а также параметры игры (например, каких персонажей активировать в этой игре, максимальное число игроков и т.п.). Отдельным параметром игры является наличие пароля на присоединение, что позволяет создать непубличные игры. По-умолчанию создается публичная игра. Результатом выполнения функции является JSON, в котором есть поле успешности создания, уникальный идентификатор игры, а также другие параметры.
Tgħaqqad logħba
Функция работает только с авторизованными пользователями, на входе — идентификатор игры и ее пароль, если это непубличная игра, на выходе — JSON с параметрами игры. Авторизованный пользователь, присоединившийся к игре, а также создатель игры далее зовутся участниками игры.
Просмотр событий игры
Любой неавторизованный пользователь может запросить список событий неактивных игр, а авторизованный — получить список событий и любой активной игры. Дополнительным параметром функции может передаваться номер события, который уже есть у пользователя. В этом случае в списке вернутся только те события, которые произошли позднее. Периодически запуская эту функцию авторизованный пользователь смотрит, что происходит в игре. Также эта функция возвращает запрос на действие, на которое пользователь может отреагировать с помощью функции отправки события игры.
Отправка события игры
Функция работает только для участников игры: реализуется возможность запустить игру, сделать ход, проголосовать, написать текстовое сообщение, которое отображается в списке событий игры и т.п.
Авторизованный пользователь, создавший игру, запускает раздачу ролей всем участникам игры, включая себя, они должны подтвердить свою роль с помощью этой же функции. Как только все роли подтверждены, игра автоматически переходит в режим ночи.
Статистика игры
Функция работает только для участников игры, показывает состояние игры, список и число игроков (псевдонимы), роли и их статус (сделан ход, или нет), а также другую информацию. Как и для предыдущей функции, все работает только для участников игры.
Периодически запускаемые функции
Если игра не была запущена в течение некоторого времени, указанного при создании игры — она будет автоматически удалена из списка активных игр с помощью функции зачистки.
Еще одна периодическая задача — принудительное переключение режима игры с ночи в день и обратно для игр, у которых этого не произошло во время хода (к примеру, игрок, которому надо отреагировать на игровое событие, не прислал свое решение по каким-либо причинам).