## Analyse des plates-forme d'informatique en nuage

### Objectifs

Les serveurs du jeu seront regroupés au sein d'une structure permettant
facilement d'adapter leur nombre en fonction du besoin (fortement en
corrélation avec le nombre de joueurs inscrits et connectés).

Depuis quelques années, un grand nombre de plate-forme se développent,
fournissant un service clef en main ; mais des solutions libres sont également
disponibles lorsque l'on désire s'occuper du service manuellement.

Ici, l'objectif était de trouver les avantages et les inconvénients de chaque
fournisseur et de contre balancer cette analyse par rapport aux solutions à
mettre en place soi-même.

### Alternatives possibles

Développer une solution de mise à l'échelle automatique, parfaitement adapté à
nos besoins n'était pas envisageable : cela aurait réclamé une équipe dédiée au
développement de cette solution alternative. Comme ce n'est pas le cœur de
métier du studio, cette solution a d'emblée été écartée.

### Cadre imposé

### Propositions retenues

Les fournisseurs de service d'hébergement en nuage retenus sont :

* Amazon Web Services Elastic Cloud 2 ;
* Digital Ocean ;
* Gandi ;
* Google Compute Engine ;
* Ikoula ;
* Linode ;
* Lunacloud ;
* Numergy ;
* Rackspace ;
* Windows Azure.

Les solutions libres retenues sont :

* Ecalyptus ;
* Libvirt.

### Résultats obtenus

La solution d'Amazon a été retenue pour sa grande diversité et le
support dont nous bénéficions en tant que start-up en développement.

Vous trouverez en annexe le tableau de résultat comparatif effectué
dans le cadre de cette analyse.

\newpage

## Analyse des outils de déploiement automatique

### Objectifs

Les outils de déploiement automatique vont éviter toutes les problématiques de
configuration des différents serveurs que peuvent être le manque
d'harmonisation, les difficultés de réalisation des mises à jour, les besoins
de tests de l'environnement avant la mise en production, le redéploiement
rapide d'une version stable ou précédente.

Il est nécessaire de configurer de nombreuses machines dans différents cadres :

* ajout d'un nouveau serveur au sein du cluster (fournir le contexte) ;
* configuration d'une machine virtuelle à destination des développeurs ;
* configuration des serveurs annexes (sites web, bases de données, monitoring, ...).

### Alternatives possibles

Dans de nombreux environnements chaque machine est configurée à la main par un
administrateur système, a chaque étape, une erreur humaine peut venir
interférer dans la procédure de mise à jour.

Cette solution est évidemment à écarter si l'on veut garder le contrôle de son
système d'information et pouvoir faire face à tout type de problème.

### Propositions retenues

Les outils de déploiment automatique retenus sont :

* Ansible ;
* Capistrano ;
* CFEngine ;
* Chef ;
* Fabric ;
* Puppet.

### Résultats obtenus

Ansible a été la solution retenue : assez récente, elle n'impose pas
l'installation préalable d'un programme sur chaque machine et est en
constant développement depuis son lancement.

Vous trouverez en annexe le tableau comparatif effectué dans le cadre
de cette analyse.


\newpage

## Analyse des solutions de virtualisation

### Objectifs

La virtualisation peut nous être utile à plusieurs niveaux :

* la mise en place d'un environnement de tests de plusieurs machines ;
* l'utilisation d'un environnement standardisé pour les développeurs ;
* le déploiement d'environnements standardisés et minimalistes.

Si dans une contexte de production les serveurs sont utilisés à une valeur
proche de leur puissance maximale, pour un environnement de test, il est tout à
fait envisageable de regrouper les différentes machines nécessaire au sein de
plusieurs machines virtuelles d'une même machine physique, dédiée aux tests.

Pour les développeurs, l'installation de l'environnement de développement n'est
pas toujours facile (surtout s'ils doivent alterner entre deux systèmes
d'exploitation différent) et requiert une certaine standardisation (version
précises de certaine bibliothèques, paquet particulier). La virtualisation
permet de leur fournir un environnement clef en main qu'ils n'ont pas à
maintenir.

