„Nowe Byliny”. Jemy słonia po kawałkach.

„Nowe Byliny”. Jemy słonia po kawałkach.

W tym artykule skonfiguruję środowisko do tworzenia gry „Byliny”, a także podzielę samą grę na części nadające się do użycia w OpenFaaS. Wszystkie operacje wykonam w systemie Linux, Kubernetes uruchomię w minikube przy użyciu VirtualBox. Moja maszyna robocza ma 2 rdzenie procesora i 12 GB pamięci RAM, jako dysk systemowy używam SSD. Jako główny system do rozwoju będę korzystał z debiana 8, z zainstalowanymi pakietami emacs, sudo, git i virtualbox, wszystkie inne zainstaluję pobierając z GitHub i innych źródeł. Te aplikacje zainstalujemy w /usr/local/bin, chyba że zaznaczone jest inaczej. Zaczynamy!

Przygotowanie środowiska roboczego

Instalacja Go

Postępujemy zgodnie z instrukcjami na oficjalnej stronie:

$ 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

Sprawdzamy działanie:

$ 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

Instalacja faas-cli

Postępujemy zgodnie z instrukcjami na oficjalnej stronie:

$ curl -sSL https://cli.openfaas.com | sudo -E sh
x86_64
Pobieranie paczki https://github.com/openfaas/faas-cli/releases/download/0.11.3/faas-cli jako /tmp/faas-cli
Pobieranie zakończone.

Uruchamianie z wystarczającymi uprawnieniami, aby spróbować przenieść faas-cli do /usr/local/bin
Nowa wersja faas-cli zainstalowana w /usr/local/bin
Tworzenie aliasu 'faas' dla 'faas-cli'.
  ___                   _____           ____
 / _  _ __   ___ _ __ |  ___|_ _  __ _/ ___|
| | | | '_  / _  '_ | |_ / _` |/ _` ___ 
| |_| | |_) |  __/ | | |  _| (_| | (_| |___) |
 ___/| .__ / ___|_| |_|_|  __,_|__,_|____/
      |_|

CLI:
 commit:  73004c23e5a4d3fdb7352f953247473477477a64
 wersja: 0.11.3

Dodatkowo można włączyć działanie bash-completion:

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

Instalacja i konfiguracja Kubernetes

Do rozwoju wystarczy minikube, więc zainstalujemy go oraz kubelet w /usr/local/bin, a także zainstalujemy 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

Uruchamiamy minikube:

$ minikube start
  minikube v1.6.2 na Debianie 8.11
  Automatycznie wybrano sterownik 'virtualbox' (alternatywy: [])
  Pobieranie obrazu startowego 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
  Tworzenie VM w virtualbox (CPU=2, Pamięć=8192MB, Dysk=20000MB) ...
  Przygotowywanie Kubernetes v1.17.0 na Docker '19.03.5' ...
  Pobieranie kubeadm v1.17.0
  Pobieranie kubelet v1.17.0
  Pobieranie obrazów ...
  Uruchamianie Kubernetes ...  Czekam na uruchomienie klastra ...
  Zrobione! kubectl jest teraz skonfigurowany do użycia "minikube"

Sprawdzamy:

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

Instalacja OpenFaaS

Zaleceniem deweloperów jest stworzenie 2 przestrzeni nazw do pracy:

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

Dodajemy repozytorium dla helm:

$ helm repo add openfaas https://openfaas.github.io/faas-netes/
"openfaas" zostało dodane do Twoich repozytoriów

W chartach jest możliwość ustawienia hasła przed instalacją, skorzystajmy z tej opcji i zapiszmy dane dostępu jako sekret 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 utworzony

Przystępujemy do wdrożenia:

$ helm repo update
Proszę czekać, podczas gdy pobieramy najnowsze z Twoich repozytoriów chartów...
...Sukces! Zaktualizowano repozytorium charta "openfaas"
Aktualizacja zakończona. Miłego korzystania z Helma!
$ helm upgrade openfaas --install openfaas/openfaas --namespace openfaas --set functionNamespace=openfaas-fn --set generateBasicAuth=false
Wydanie "openfaas" nie istnieje. Instalacja teraz.
NAZWA: openfaas
OSTATNIO WDROŻONE: Pt, 25 gru 2019 10:28:22
PRZESTRZEŃ NAZW: openfaas
STATUS: wdrożono
REWIZJA: 1
ZESTAW TESTOWY: Brak
NOTATKI:
Aby zweryfikować, że openfaas został uruchomiony, uruchom:

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

Po pewnym czasie uruchommy sugerowaną komendę:

$ kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"
NAZWA                GOTOWY   ZGODNY ZAKRES   DOSTĘPNY   WIEK
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

Sprawdzamy działanie:

$ 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
Ostrzeżenie! Komunikacja nie jest zabezpieczona, rozważ użycie HTTPS. Letsencrypt.org oferuje darmowe certyfikaty SSL/TLS.
credentials saved for admin http://127.0.0.1:8080
$ faas-cli list
Funkcja                        Wywołania     Repliki

Instalacja Mongodb

Instalujemy wszystko przy użyciu helm:

$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
"stable" zostało dodane do twoich repozytoriów
$ helm install stable/mongodb --generate-name
NAZWA: mongodb-1577466908
OSTATNIE WDRUŻENIE: Pią 25 Gru 11:15:11 2019
NAMESPACE: default
STATUS: wdrążony
REVISION: 1
TEST SUITE: Brak
NOTATKI:
** Proszę być cierpliwym podczas wdrażania wykresu **

MongoDB można uzyskać poprzez port 27017 pod następującą nazwą DNS z wnętrza klastra:

    mongodb-1577466908.default.svc.cluster.local

Aby uzyskać hasło administratora, uruchom:

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

Aby połączyć się z bazą danych, uruchom następujące polecenie:

    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

Aby połączyć się z bazą danych z zewnątrz klastra, wykonaj następujące polecenia:

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

Sprawdzamy:

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)
Jeśli nie widzisz zaproszenia do polecenia, spróbuj nacisnąć enter.

