# Clusters gérés

En savoir plus sur les clusters gérés et commencer rapidement avec des solutions back-end personnalisées.

## ✔️ Introduction

Les clusters gérés facilitent et accélèrent l'hébergement de services de jeu autogérés et de backends de jeu. Vous préparez l'image du service et nous fournissons un environnement cloud résilient et à haute disponibilité pour les exécuter :

* authentification des joueurs,
* stockage de données - comptes, progression, inventaire, récompenses, ...
* services sociaux - chat, clans, tableaux de classement, tournois, ...
* matchmaking personnalisé - en utilisant [#advanced-matchmaker](#advanced-matchmaker "mention"), [#nakama-by-heroic-labs](#nakama-by-heroic-labs "mention"), ...
* calcul sans serveur - géré [fonctions en tant que service](https://github.com/openfaas/faas) (alt. cloudscript, lambda), ...

Les clusters privés garantissent que vos services disposent de **des ressources de calcul dédiées pour servir vos joueurs 24/7**.

{% hint style="info" %}
Nos machines de cluster utilisent des CPU AMD/Intel avec une fréquence de 2,4 - 3,2 GHz. Contactez-nous sur [Discord Communautaire](https://discord.gg/MmJf8fWjnt) pour coordonner les tests de charge et pour vous assurer que votre serveur dispose des ressources suffisantes disponibles.
{% endhint %}

## 🛠️ Outils pour développeurs

Si vous voyez une opportunité d'amélioration, veuillez nous en informer dans notre [Discord Communautaire](https://discord.gg/NgCnkHbsGp).

Nous espérons que vous apprécierez une expérience fluide. 🚀

### Docker

Pour aider à rendre votre serveur fiable, nous utilisons [Docker](https://www.docker.com/) - un logiciel de virtualisation garantissant que toutes les dépendances du code serveur jusqu'au niveau du système d'exploitation seront toujours exactement les mêmes, peu importe comment ou où le serveur est lancé.

### Kubernetes (K8s)

[Kubernetes](https://kubernetes.io/docs/concepts/overview/), également connu sous le nom de K8s, est un système open source pour automatiser le déploiement, la mise à l'échelle et la gestion des applications conteneurisées (images Docker). Il regroupe les conteneurs qui composent une application en unités logiques pour une gestion et une découverte faciles.

Les clusters gérés Edgegap fournissent une API Kubernetes à des fins d'administration.

### K8s Lens

Avec plus d'un million d'utilisateurs, [K8s Lens](https://k8slens.dev/) est l'EDI Kubernetes le plus populaire au monde. Connectez-vous aux clusters, explorez, obtenez des informations, apprenez et agissez si nécessaire. Lens fournit toutes les informations de vos charges de travail et ressources en temps réel, toujours dans le bon contexte.

L'API Kubernetes du cluster Edgegap peut être utilisée via Lens ou d'autres EDI Kubernetes.

### Gestionnaire de paquets Helm

[Helm](https://helm.sh/) est la meilleure façon de trouver, partager et utiliser des logiciels conçus pour Kubernetes. Helm vous aide à gérer les applications Kubernetes - les Helm Charts vous aident à définir, installer et mettre à niveau même les applications Kubernetes les plus complexes. Les charts sont faciles à créer, versionner, partager et publier - alors commencez à utiliser Helm et arrêtez le copier-coller.

[Installation de l'interface CLI Helm](https://helm.sh/docs/intro/install/) fournit aux développeurs une interface simple pour gérer leurs packages de cluster.

## 🚀 Démarrage

☑️ [Inscrit pour votre compte Edgegap gratuit](https://app.edgegap.com/auth/register) et passez au niveau paiement à l'utilisation pour débloquer les clusters.

☑️ Accédez à [Clusters gérés](https://app.edgegap.com/cluster-management/clusters/list) page.

☑️ Cliquez sur **Créer un cluster** d'abord, puis saisissez :

* **Étiquette** pour votre cluster afin de le retrouver facilement plus tard,
* **Taille du cluster -** voir [#introduction](#introduction "mention").

{% hint style="danger" %}
**Nous recommandons fortement de créer des clusters séparés pour vos environnements de développement et de production.**
{% endhint %}

☑️ Vérifiez le coût estimé et cliquez **Créer un cluster** pour démarrer votre nouveau cluster.

☑️ Une fois le cluster prêt, **cliquez sur Kubeconfig pour télécharger votre configuration et vos identifiants** pour vous connecter et administrer votre nouveau cluster.

☑️ [Déplacez votre fichier kubeconfig](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) pour `kubectl` pour le trouver.

☑️ Utilisateurs Lens : [importez votre fichier kubeconfig](https://docs.k8slens.dev/getting-started/add-cluster/#specify-kubeconfig-files).

☑️ Testez la connexion à votre cluster avec la commande `kubectl get nodes` :

```bash
kubectl get nodes
NOM                             STATUT   RÔLES    ÂGE    VERSION
lke334087-533013-294dcfe70000   Prêt     <aucun>   10m   v1.31.0
lke334087-533013-4e69edc10000   Prêt     <aucun>   10m   v1.31.0
lke334087-533013-50bf39880000   Prêt     <aucun>   10m   v1.31.0
```

🙌 Félicitations, vous avez terminé la configuration du cluster géré ! Vous pouvez maintenant installer vos services.

## 📦 Nakama par Heroic Labs

{% hint style="info" %}
Intégrez Edgegap avec [plugin Nakama](https://github.com/edgegap/nakama-edgegap) + [plugin Unity](https://github.com/edgegap/edgegap-server-nakama-plugin-unity)! [Contactez-nous pour d'autres plateformes/fonctionnalités.](https://discord.gg/NgCnkHbsGp)
{% endhint %}

Suivez ces étapes pour héberger votre propre [Backend de jeu Nakama](https://heroiclabs.com/docs/nakama/getting-started/) sur des clusters gérés :

☑️ Créez un **enregistrement DNS de type A** chez votre fournisseur DNS (par ex. [Cloudflare](https://developers.cloudflare.com/dns/get-started/)), notez l'URL pour plus tard. Votre **IP externe pour l'enregistrement DNS** peut être trouvée dans Lens sous Services / `ingress-nginx-controller` .

☑️ Vérifiez que votre DNS est correctement configuré en effectuant une recherche [à l'aide de DNSchecker](https://dnschecker.org/ns-lookup.php).

☑️ Créez un fichier nommé `values.yaml` avec le contenu suivant (utilisez vos propres valeurs) :

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

# Le nom d'hôte externe pour le serveur Nakama - enregistrement DNS de l'étape précédente
externalHostName: <a data-footnote-ref href="#user-content-fn-1">&#x3C;DNS_A_RECORD_URL></a>

nakama:
  # La version de Nakama à déployer.
  # Voir https://hub.docker.com/r/heroiclabs/nakama/tags pour les versions disponibles.
  version: 3.26.0
  # Nom d'utilisateur et mot de passe pour la console 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" %}
**Remplacez \<VALUES> ci-dessus par vos propres valeurs** dans le fichier ci-dessus.
{% endhint %}

☑️ Déployer le chart helm 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 : vérifiez l'installation dans la section Workloads / Deployments, `nakama` devrait être en cours d'exécution.

✅ **Connectez-vous à votre console Nakama** avec l'URL et les identifiants du `values.yaml` fichier.

🙌 Félicitations, vous avez terminé la configuration du backend de jeu Nakama auto-hébergé !

### Mises à jour du service

Suivez ces étapes pour mettre à jour votre service hébergé dans le cluster géré :

☑️ Mettez à jour votre `value.yaml` fichier avec les nouveaux fichiers.

☑️ Mettez à jour votre chart helm en utilisant cette commande :

```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
```

☑️ Rechargez vos modifications en fermant les pods mis à jour, ce qui provoquera l'utilisation du nouveau chart helm après que nous redémarrions automatiquement les pods.

🙌 Félicitations, vous avez terminé la mise à jour du cluster Nakama !

## 👷 Matchmaker avancé

Suivez ces étapes pour héberger votre [OpenMatch](https://open-match.dev/site/) sur un cluster géré.

☑️ Créez un enregistrement DNS de type A chez votre fournisseur DNS (par ex. [Cloudflare](https://developers.cloudflare.com/dns/get-started/)), notez l'URL pour plus tard. Votre **IP externe pour l'enregistrement DNS** peut être trouvée dans Lens sous Services / `ingress-nginx-controller` .

☑️ Vérifiez que votre DNS est correctement configuré en effectuant une recherche [à l'aide de DNSchecker](https://dnschecker.org/ns-lookup.php).

☑️ Créez un fichier nommé `values.yaml` avec le contenu suivant (utilisez vos propres valeurs) :

```yaml
isProductionEnvironment: false

director:
  credential:
    registry: <VOTRE_REGISTRY_DIRECTOR>
    username: <VOTRE_USERNAME_REGISTRY_DIRECTOR>
    password: <VOTRE_MOT_DE_PASSE_REGISTRY_DIRECTOR>
  image: <IMAGE_DIRECTOR>
  env: {
    "KEY": "VALUE"
  }

mmf:
  credential:
    registry: <REGISTRY_MATCHMAKER_FUNCTION>
    username: <USERNAME_REGISTRY_MATCHMAKER_FUNCTION>
    password: <MOT_DE_PASSE_REGISTRY_MATCHMAKER_FUNCTION>
  image: <IMAGE_MATCHMAKER_FUNCTION>
  env: {
    "KEY": "VALUE"
  }

frontend:
  credential:
    registry: <REGISTRY_FRONTEND>
    username: <USERNAME_REGISTRY_FRONTEND>
    password: <MOT_DE_PASSE_REGISTRY_FRONTEND>
  externalHostName: <VOTRE_NOM_D_HOTE_CLOUDFLARE> # par ex. exemple.test.com
  image: <IMAGE_FRONTEND>
  env: {
    "KEY": "VALUE"
  }

# Configurations globales visibles par tous les sous-charts
global:
  kubernetes:
    resources:
      requests:
        memory: 100Mi
        cpu: 100m
      limits:
        memory: 100Mi
        cpu: 100m
```

{% hint style="danger" %}
**Remplacez \<VALUES> ci-dessus par vos propres valeurs** dans le fichier ci-dessus.
{% endhint %}

☑️ Ajoutez **le dépôt Edgegap** à votre liste de dépôts :

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

☑️ Déployer le chart helm du matchmaker avancé :

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

🙌 Félicitations, vous avez terminé la configuration du Matchmaker avancé !

### Mises à jour du service

Suivez ces étapes pour mettre à jour votre service hébergé dans le cluster géré :

☑️ Mettez à jour votre `value.yaml` fichier avec les nouveaux fichiers.

☑️ Mettez à jour votre chart helm en utilisant cette commande :

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

☑️ Rechargez vos modifications en fermant les pods mis à jour (director, mmf, frontend), ce qui provoquera l'utilisation du nouveau chart helm après que nous redémarrions automatiquement les pods.

🙌 Félicitations, vous avez terminé la mise à jour du Matchmaker avancé !

### Déploiement continu

Automatisez la mise à jour de vos services en ajoutant ce script shell à votre pipeline de déploiement :

```bash
#!/bin/bash

RELEASE_NAME="<RELEASE_NAME>"
NAMESPACE="matchmaker"  # Changez ceci si vous avez modifié le namespace.

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

echo "Installation de 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

# Pour chaque déploiement (director, mmf, custom-frontend) arrêtez les pods
for deployment in $DIRECTOR_DEPLOYMENT_NAME $MMF_DEPLOYMENT_NAME $CUSTOM_FRONTEND_DEPLOYMENT_NAME
do
  echo "Arrêt des pods pour le déploiement : $deployment"
  replicas[$deployment]=$(kubectl get deployment $deployment -o=jsonpath='{.spec.replicas}' --namespace $NAMESPACE)
  kubectl scale deployment/$deployment --replicas=0 --namespace $NAMESPACE
done

# Attendre que les pods soient terminés
for deployment in $DIRECTOR_DEPLOYMENT_NAME $MMF_DEPLOYMENT_NAME $CUSTOM_FRONTEND_DEPLOYMENT_NAME
do

  echo "Attente de la terminaison des pods pour le déploiement : $deployment"
  kubectl wait --for=delete pod -l app=$deployment --timeout=60s --namespace $NAMESPACE

  # Vérifier si la commande wait a réussi. Sinon, quitter le script
  if [ $? -ne 0 ]; then
    echo "Échec de l'attente de la terminaison des pods pour le déploiement : $deployment"
    exit 1
  fi
done

# Nettoyer la base de données redis
echo "Nettoyage de la base de données redis"
redis-cli -h $REDIS_HOST flushall

# Pour chaque déploiement (director, mmf, custom-frontend) restaurez l'échelle des pods à leur nombre d'origine
for deployment in $DIRECTOR_DEPLOYMENT_NAME $MMF_DEPLOYMENT_NAME $CUSTOM_FRONTEND_DEPLOYMENT_NAME
do
  echo "Redimensionnement des pods à ${replicas[$deployment]} pour le déploiement : $deployment"
  kubectl scale deployment/$deployment --replicas=${replicas[$deployment]} --namespace $NAMESPACE
done
```

### Validation du certificat Letsencrypt (C#)

Pour certains clients, la validation de certificat Letsencrypt recommandée peut échouer avec l'erreur :

```bash
Erreur Curl 60 : Échec de la vérification du certificat. Le certificat a expiré. Code d'erreur UnityTls : 7
```

{% hint style="success" %}
La mise à jour de votre système d'exploitation peut résoudre les problèmes liés à une autorité de certification racine obsolète.
{% endhint %}

En dernier recours, les clients de jeu peuvent implémenter une fonction personnalisée de gestion des certificats :

````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;
    }
  }
}
```
````

Utilisation :

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

Nous recommandons de stocker la `EXPECTED_CERT` valeur dans votre propre stockage de fichiers, et de la récupérer à l'exécution, afin de pouvoir la mettre à jour sans publier une mise à jour du client de jeu.

## 🟢 Opérations et observabilité

### Changements de niveau de cluster

Préparez-vous au succès et optimisez après le lancement, afin de ne pas bloquer vos joueurs le jour de la sortie.

{% hint style="warning" %}
&#x20;Changer la taille du cluster nécessite d'arrêter votre cluster. Voir [déploiement blue/green](https://circleci.com/blog/canary-vs-blue-green-downtime/) pour des mises à jour sans interruption.
{% endhint %}

### Support et mises à jour futures

**Votre succès est notre priorité.** Si vous souhaitez envoyer des demandes personnalisées, demander des fonctionnalités critiques manquantes, ou exprimer toute remarque, [veuillez nous contacter dans notre Discord Communautaire](https://discord.gg/MmJf8fWjnt).

[^1]: enregistrement DNS de l'étape précédente

[^2]: choisissez votre propre nom d'utilisateur admin

[^3]: choisissez un mot de passe sécurisé pour l'administrateur