Sont apparues ces dernières années des technologies prônant le déploiement en
production de machines virtuelles ou conteneur. Cela permet d'avoir une série
de machine hôte dédiée au déploiement et des machines virtuelles minimalistes
et standardisées (pas d'écoute SSH par exemple).

### Propositions retenues

Sous GNU/Linux, les solutions retenues sont :

* Docker ;
* Libvirt ;
* Linux Kernel-based Virtual Machine (KVM) ;
* Linux Containers (LXC) ;
* Oracle VirtualBox.

Sur Windows, seul Oracle VirtualBox répondait aux contraintes, en particulier
car le logiciel Boot2Docker s'intègre uniquement à cette solution.

### Résultats obtenus

Globalement, les technologies de virtualisation de type hyperviseur n'ont plus
guère d'avantages face aux conteneurs : ils permettent de garantir un niveau de
sécurité et d'isolation quasi-identique, sans avoir la lourdeur de gestion
d'autant de noyau que l'on veut lancer de machines.

Docker et LXC ont donc été retenus. La première version stable de Docker est
sortie pendant mon stage, ce qui a été déterminant pour le choix de cette
solution. LXC reste dans la course pour tout ce qui nécessite une configuration
avancée que ne permettrait pas de faire Docker.


\newpage

## Recherche d'une solution de gestion de chat ingame

### Objectifs

Le chat est un élément essentiel dans un jeu massivement
multijoueurs. Pour nous éviter de réinventer la roue, il a fallu faire
le choix d'une technologie existante et répondant à nos besoins.

### Alternatives possibles

Ajouter au sein du serveur de jeu la gestion du chat aurait pu être
envisageable. Cependant, il peut être fastidieux de programmer un
système complet (par exemple il faut prévoir les systèmes de
modération, de répartition de charge, ...). Afin d'éviter de faire
perdre du temps inutilement au développement, il a donc été préféré le
choix d'une technologie existante.

### Propositions retenues

Les principales solutions existantes sont les suivantes :

* IRC ;
* XMPP.

### Résultats obtenus

Jabber (protocole XMPP) a été retenu comme solution de chat. En effet,
le serveur `ejabberd`, écrit en Erlang, permet aisément de déployer un
cluster et ainsi répartir la charge d'une manière relativement
transparente, comparé aux autres implémentations et des autres
protocoles.


\newpage

## Recherche d'une solution de gestion de l'authentification

### Objectifs

L'authentification est un point crucial à ne pas négliger lorsque l'on
développe un jeu massivement multijoueur. En effet, c'est elle qui
permettra de contrôler l'accès aux différents services du jeu :

* site web ;
* forum ;
* jeu ;
* système de chat dans le jeu ;
* ...

### Alternatives possibles

L'implémentation d'une solution maison est encore une fois
envisageable. Elle n'a pas été retenue pour éviter d'avoir à gérer les
vulnérabilités qui pourraient être découverte une fois le jeu lancé.

D'autre part, étant donné que plusieurs services devront pouvoir
s'authentifier en un point central, cela évite de fournir un travail
pour rendre compatible avec une solution maison les logiciels
compatibles avec des solutions d'authentification standards.

### Propositions retenues

Les solutions de centralisation d'authentification courantes sont :

* LDAP ;
* Kerberos ;
* RADIUS.

### Résultats obtenus

LDAP est une solution utilisée universellement dans le cadre de
l'authentification et du stockage d'informations sur les utilisateurs (Active
Directory dans les environnements Windows, LDAP directement dans les
environnements Unix traditionnels ou en plugin dans de nombreuses applications
demandant une authentification).

Afin de gérer plus simplement l'authentification entre les différents services
au sein du client de jeu (chat, jeu, contenus, marché) et compte tenu du fait
que plusieurs serveurs vont être contactés par le client au fil de l'évolution
du joueur dans le jeu, l'authentification par un serveur Kerberos puis
l'échange de tickets permet de s'affranchir de trop nombreuses
authentifications.


\newpage

## Conception d'un programme de relevé de métriques système

### Objectifs

Afin de pouvoir déterminer le moment optimal pour démarrer un nouveau serveur,
il faut relever un certain nombre de métrique et déterminer dans une première
phase l'indicateur le plus adapté.

### Cadre imposé

Avant mon arrivée dans l'entreprise, mon maître de stage a fait le choix de la
base de données InfluxDB pour le stockage des métriques (aussi bien système que
business).

### Propositions retenues

La base de données retenue est toute récente ; c'est pourquoi il n'existait
encore aucun programme pour faire simplement un relevé de métriques système
(consommation CPU, mémoire vive disponible, bande passante, ...). Il a donc été
choisi de le développer.

Le langage retenu fut le Go : le langage compilant les binaires statiquement,
il n'y aurait donc rien de plus à installer sur les machines sur lesquels nous
devrons faire les relevés.

### Résultats obtenus

Le projet a été terminé et mis en ligne publiquement sur GitHub sous licence
CC0.

Il a ensuite été annoncé à la communauté InfluxDB qui lui a fait un bon
accueil : nous avons eu quelques retours sur des fonctionnalités manquantes et
les membres de la communauté ont eux-mêmes pris la peine de modifier le code
pour y faire des améliorations.

En sus de ce programme de relevé de métrique, il m'a été demandé de réaliser un
tableau de board permettant de visualiser en temps réel les données
compilées. Le premier tableau de bord a été réalisé directement avec le serveur
web de la base de données allié à la bibliothèque JavaScript *Cubism* (voir
figure FIXME) : il permet de visualiser en un coup d'oeil l'état des différents
serveurs. Le deuxième dashboard utilise la bibliothèque JavaScript *Graphana* :
il montre sous une autre forme les données enregistrées dans la base de données
en permettant plus facilement de comparer sur le long terme l'utilisation des
ressources sur les machines en les corrélant avec les événements survenus dans
le jeu.

%%fimage(img/cubism.png, 0.77, "Tableau de bord réalisé avec Cubism")
%%fimage(img/grafana-monitor0.png, 1, "Tableau de bord réalisé avec Graphana")


\newpage

## Conception de recettes de déploiement automatique de serveurs

### Objectifs

Chaque serveur, que ce soit un serveur physique ou virtuel, doit pouvoir être
reconfiguré rapidement en fonction des rôles qui lui sont attribués.

Certain rôles sont réutilisés d'une recette à l'autre : par exemple la machine
virtuelle de développement est un serveur de jeu sur lequel tous les types de
serveur sont disponibles et elle possède également une base de donnée locale.

### Résultats obtenus

Les recettes qu'il a été nécessaire de développer sont les suivantes :

- **serveur de monitoring :** chaque serveur déployé assure son rôle grâce à la
  mise à disposition d'une base de données InfluxDB et à des outils permettant
  de visualiser la charge. Afin de toujours connaître l'état en temps réel
  l'état des serveurs de jeu, chaque serveur configuré est inclus au sein d'un
  cluster de haute-disponibilité.
- **serveurs de base de données :** pour l'instant un seul type de base de
  données est utilisé : Redis. La recette doit permettre de déployer un serveur
  au sein d'un cluster Redis. À terme, un second type de base de données devra
  être déployée afin de disposer de stockage permanent.
- **serveurs de jeu :** le serveur étant décomposé en trois parties, trois
  recettes différentes sont nécessaires, en fonction du type de serveur que
  l'on veut déployé.
- **machine virtuelle de développement :** ces machines mises à disposition des
  développeurs doivent leur permettre de tester le jeu avec un serveur qui leur
  est fournis grâce à cette machine virtuelle. Elle contient tous les
  composants nécessaire au bon fonctionnement du serveur.
- **serveur de machines virtuelles :** il s'agit de configurer un serveur
  fraîchement arrivé pour lui permettre d'exécuter des conteneurs (serveur de
  jeu, site web, etc.).