> db.version();
4.0.14

Naciśnij ctrl+D, aby wyjść z kontenera.

Konfiguracja emacsa

W zasadzie, wszystko było już skonfigurowane po w tym artykule, więc nie będę szczegółowo opisywał.

Podział gry na funkcje

Interakcja z funkcjami odbywa się za pośrednictwem protokołu http, a pełna autoryzacja między różnymi funkcjami zapewniana jest przez JWT. Do przechowywania tokenów, a także stanu gry, danych graczy, sekwencji ruchów wszystkich gier i innych informacji używana jest mongodb. Przyjrzyjmy się bliżej najciekawszym funkcjom.

Rejestracja

Na wejściu tej funkcji — JSON z pseudonimem i hasłem do gry. Po wywołaniu tej funkcji wykonywana jest weryfikacja, czy ten pseudonim nie istnieje w bazie danych; po udanej weryfikacji następuje wstawienie pseudonimu i hasza hasła do bazy. Rejestracja jest niezbędna do aktywnego uczestnictwa w grze.

Wstęp

Funkcja przyjmuje JSON z pseudonimem gracza i hasłem; jeśli pseudonim znajduje się w bazie i hasło zostało pomyślnie potwierdzone, zwracany jest JWT, który należy przekazać innym funkcjom przy ich wywoływaniu. Wykonywana jest również insercja różnych rejestrów pomocniczych do bazy, na przykład czasu ostatniego logowania itp.

Przeglądanie listy gier

Każdy nieautoryzowany użytkownik może zażądać listy wszystkich gier, z wyjątkiem aktywnych. Użytkownik autoryzowany widzi również listę gier aktywnych. Wynikiem funkcji jest JSON zawierający listy gier (identyfikator gry, czytelna nazwa itd.).

Tworzenie gry

Funkcja działa tylko z użytkownikami autoryzowanymi, przyjmuje maksymalną liczbę graczy oraz parametry gry (na przykład, jakie postacie aktywować w tej grze, maksymalna liczba graczy itp.). Oddzielnym parametrem gry jest posiadanie hasła do dołączenia, co pozwala na tworzenie gier niepublicznych. Domyślnie tworzona jest gra publiczna. Wynikiem wykonania funkcji jest JSON, który zawiera pole z informacją o powodzeniu utworzenia, unikalny identyfikator gry oraz inne parametry.

Dołączenie do gry

Funkcja działa tylko z użytkownikami autoryzowanymi; przyjmuje identyfikator gry oraz jej hasło, jeśli jest to gra niepubliczna, a na wyjściu zwraca JSON z parametrami gry. Użytkownik autoryzowany, który dołączył do gry, oraz jej twórca nazywani są uczestnikami gry.

Przeglądanie wydarzeń gry

Każdy nieautoryzowany użytkownik może zażądać listy wydarzeń nieaktywnych gier, a użytkownik autoryzowany może otrzymać listę wydarzeń każdej aktywnej gry. Dodatkowym parametrem funkcji może być numer wydarzenia, który już posiada użytkownik. W takim przypadku w liście zwrócone zostaną tylko te wydarzenia, które miały miejsce później. Okresowo uruchamiając tę funkcję, użytkownik autoryzowany może sprawdzić, co się dzieje w grze. Ta funkcja zwraca również zapytanie o akcję, na którą użytkownik może zareagować za pomocą funkcji wysyłania wydarzenia gry.

Wysyłanie wydarzenia gry

Funkcja działa tylko dla uczestników gry: umożliwia rozpoczęcie gry, wykonanie ruchu, głosowanie, napisanie wiadomości tekstowej, która jest wyświetlana w liście wydarzeń gry itp.
Autoryzowany użytkownik, który stworzył grę, rozpoczyna rozdawanie ról wszystkim uczestnikom gry, w tym sobie, muszą oni potwierdzić swoją rolę za pomocą tej samej funkcji. Gdy wszystkie role są potwierdzone, gra automatycznie przechodzi w tryb nocy.

Statystyka gry

Funkcja działa tylko dla uczestników gry, pokazuje stan gry, listę i liczbę graczy (pseudonimy), role i ich status (czy ruch został wykonany, czy nie), a także inne informacje. Podobnie jak w przypadku poprzedniej funkcji, wszystko działa tylko dla uczestników gry.

Okresowo uruchamiane funkcje

Jeśli gra nie została uruchomiona przez pewien czas określony podczas tworzenia gry — zostanie automatycznie usunięta z listy aktywnych gier za pomocą funkcji oczyszczania.

Jeszcze jedno okresowe zadanie — wymuszone przełączenie trybu gry z nocy na dzień i z powrotem dla gier, które tego nie zrobiły w trakcie ruchu (na przykład gracz, który miał zareagować na wydarzenie w grze, nie wysłał swojej decyzji z jakiegoś powodu).

Ogłoszenie

  • Wprowadzenie
  • Ustawienie środowiska do rozwoju, podział zadania na funkcje
  • Prace nad backendem
  • Prace nad frontendem
  • Konfiguracja CICD, organizacja testowania
  • Uruchomienie próbnej sesji gry
  • Podsumowanie

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster