> For the complete documentation index, see [llms.txt](https://docs.edgegap.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.edgegap.com/ru/learn/advanced-features/managed-clusters.md).

# Managed Clusters

Запускайте собственные backend-сервисы на управляемых кластерах Edgegap с быстрым стартом для интеграции вашей инфраструктуры.

Узнайте о Managed Clusters и быстро начните работу с пользовательскими backend-решениями.

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

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

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

{% hint style="success" %}
Смотрите [Матчмейкинг](/ru/learn/matchmeiking.md) и [Браузер серверов](/ru/learn/brauzer-serverov.md) чтобы начать интеграцию клиентской части игры.
{% endhint %}

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

В настоящее время мы предлагаем [3 уровня частных кластеров](https://edgegap.com/resources/pricing#managed-infrastructure) для любых потребностей:

<table><thead><tr><th width="160">Уровень</th><th align="right">Любительский уровень</th><th align="right">Студийный уровень</th><th align="right">Корпоративный уровень</th></tr></thead><tbody><tr><td>Лучше всего подходит для</td><td align="right">энтузиасты,<br>разработчики-одиночки</td><td align="right">коммерческие релизы</td><td align="right">запуски с высоким трафиком</td></tr><tr><td>Ограничение частоты запросов (запросов/с)</td><td align="right">200</td><td align="right">750</td><td align="right">2,000</td></tr><tr><td>Ресурсы</td><td align="right">1 vCPU + 2 ГБ ОЗУ</td><td align="right">6 vCPU + 12 ГБ ОЗУ</td><td align="right">18 vCPU + 48 ГБ ОЗУ</td></tr><tr><td>Резервирование</td><td align="right">1 виртуальный узел</td><td align="right">3 виртуальных узла</td><td align="right">3 виртуальных узла</td></tr><tr><td>Цена, за час</td><td align="right">$0.0312</td><td align="right"> $0.146</td><td align="right">$0.548</td></tr><tr><td><strong>Цена, за 30 дней</strong><br>(непрерывное использование)</td><td align="right"><strong>$22.464</strong></td><td align="right"><strong>$105.12</strong></td><td align="right"><strong>$394.56</strong></td></tr></tbody></table>

{% hint style="info" %}
Наши кластеры используют облачные машины с процессорами AMD/Intel с тактовой частотой до 3,7 ГГц.
{% endhint %}

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

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

Надеемся, вам понравится плавный опыт. 🚀

### Docker

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

{% hint style="info" %}
Мы рекомендуем посмотреть [«Никогда не устанавливайте локально» (видео)](https://www.youtube.com/watch?v=J0NuOlA2xDc\&ab_channel=Coderized). **Вам НЕ нужно использовать Dockerhub с Docker**.  Docker ≠ Dockerhub. Думайте о Docker как о движке для программирования, а о Dockerhub — как о его магазине приложений.
{% endhint %}

### Kubernetes (K8s)

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

Edgegap Managed Clusters предоставляют Kubernetes API для целей администрирования.

### K8s Lens

Более чем с 1 миллионом пользователей, [K8s Lens](https://k8slens.dev/) — это самая популярная Kubernetes IDE в мире. Подключайтесь к кластерам, изучайте их, получайте информацию, учитесь и при необходимости предпринимайте действия. 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) и перейдите на тариф pay-as-you-go, чтобы разблокировать Clusters.

☑️ Перейдите на страницу [Managed Clusters](https://app.edgegap.com/cluster-management/clusters/list) .

☑️ Нажмите **Create Cluster** сначала, затем введите:

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

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

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

☑️ После того как кластер будет готов, **нажмите 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
```

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

## 📦 Nakama от Heroic Labs

{% hint style="success" %}
См. [Managed Clusters](/ru/learn/advanced-features/managed-clusters.md#getting-started) перед настройкой ваших служб на управляемых кластерах.
{% endhint %}

{% 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 %}

Следуйте этим шагам, чтобы разместить свой собственный [игровой backend Nakama](https://heroiclabs.com/docs/nakama/getting-started/) на Managed Clusters:

☑️ Установите **Диспетчер сертификатов** для поддержки использования HTTPS-запросов от игровых клиентов:

```bash
helm repo add jetstack https://charts.jetstack.io --force-update;
helm upgrade --install cert-manager jetstack/cert-manager \
  --namespace cert-manager --create-namespace \
  --version v1.16.1 --set crds.enabled=true;
```

☑️ Lens: проверьте установку в разделе Services / Network, `cert-manager` должен работать.

☑️ Создайте **Cluster Issuer** файл, не забудьте заменить `<YOUR_EMAIL>` ниже:

<pre class="language-yaml"><code class="lang-yaml">apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
  namespace: cert-manager
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: <a data-footnote-ref href="#user-content-fn-1">&#x3C;YOUR_EMAIL></a>
    privateKeySecretRef:
      name: <a data-footnote-ref href="#user-content-fn-2">letsencrypt-staging</a>
    solvers:
    - http01:
        ingress:
          class: nginx
          
</code></pre>

{% hint style="danger" %}
Используйте `letsencrypt-prod` для вашего продакшн-кластера `privateKeySecretRef`.
{% endhint %}

☑️ Создайте **Cluster Issuer** в командной строке:

```bash
kubectl create -f <FILE_PATH>/issuer.yaml
```

☑️ Lens: проверьте установку в разделе Custom Resources / `cert-manager.io` - cluster issuer создан.

☑️ Установите **nginx Ingress** для приема клиентских запросов и передачи их сервисам в кластере:

```
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx --create-namespace
```

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

☑️ Создайте **запись 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

# Внешний hostname для сервера Nakama - запись DNS из предыдущего шага
externalHostName: <a data-footnote-ref href="#user-content-fn-3">&#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-4">&#x3C;USERNAME></a>
  password: <a data-footnote-ref href="#user-content-fn-5">&#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` файла.

🙌 Поздравляем, вы завершили настройку self-hosted Nakama Game Backend!

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

Следуйте этим шагам, чтобы обновить ваш сервис, размещенный в Managed Cluster:

☑️ Обновите ваш `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
```

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

{% hint style="warning" %}
Это **Это обновление приведёт к короткому простою** пока поды перезапускаются.
{% endhint %}

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

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

{% hint style="success" %}
См. [Managed Clusters](/ru/learn/advanced-features/managed-clusters.md#getting-started) перед настройкой ваших служб на управляемых кластерах.
{% endhint %}

Следуйте этим шагам, чтобы разместить ваш [OpenMatch](https://open-match.dev/site/) в Managed Cluster.

☑️ Установите **Диспетчер сертификатов** для поддержки использования HTTPS-запросов от игровых клиентов:

```bash
helm repo add jetstack https://charts.jetstack.io --force-update;
helm upgrade --install cert-manager jetstack/cert-manager \
  --namespace cert-manager --create-namespace \
  --version v1.16.1 --set crds.enabled=true;
```

☑️ Lens: проверьте установку в разделе Services / Network, `cert-manager` должен работать.

☑️ Создайте **Cluster Issuer** файл, не забудьте заменить `<YOUR_EMAIL>` ниже:

<pre class="language-yaml"><code class="lang-yaml">apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
  namespace: cert-manager
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: <a data-footnote-ref href="#user-content-fn-1">&#x3C;YOUR_EMAIL></a>
    privateKeySecretRef:
      name: <a data-footnote-ref href="#user-content-fn-2">letsencrypt-staging</a>
    solvers:
    - http01:
        ingress:
          class: nginx
          
</code></pre>

{% hint style="danger" %}
Используйте `letsencrypt-prod` для вашего продакшн-кластера `privateKeySecretRef`.
{% endhint %}

☑️ Создайте **Cluster Issuer** в командной строке:

```bash
kubectl create -f <FILE_PATH>/issuer.yaml
```

☑️ Lens: проверьте установку в разделе Custom Resources / `cert-manager.io` - cluster issuer создан.

☑️ Установите **nginx Ingress** для приема клиентских запросов и передачи их сервисам в кластере:

```
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx --create-namespace
```

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

☑️ Создайте запись 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> # e.g. 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
```

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

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

Следуйте этим шагам, чтобы обновить ваш сервис, размещенный в Managed Cluster:

☑️ Обновите ваш `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
```

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

{% hint style="warning" %}
Это **Это обновление приведёт к короткому простою** пока поды перезапускаются.
{% endhint %}

🙌 Поздравляем, вы завершили обновление Advanced Matchmaker!

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

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

```bash
#!/bin/bash

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

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) остановите pods
for deployment in $DIRECTOR_DEPLOYMENT_NAME $MMF_DEPLOYMENT_NAME $CUSTOM_FRONTEND_DEPLOYMENT_NAME
do
  echo "Остановка pods для развертывания: $deployment"
  replicas[$deployment]=$(kubectl get deployment $deployment -o=jsonpath='{.spec.replicas}' --namespace $NAMESPACE)
  kubectl scale deployment/$deployment --replicas=0 --namespace $NAMESPACE
done

# Подождите, пока pods будут завершены
for deployment in $DIRECTOR_DEPLOYMENT_NAME $MMF_DEPLOYMENT_NAME $CUSTOM_FRONTEND_DEPLOYMENT_NAME
do

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

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

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

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

{% hint style="warning" %}
Это **Это обновление приведёт к короткому простою** пока поды перезапускаются.
{% endhint %}

### Проверка сертификата Let's Encrypt (C#)

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

```bash
Ошибка Curl 60: проверка сертификата не удалась. Срок действия сертификата истек. Код ошибки UnityTls: 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 deployment](https://circleci.com/blog/canary-vs-blue-green-downtime/) для обновлений без простоя.
{% endhint %}

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

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

[^1]: замените на свой email

[^2]: используйте letsencrypt-prod для продакшна

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

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

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