- **site web commercial :** cette recette crée un conteneur permettant
  d'afficher le site web du jeu via un serveur web correctement configuré.
- **serveur de supervision :** cette recette crée un conteneur pouvant exécuter
  un serveur icinga (clone de nagios). Le conteneur est préconfiguré pour
  superviser les serveurs connus au moment de sa construction.

\vspace{1em}

Pour chaque recette, un certain nombre d'actions communes sont effectuées comme
la mise à jour des paquets et la sécurisation générale (comme la restriction de
l'authentification par SSH, des règles de pare-feu sommaires et diverses règles
permettant de prévenir diverses attaques comme le DNS et l'ARP-poisoning).

\vspace{1em}

Certaines machines disposeront de deux interfaces réseau : une publique et une
interne. Un plugin pour Ansible a donc été développé afin de gérer la présence
de ces deux cartes, permettant d'adapter automatique les configurations des
logiciels en fonction de leur besoin (usage interne ou externe au cluster).

\vspace{1em}

De nombreux modules Ansible existent afin de configurer des bases de
données. Malheureusement, InfluxDB étant encore relativement récente, aucun
module n'était disponible. Pour nos besoins, nous avons donc du développer un
module en Go (pour profiter d'un code compilé de manière statique avec ses
bibliothèques, nous évitant ainsi d'avoir des prérequis sur les machines). Une
demande de fusion de branche a été passé auprès de l'équipe d'Ansible afin de
permettre l'exécution de programme natifs (précédemment limité aux scripts).

\vspace{1em}

Les premières versions du serveur de jeu utilisaient le programme de
compilation `sbt-native-packager`, cela générait les scripts
d'initialisation. Lors de la mise en place des recettes de déploiement pour
cette version du serveur, nous avons observé un bug dans le script
d'initialisation à destination des systèmes Debian. Nous avons donc corrigé le
problème et soumis le correctif au mainteneur du la solution.

\vspace{1em}

Un peu plus tard, afin d'enregistrer les actions effectuées par le programme de
déploiement, il a été nécessaire de développer un nouveau module pour Ansible
afin qu'il enregistrer les actions qu'il fait et les éventuelles erreurs qu'il
rencontre. Cela permet d'avoir une traçabilité des déploiements et des mises à
jour effectuées sur l'ensemble du cluster.


\newpage

## Mise en place d'un processus de livraison du serveur à destination des développeurs du client

### Objectifs

Notre jeu se basant sur un serveur, chaque personne utilisant le client
(développeur ou graphiste) a donc besoin de se connecter à un serveur « stable
» afin de pouvoir visualiser l'impact de ses modifications dans l'environnement
de jeu.

Chaque développeur, pour ses tests peut avoir besoin d'une version particulière
du serveur : une version avancée pour les développeurs travaillant sur
l'intégration réseau, une version stable pour les graphistes, ... Et chacun
peut avoir besoin de faire des tests dans un environnement particulier.

Ainsi, chacun devrait avoir accès à un serveur de jeu dédié et à un serveur de
jeu global (lorsqu'il est question de faire des tests à plusieurs).

### Cadre imposé

Le temps passé au développement est primordial comparé au temps passé à tenter
de configurer l'environnement à partir de la documentation. Une solution clef
en main où le moins de connaissances préalables sont nécessaire est un plus.

### Propositions retenues

Pour la mise en place de ce processus, il a été retenu la mise à disposition :

* de machines virtuelles pré-configurées : l'équipe serveur met à disposition
  du reste de l'équipe des fichiers `.ova` : un disque virtuel au format `VMDK`
  associé à une configuration de machine virtuelle au format `OVF` ;
* de conteneurs associés à des scripts d'automatisation ;
* d'un conteneur sur une machine dédiée : l'équipe serveur s'occupe de mettre
  en place les conteneurs en fonction des besoins de chacun, sans avoir à gérer
  les problèmes lié à la configuration personnelle des machines de chacun.

### Difficultés

Chacune des solutions listée ci-dessus a été testée. La première solution a
souffert d'un manque de consultation des besoins des développeurs : travailler
dans une machine virtuelle en ligne de commande n'est en général pas à la
portée des développeurs plus habitués à Visual Studio.

%FIXME parler de l'interface console

Dans un soucis d'harmonisation des technologies, Docker a été retenu dans un
second temps pour répondre également aux problématiques de déploiement futurs.

Après une semaine de test sur les machines des développeurs, de nombreux
problèmes m'ont été remontés. Ces problèmes étant liés d'une part à la
difficulté de configuration automatique des machines sous Windows et d'autre
part à la complexité grandissante des scripts automatisant pourtant seulement
le téléchargement et l'exécution d'un conteneur dans un environnement connu, il
a été décidé que ces machines virtuelles ne seraient plus distribuées aux
développeurs : ils disposeront d'un accès sur une machine virtuelle maintenue
par l'équipe en charge de l'administration système.

### Résultats obtenus

Compte tenu de la diversité des systèmes employés et de la non-maîtrise de
ceux-ci par les développeurs (filtrage de ports par un anti-virus nouvellement
installé, version différentes de Windows, ...), la solution utilisant des
conteneurs contrôlés par l'équipe serveur sur une machine dédiée a été retenue.

Actuellement au stade d'étude, il serait question de mettre à disposition des
développeur une interface web leur permettant de lancer à volonté des machines
virtuelles et de leur permettre de contrôler certain aspects préenregistrés
(vider la base de données, charger une carte prédéfinie, ...) et de consulter
les journaux du serveurs.


\newpage

## Conception de l'architecture de test de monté en charge

### Objectifs

Une fois les premières versions du serveur livrées, nous nous sommes rapidement
intéressé à ses capacités : en particulier le nombre maximum de joueurs pouvant
être accueillit.

### Propositions retenues

En tant que start-up, nous avons eu un certain nombre de crédit sur Amazon Web
Service afin de tester et démarrer notre activité sur leur plate-forme.

Nous avons donc utilisé un certain nombre de nos crédits afin de lancer 20
machines virtuelles exécutant chacune plusieurs clients.

### Résultats obtenus

Dans un premier temps, la monté en charge montrait que le serveur ne permettait
pas de dépasser 250 joueurs. Au delà, l'analyse qui s'en est suivie a montré
que le scheduler de la bibliothèque d'acteurs que nous utilisions ne faisais
pas correctement son travail : il en résultait une surcharge des canaux de
diffusion, entraînant le plantage du serveur.

Ce problème a été corrigé dans la version suivante de la bibliothèque
d'acteurs. La nouvelle monté en charge a permis d'atteindre cette fois plus de
800 joueurs simultanément, à ce moment, c'était bien le CPU qui était limitant
et il n'en résultat pas de plantage du serveur.


\newpage

## Intégration de métriques dans le serveur

### Objectifs

Les métriques relevées précédemment concernait le système : consommation CPU,
utilisation de la mémoire et de la bande passante, ... Pour des besoins
statistiques (et à terme business), il est nécessaire d'intégrer au serveur
l'envoi de métrique telles que le nombre de joueurs inscrits, connectés, ...

### Difficultés

Le serveur étant écrit en C++, il est nécessaire d'utiliser une bibliothèque C
ou C++ pour s'interfacer avec la base de données. Malheureusement, comme elle
est récente, cette bibliothèque n'avait pas encore été développée.

J'ai donc pris le soin de la développer puis de la proposer aux développeurs de
la base de données qui l'ont intégrée. La bibliothèque est désormais disponible
sur GitHub : https://github.com/influxdb/influxdb-c

### Résultats obtenus

Le travail d'intégration de métriques a d'abord conduit à la réalisation d'un
système de configuration de l'application. En effet, jusque là, les quelques
paramètres nécessaires au fonctionnement du serveur étaient regroupés dans des
macros de préprocesseur.

Une fois ce travail préliminaire réalisé, il a été aisé de rajouter dans le
code du serveur une série de macros envoyant à chaque événement intéressant, un
message vers la base de données.


\newpage

## Déploiement du site web commercial du jeu

### Objectifs

Précédemment hébergé auprès d'une société d'hébergement mutualisé permettant de
modifier facilement de contenu du site ; nous avons été contraint de le refaire
et de l'héberger nous-même afin de pouvoir l'adapter plus facilement à nos
besoins.

### Résultats obtenus

Le site web est déployé par un conteneur Docker, sur un serveur dédié aux
services présenté à la communauté (aucun service d'usage interne ne s'y
trouve).

Le serveur web `nginx` est utilisé, allié au service `php-fpm`. Tous deux ont
été configurés afin de permettre à un millier d'utilisateur de visionner le
site en même temps.

Prévoyant un afflux massif de joueurs dans les prochains mois, nous nous sommes
intéressé aux services d'Amazon afin de bénéficier d'une structure de mise à
l'échelle. Un test grandeur nature a donc été effectué en utilisant le service
*Amazon Elastic Beanstalk*. Ce service configure seul un load-balancer et
s'occupe de déployer automatiquement de nouvelles instances d'une machine
spécifique afin de répondre à la demande fluctuante, selon des critères
préétablis. Après ce test, compte-tenu du coût de la solution, il a été décidé
d'attendre d'en avoir vraiment l'utilité.

%%fimage(img/siteweb.png, 0.95, "Page d'accueil du site web")

\newpage

## Conception de l'architecture des serveurs

### Objectifs

### Alternatives possibles

### Cadre imposé

### Propositions retenues

### Difficultés

### Résultats obtenus
