# Управляемые кластеры

Узнайте о управляемых кластерах и быстро начните работу с настраиваемыми бэкенд-решениями.

## ✔️ Введение

Управляемые кластеры упрощают и ускоряют размещение самостоятельно управляемых игровых сервисов и бэкенда. Вы готовите образ сервиса, а мы предоставляем высокодоступную, отказоустойчивую облачную среду для их запуска:

* аутентификация игроков,
* хранение данных - аккаунты, прогресс, инвентарь, награды, ...
* социальные сервисы - чат, кланы, таблицы лидеров, турниры, ...
* настраиваемый матчмейкинг - с использованием [#advanced-matchmaker](#advanced-matchmaker "mention"), [#nakama-by-heroic-labs](#nakama-by-heroic-labs "mention"), ...
* безсерверные вычисления - управляемые [функции как сервис](https://github.com/openfaas/faas) (альт. cloudscript, lambda), ...

Приватные кластеры гарантируют, что вашим сервисам обеспечен **выделённый вычислительный ресурс для обслуживания игроков 24/7**.

{% hint style="info" %}
Наши кластерные машины используют процессоры AMD/Intel с тактовой частотой 2.4 - 3.2 ГГц. Свяжитесь в [сообществе Discord](https://discord.gg/MmJf8fWjnt) чтобы согласовать нагрузочные тесты и убедиться, что вашему серверу доступно достаточное количество ресурсов.
{% endhint %}

## 🛠️ Инструменты разработчика

Если вы видите возможность улучшения, пожалуйста, сообщите нам в нашем [сообществе Discord](https://discord.gg/NgCnkHbsGp).

Мы надеемся, что вы получите плавный опыт. 🚀

### Docker

Чтобы сделать ваш сервер надёжным, мы используем [Docker](https://www.docker.com/) - программное обеспечение виртуализации, чтобы гарантировать, что все зависимости вашего серверного кода вплоть до уровня операционной системы всегда будут точно одинаковыми, вне зависимости от того, как и где запускается сервер.

### Kubernetes (K8s)

[Kubernetes](https://kubernetes.io/docs/concepts/overview/), также известный как K8s, — это система с открытым исходным кодом для автоматизации развертывания, масштабирования и управления контейнеризированными приложениями (Docker Images). Она группирует контейнеры, составляющие приложение, в логические единицы для лёгкого управления и обнаружения.

Управляемые кластеры Edgegap предоставляют Kubernetes API для административных задач.

### K8s Lens

С более чем 1 миллионом пользователей, [K8s Lens](https://k8slens.dev/) является самым популярным IDE для Kubernetes в мире. Подключайтесь к кластерам, исследуйте, получайте инсайты, изучайте и при необходимости предпринимаете действия. Lens предоставляет всю информацию о ваших нагрузках и ресурсах в реальном времени, всегда в нужном контексте.

Kubernetes API кластера Edgegap можно использовать через Lens или другие IDE для Kubernetes.

### Пакетный менеджер Helm

[Helm](https://helm.sh/) — лучший способ находить, делиться и использовать ПО, созданное для Kubernetes. Helm помогает управлять Kubernetes-приложениями — Helm Charts помогают определять, устанавливать и обновлять даже самые сложные Kubernetes-приложения. Charts легко создавать, версионировать, делиться и публиковать — так что начните использовать Helm и прекратите копировать и вставлять.

[Установка Helm CLI](https://helm.sh/docs/intro/install/) обеспечивает разработчикам простой интерфейс для управления пакетами кластера.

## 🚀 Начало работы

☑️ [Зарегистрировались для вашего бесплатного аккаунта Edgegap](https://app.edgegap.com/auth/register) и обновитесь до тарифа «плати по мере использования», чтобы разблокировать Кластеры.

☑️ Перейдите в [Управляемые кластеры](https://app.edgegap.com/cluster-management/clusters/list) страницу.

☑️ Нажмите на **Создать кластер** сначала, затем введите:

* **Метка** для вашего кластера, чтобы позже легко его найти,
* **Размер кластера -** см. [#introduction](#introduction "mention").

{% hint style="danger" %}
**Мы настоятельно рекомендуем создавать отдельные кластеры для сред разработки и продакшна.**
{% endhint %}

☑️ Просмотрите оценочную стоимость и нажмите **Создать кластер** чтобы запустить ваш новый кластер.

☑️ Как только кластер будет готов, **нажмите Kubeconfig, чтобы скачать вашу конфигурацию и учетные данные** для подключения и администрирования вашего нового кластера.

☑️ [Переместите файл kubeconfig](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) в `kubectl` чтобы он мог его найти.

☑️ Пользователи Lens: [импортируйте ваш файл kubeconfig](https://docs.k8slens.dev/getting-started/add-cluster/#specify-kubeconfig-files).

☑️ Проверьте подключение к кластеру командой `kubectl get nodes` :

```bash
kubectl get nodes
NAME                            STATUS   ROLES    AGE    VERSION
lke334087-533013-294dcfe70000   Ready    <none>   10m   v1.31.0
lke334087-533013-4e69edc10000   Ready    <none>   10m   v1.31.0
lke334087-533013-50bf39880000   Ready    <none>   10m   v1.31.0
```

🙌 Поздравляем, вы завершили настройку управляемого кластера! Теперь вы можете устанавливать ваши сервисы.

## 📦 Nakama от Heroic Labs

{% hint style="info" %}
Интегрируйте Edgegap с [плагином Nakama](https://github.com/edgegap/nakama-edgegap) + [плагином Unity](https://github.com/edgegap/edgegap-server-nakama-plugin-unity)! [Свяжитесь с нами по другим платформам/функциям.](https://discord.gg/NgCnkHbsGp)
{% endhint %}

Выполните следующие шаги, чтобы разместить свой собственный [Игровой бэкенд Nakama](https://heroiclabs.com/docs/nakama/getting-started/) в управляемых кластерах:

☑️ Создайте **DNS-запись типа A** у вашего провайдера DNS (например, [Cloudflare](https://developers.cloudflare.com/dns/get-started/)), запомните URL для дальнейшего использования. Ваш **внешний IP для DNS-записи** можно найти в Lens в разделе Services / `ingress-nginx-controller` .

☑️ Проверьте корректность настройки DNS, выполнив запрос [с помощью DNSchecker](https://dnschecker.org/ns-lookup.php).

☑️ Создайте файл с именем `values.yaml` со следующим содержимым (используйте свои значения):

<pre class="language-yaml"><code class="lang-yaml">isProductionEnvironment: true

# Внешнее имя хоста для сервера Nakama - DNS-запись из предыдущего шага
externalHostName: <a data-footnote-ref href="#user-content-fn-1">&#x3C;DNS_A_RECORD_URL></a>

nakama:
  # Версия Nakama для развертывания.
  # Смотрите https://hub.docker.com/r/heroiclabs/nakama/tags для доступных версий.
  version: 3.26.0
  # Имя пользователя и пароль для консоли Nakama
  username: <a data-footnote-ref href="#user-content-fn-2">&#x3C;USERNAME></a>
  password: <a data-footnote-ref href="#user-content-fn-3">&#x3C;PASSWORD></a>
</code></pre>

{% hint style="danger" %}
**Замените \<VALUES> выше на ваши собственные значения** в файле выше.
{% endhint %}

☑️ Разверните helm chart Nakama:

```bash
helm upgrade --install \
  --namespace nakama --create-namespace -f <FILE_PATH>/values.yaml \
  --version 1.0.0 <RELEASE_NAME> oci://registry-1.docker.io/edgegap/heroiclabs-nakama
```

☑️ Lens: проверьте установку в разделе Workloads / Deployments, `nakama` должен работать.

✅ **Подключитесь к вашей консоли Nakama** используя URL и учётные данные из `values.yaml` файла.

🙌 Поздравляем, вы завершили настройку самоуправляемого игрового бэкенда Nakama!

### Обновления сервиса

Выполните следующие шаги для обновления сервиса, размещённого в управляемом кластере:

☑️ Обновите ваш `файл value.yaml` с новыми данными.

☑️ Обновите ваш helm chart, используя эту команду:

```bash
helm upgrade --reuse-values \
  --namespace nakama -f <FILE_PATH>/values.yaml \
  --version 1.0.0 <RELEASE_NAME> oci://registry-1.docker.io/edgegap/heroiclabs-nakama
```

☑️ Перезагрузите изменения, завершив обновлённые поды — после этого будет использован новый helm chart, когда мы автоматически перезапустим поды.

🙌 Поздравляем, вы завершили обновление кластера Nakama!

## 👷 Продвинутый матчмейкер

Выполните следующие шаги, чтобы разместить ваш [OpenMatch](https://open-match.dev/site/) в управляемом кластере.

☑️ Создайте DNS-запись типа A у вашего провайдера DNS (например, [Cloudflare](https://developers.cloudflare.com/dns/get-started/)), запомните URL для дальнейшего использования. Ваш **внешний IP для DNS-записи** можно найти в Lens в разделе Services / `ingress-nginx-controller` .

☑️ Проверьте корректность настройки DNS, выполнив запрос [с помощью DNSchecker](https://dnschecker.org/ns-lookup.php).

☑️ Создайте файл с именем `values.yaml` со следующим содержимым (используйте свои значения):

```yaml
isProductionEnvironment: false

director:
  credential:
    registry: <YOUR_DIRECTOR_REGISTRY>
    username: <YOUR_DIRECTOR_REGISTRY_USERNAME>
    password: <YOUR_DIRECTOR_REGISTRY_PASSWORD>
  image: <DIRECTOR_IMAGE>
  env: {
    "KEY": "VALUE"
  }

mmf:
  credential:
    registry: <MATCHMAKER_FUNCTION_REGISTRY>
    username: <MATCHMAKER_FUNCTION_REGISTRY_USERNAME>
    password: <MATCHMAKER_FUNCTION_REGISTRY_PASSWORD>
  image: <MATCHMAKER_FUNCTION_IMAGE>
  env: {
    "KEY": "VALUE"
  }

frontend:
  credential:
    registry: <FRONTEND_REGISTRY>
    username: <FRONTEND_REGISTRY_USERNAME>
    password: <FRONTEND_REGISTRY_PASSWORD>
  externalHostName: <YOUR_CLOUDFLARE_HOST_NAME> # напр. exemple.test.com
  image: <FRONTEND_IMAGE>
  env: {
    "KEY": "VALUE"
  }

# Глобальные конфигурации, которые видны всем субчартам
global:
  kubernetes:
    resources:
      requests:
        memory: 100Mi
        cpu: 100m
      limits:
        memory: 100Mi
        cpu: 100m
```

{% hint style="danger" %}
**Замените \<VALUES> выше на ваши собственные значения** в файле выше.
{% endhint %}

☑️ Добавьте **репозиторий Edgegap** в список ваших репозиториев:

```bash
helm repo add edgegap-public https://registry.edgegap.com/chartrepo/edgegap-public
```

☑️ Разверните helm chart продвинутого матчмейкера:

```bash
helm upgrade --install \
  --namespace matchmaker --create-namespace -f <FILE_PATH>/values.yaml \
  --version 1.0.1 <RELEASE_NAME> edgegap-public/open-match-edgegap
```

🙌 Поздравляем, вы завершили настройку продвинутого матчмейкера!

### Обновления сервиса

Выполните следующие шаги для обновления сервиса, размещённого в управляемом кластере:

☑️ Обновите ваш `файл value.yaml` с новыми данными.

☑️ Обновите ваш helm chart, используя эту команду:

```bash
helm upgrade --reuse-values \
  --namespace matchmaker -f <FILE_PATH>/values.yaml \
  --version 1.0.1 <RELEASE_NAME> edgegap-public/open-match-edgegap
```

☑️ Перезагрузите изменения, завершив обновлённые поды (director, mmf, frontend), после чего будет использован новый helm chart, когда мы автоматически перезапустим поды.

🙌 Поздравляем, вы завершили обновление продвинутого матчмейкера!

### Непрерывное развертывание

Автоматизируйте обновление ваших сервисов, добавив этот shell-скрипт в ваш пайплайн развертывания:

```bash
#!/bin/bash

RELEASE_NAME="<RELEASE_NAME>"
NAMESPACE="matchmaker"  # Измените это, если вы сменили пространство имён.

helm upgrade --reuse-values -f <FILE_PATH>/value.yaml --namespace $NAMESPACE --version 1.0.1 $RELEASE_NAME edgegap-public/open-match-edgegap

echo "Установка redis-tools"
apt-get update
apt-get install -y redis-tools

DIRECTOR_DEPLOYMENT_NAME="$RELEASE_NAME-director"
MMF_DEPLOYMENT_NAME="$RELEASE_NAME-mmf"
CUSTOM_FRONTEND_DEPLOYMENT_NAME="$RELEASE_NAME-custom-frontend"
REDIS_HOST="$RELEASE_NAME-redis-master"

declare -A replicas

# Для каждого развертывания (director, mmf, custom-frontend) остановите поды
for deployment in $DIRECTOR_DEPLOYMENT_NAME $MMF_DEPLOYMENT_NAME $CUSTOM_FRONTEND_DEPLOYMENT_NAME
do
  echo "Остановка подов для развертывания: $deployment"
  replicas[$deployment]=$(kubectl get deployment $deployment -o=jsonpath='{.spec.replicas}' --namespace $NAMESPACE)
  kubectl scale deployment/$deployment --replicas=0 --namespace $NAMESPACE
done

# Ожидание завершения подов
for deployment in $DIRECTOR_DEPLOYMENT_NAME $MMF_DEPLOYMENT_NAME $CUSTOM_FRONTEND_DEPLOYMENT_NAME
do

  echo "Ожидание завершения подов для развертывания: $deployment"
  kubectl wait --for=delete pod -l app=$deployment --timeout=60s --namespace $NAMESPACE

  # Проверьте, успешно ли выполнилась команда ожидания. Если нет, завершите скрипт
  if [ $? -ne 0 ]; then
    echo "Не удалось дождаться завершения подов для развертывания: $deployment"
    exit 1
  fi
done

# Очистка базы данных redis
echo "Очистка базы данных redis"
redis-cli -h $REDIS_HOST flushall

# Для каждого развертывания (director, mmf, custom-frontend) восстановите количество подов до исходного
for deployment in $DIRECTOR_DEPLOYMENT_NAME $MMF_DEPLOYMENT_NAME $CUSTOM_FRONTEND_DEPLOYMENT_NAME
do
  echo "Изменение количества подов на ${replicas[$deployment]} для развертывания: $deployment"
  kubectl scale deployment/$deployment --replicas=${replicas[$deployment]} --namespace $NAMESPACE
done
```

### Проверка сертификата Letsencrypt (C#)

Для некоторых клиентов рекомендованная проверка сертификата Letsencrypt может завершаться с ошибкой:

```bash
Curl error 60: Cert verify failed. Certificate has expired. UnityTls error code: 7
```

{% hint style="success" %}
Обновление операционной системы может решить проблемы с устаревшим корневым центром сертификации.
{% endhint %}

В крайнем случае игровые клиенты могут реализовать пользовательскую функцию обработки сертификата:

````csharp
```csharp
public class CustomCertificateHandler : CertificateHandler
{
  private readonly string EXPECTED_CERT = "-----BEGIN CERTIFICATE-----<key>-----END CERTIFICATE-----\r\n";
  protected override bool ValidateCertificate(byte[] certificateData)
  {
    X509Certificate2 certificate = new X509Certificate2(certificateData);
    X509Certificate2 expectedCert = new X509Certificate2(Encoding.ASCII.GetBytes(EXPECTED_CERT));

    using (SHA256 sha256 = SHA256.Create())
    {
      Debug.Log("certificate.Thumbprint: " + certificate.Thumbprint);
      Debug.Log("expectedCert.Thumbprint: " + expectedCert.Thumbprint);

      return certificate.Thumbprint == expectedCert.Thumbprint;
    }
  }
}
```
````

Использование:

```csharp
UnityWebRequest request = UnityWebRequest.Get(...);
request.certificateHandler = new BypassCertificateHandler();
request.SendWebRequest();
request.certificateHandler.Dispose();
```

Мы рекомендуем хранить значение `EXPECTED_CERT` в вашем собственном хранилище файлов и получать его во время выполнения, чтобы вы могли обновлять его без выпуска обновления игрового клиента.

## 🟢 Операции и наблюдаемость

### Изменения уровня кластера

Подготовьтесь к успеху и оптимизируйте после запуска, чтобы не блокировать игроков в день релиза.

{% hint style="warning" %}
&#x20;Изменение размера кластера требует остановки кластера. Смотрите [развёртывание blue/green](https://circleci.com/blog/canary-vs-blue-green-downtime/) для обновлений без простоя.
{% endhint %}

### Поддержка и будущие обновления

**Ваш успех — наш приоритет.** Если вы хотите отправить пользовательские запросы, попросить отсутствующие критические функции или поделиться любыми мыслями, [пожалуйста, свяжитесь с нами в нашем сообществе Discord](https://discord.gg/MmJf8fWjnt).

[^1]: DNS-запись из предыдущего шага

[^2]: выберите собственное имя администратора

[^3]: выберите надёжный пароль для администратора
