Série de séminaires Web: Déploiement de services avec état dans Kubernetes

introduction

Kubernetes est un outil d’orchestration de conteneur open source pour la gestion des applications conteneurisées. Dans les parties précédentes de cette série, vous avez appris les blocs de construction de Kubernetes et des conteneurs empaquetés sous la forme de Kubernetes ReplicaSets. Les ReplicaSets garantissent la disponibilité des pods sans état, mais ils ne peuvent pas être utilisés avec des charges de travail avec état, telles que des clusters de bases de données.

S’il est peut-être facile de conditionner, déployer, gérer et mettre à l’échelle des applications cloud natives contemporaines dans Kubernetes, le déploiement et la gestion de charges de travail traditionnelles telles que des bases de données et des systèmes de gestion de contenu dans un environnement conteneurisé appelle une approche différente. StatefulSets apporte la flexibilité de Kubernetes ReplicaSet aux charges de travail avec état.

Dans la dernière partie de cette série de didacticiels, vous allez déployer un réplica MongoDB hautement disponible dans Kubernetes en tant qu’EtatfulSet à l’aide de Helm, un gestionnaire de packages open source populaire pour Kubernetes.

Conditions préalables

Pour compléter ce tutoriel, vous aurez besoin de:

Étape 1 - Installation du client Helm sur la machine de développement

Avec Helm, les administrateurs peuvent déployer des applications Kubernetes complexes en une seule commande. Les applications sont packagées sous la forme Charts qui définissent, installent et mettent à niveau les applications Kubernetes. Les graphiques fournissent une abstraction sur les objets Kubernetes tels que les pods, les déploiements et les services.

Helm a deux composants: le serveur et le client. Le côté serveur de Helm s’exécute dans Kubernetes en tant que service appelé Tiller. Le client est un outil de ligne de commande qui interagit avec Tiller.

Étant donné que vous allez déployer un tableau de contrôle MongoDB ReplicaSet, vous avez besoin de la CLI qui communique avec Tiller, le composant côté serveur de Helm. StackPointCloud, que vous avez utilisé pour configurer Kubernetes sur DigitalOcean, est livré avec Tiller préinstallé.

En supposant que Homebrew soit installé et configuré sur votre Mac, exécutez la commande suivante pour installer Helm:

brew install kubernetes-helm
Output==> Downloading https://homebrew.bintray.com/bottles/kubernetes-helm-2.8.2.high_sierra.bottle.tar.gz
...
==> Summary
🍺  /usr/local/Cellar/kubernetes-helm/2.8.2: 50 files, 121.7MB

Une fois Helm installé, vérifiez que vous pouvez l’exécuter en vérifiant sa version actuelle.

helm version
OutputClient: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}

Cela confirme que le client est correctement installé et qu’il est capable de parler à Tiller.

Dans la prochaine étape, nous utiliserons Helm pour déployer le MongoDB ReplicaSet dans Kubernetes.

Étape 2 - Déploiement de MongoDB ReplicaSet dans Kubernetes

Une StorageClass dans Kubernetes offre aux administrateurs un moyen de décrire les «classes» de stockage qu’ils proposent. Par exemple, lorsque les utilisateurs demandent un volume de stockage, la StorageClass déterminera quelle classe d’arrière-plan de stockage leur est fournie. Les classes peuvent inclure un disque dur standard et un disque SSD plus rapide. En coulisse, la StorageClass interagit avec l’infrastructure sous-jacente, telle l’API du fournisseur de cloud, pour provisionner le stockage.

Étant donné que vous avez besoin d’un stockage persistant pour stocker les données MongoDB, vous souhaiterez peut-être attacher un volume de stockage de bloc DigitalOcean à un nœud de travail et pointer le pod MongoDB pour qu’il utilise le volume de stockage à des fins de persistance.

Dans ce cas, StorageClass agit en tant qu’interface entre le pod et le service de stockage de bloc DigitalOcean. Lorsque vous demandez un volume de stockage en mode bloc, la StorageClass dialogue avec le pilote préconfiguré qui sait comment allouer un volume de stockage en bloc.

StackPointCloud installe le pilote de stockage DigitalOcean et enregistre la StorageClass auprès de Kubernetes lors de l’installation. Cela nous évite les étapes d’installation et de configuration du pilote et de StorageClass.

Avant de déployer le cluster MongoDB, vérifions que les volumes StorageClass for DigitalOcean sont configurés:

kubectl get storageclass

La sortie confirme que StorageClass est configuré et prêt.

[secondary_label Output
NAME                     PROVISIONER                            AGE
digitalocean (default)   digitalocean/flex-volume-provisioner   1d

Ensuite, vous allez configurer et déployer MongoDB ReplicaSet en fonction de DigitalOcean StorageClass.

Créez un nouveau répertoire pour votre projet et basculez vers le nouveau répertoire:

mkdir ~/mongo-rs
cd ~/mongo-rs

Clonez le référentiel Helm Chart depuis GitHub:

git clone https://github.com/kubernetes/charts.git

Accédez au répertoire MongoDB ReplicaSet (+ charts / stable / mongodb-replicaset / +) et vérifiez que le fichier + values.yaml + existe.

cd charts/stable/mongodb-replicaset/
ls values.yaml
Outputvalues.yaml

Ce fichier contient les paramètres et la configuration du graphique. Vous devez modifier ce fichier pour configurer MongoDB ReplicaSet afin qu’il utilise DigitalOcean StorageClass.

Éditez + values.yaml +:

nano values.yaml

Recherchez et décommentez la section suivante:

valeurs.yaml

...
# storageClass: "-"
...

Remplacez " - " par " digitalocean ", comme ceci:

valeurs.yaml

...
storageClass:
...

Enregistrez le fichier et quittez votre éditeur.

Accédez maintenant au dossier + ~ / mongo-rs +.

cd ~/mongo-rs

Vous êtes maintenant prêt à déployer MongoDB ReplicaSet sur votre cluster Kubernetes, optimisé par le stockage en bloc de DigitalOcean. Exécutez la commande suivante pour lancer le cluster de base de données.

helm install --name= -f charts/stable/mongodb-replicaset/values.yaml stable/mongodb-replicaset

Dans la commande précédente, + - name + fait référence au nom du diagramme de Helm. Le commutateur + -f + pointe sur les paramètres de configuration stockés dans + values.yaml +.

Vous verrez immédiatement la sortie confirmant que la création du graphique a commencé.

OutputNAME:   todo
LAST DEPLOYED: Sat Mar 31 10:37:06 2018
NAMESPACE: default
STATUS:

RESOURCES:
==> v1/Service
NAME                     TYPE       CLUSTER-IP  EXTERNAL-IP  PORT(S)    AGE
 ClusterIP  None        <none>       27017/TCP  1s

==> v1beta1/StatefulSet
NAME                     DESIRED  CURRENT  AGE
 3        1        0s

==> v1/Pod(related)
NAME                       READY  STATUS    RESTARTS  AGE
 0/1    Init:0/2  0         0s

==> v1/ConfigMap
NAME                           DATA  AGE
       1     1s
 1     1s


NOTES:
1. After the statefulset is created completely, one can check which instance is primary by running:

   $ for ((i = 0; i < 3; ++i)); do kubectl exec --namespace default todo-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; done

2. One can insert a key into the primary instance of the mongodb replica set by running the following:
   MASTER_POD_NAME must be replaced with the name of the master found from the previous step.

   $ kubectl exec --namespace default MASTER_POD_NAME -- mongo --eval="printjson(db.test.insert({key1: 'value1'}))"

3. One can fetch the keys stored in the primary or any of the slave nodes in the following manner.
   POD_NAME must be replaced by the name of the pod being queried.

   $ kubectl exec --namespace default POD_NAME -- mongo --eval="rs.slaveOk(); db.test.find().forEach(printjson)"

Exécutons maintenant une série de commandes pour suivre l’état du cluster.

Tout d’abord, regardez le StatefulSet:

kubectl get statefulset

Cette commande confirme que MongoDB ReplicaSet a été créé en tant que Kubernetes StatefulSet.

OutputNAME                      DESIRED   CURRENT   AGE
  3         2         2m

Maintenant, explorez les pods:

kubectl get pods

Le nombre de pods et leur convention de dénomination indiquent que MongoDB ReplicaSet est configuré avec succès:

OutputNAME                        READY     STATUS        RESTARTS   AGE
  1/1       Running       0          3m
  1/1       Running       0          1m
  1/1       Running       0          54s

Notez que chaque pod a un suffixe qui se termine par un numéro séquentiel, ce qui est une caractéristique distinctive d’un StatefulSet.

Voyons maintenant si les instances de MongoDB communiquent les unes avec les autres. Pour ce faire, exécutez une commande dans le shell MongoDB dans l’un des pods.

Utilisez + kubectl pour lancer la console` + mongo` sur l’un des hôtes:

kubectl exec -it  mongo

Après vous être connecté, vous vous retrouverez dans le shell MongoDB:

OutputMongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3
Welcome to the MongoDB shell.
For interactive help, type "help".
...

2018-03-31T05:08:20.239+0000 I CONTROL  [initandlisten]

Vérifiez la configuration de ReplicaSet avec la commande suivante:

rs.conf()

La sortie confirme que trois instances de MongoDB s’exécutent en tant que ReplicaSet.

Output{
   "_id" : "rs0",
   "version" : 3,
   "protocolVersion" : NumberLong(1),
   "members" : [
       {
           "_id" : 0,
           "host" : ",
           "arbiterOnly" : false,
           "buildIndexes" : true,
           "hidden" : false,
           "priority" : 1,
           "tags" : {

           },
           "slaveDelay" : NumberLong(0),
           "votes" : 1
       },
       {
           "_id" : 1,
           "host" : "",
           "arbiterOnly" : false,
           "buildIndexes" : true,
           "hidden" : false,
           "priority" : 1,
           "tags" : {

           },
           "slaveDelay" : NumberLong(0),
           "votes" : 1
       },
       {
           "_id" : 2,
           "host" : "",
           "arbiterOnly" : false,
           "buildIndexes" : true,
           "hidden" : false,
           "priority" : 1,
           "tags" : {

           },
           "slaveDelay" : NumberLong(0),
           "votes" : 1
       }
   ],
   "settings" : {
       "chainingAllowed" : true,
       "heartbeatIntervalMillis" : 2000,
       "heartbeatTimeoutSecs" : 10,
       "electionTimeoutMillis" : 10000,
       "catchUpTimeoutMillis" : -1,
       "catchUpTakeoverDelayMillis" : 30000,
       "getLastErrorModes" : {

       },
       "getLastErrorDefaults" : {
           "w" : 1,
           "wtimeout" : 0
       },
       "replicaSetId" : ObjectId("5abdb4f61d952afc4b0b8218")
   }
}

Quittez la console MongoDB:

exit

Cela vous déconnectera également de votre hôte distant.

Passons à autre chose et vérifiez dans le panneau de commande DigitalOcean les volumes de stockage en mode bloc associés au cluster. Connectez-vous à votre compte DigitalOcean et sélectionnez l’onglet * Volumes *:

image: https: //assets.digitalocean.com/articles/webinar_6_stateful_services/IcNUFQb.jpg [Tableau de bord montrant les volumes]

Vous pouvez constater que trois volumes de 10 Go chacun sont connectés aux nœuds de travail de Kubernetes. Chaque pod de MongoDB StatefulSet stocke les données dans l’un des volumes de stockage en mode bloc. La taille de 10 Go est définie dans + values.yaml + sous la section + persistentVolume +.

valeurs.yaml

persistentVolume:
 enabled: true
 ## mongodb-replicaset data Persistent Volume Storage Class
 ## If defined, storageClassName: <storageClass>
 ## If set to "-", storageClassName: "", which disables dynamic provisioning
 ## If undefined (the default) or set to null, no storageClassName spec is
 ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
 ##   GKE, AWS & OpenStack)
 ##
 storageClass: digitalocean
 accessModes:
   - ReadWriteOnce

 annotations: {}

Vous avez correctement configuré un ensemble de répliques MongoDB à haute disponibilité s’exécutant dans Kubernetes.

Nous allons maintenant déployer l’application Web qui communique avec le cluster MongoDB.

Étape 3 - Déploiement et mise à l’échelle de l’application Web dans Kubernetes

Développons l’application ToDo Node.js que nous avons utilisée dans les parties précédentes de cette série de didacticiels pour tirer parti du cluster MongoDB.

Commencez par créer un nouveau répertoire de travail:

mkdir ~/web-app
cd ~/web-app

Puis clonez le référentiel de l’application ToDo qui contient le code et les artefacts Kubernetes.

git clone https://github.com/janakiramm/todo.git

Basculez vers le répertoire + todo-app / kubernetes + qui contient les fichiers de configuration de Kubernetes.

cd todo-app/kubernetes

Ouvrez le fichier + web-rs-ss.yaml + dans votre éditeur.

nano web-rs-ss.yaml

Notez la section + env + sur le fichier YAML.

web-rs-ss.yaml

     containers:
     - name: web
       image: janakiramm/todo



       ports:
       - containerPort: 3000

Cela transmet la chaîne de connexion à la base de données à l’application lors de l’exécution en tant que variable d’environnement. Au lieu de pointer l’application vers un simple pod MongoDB, cette version de l’application utilise le StatefulSet que vous avez créé. Chaque entrée de la section + value + fait référence à l’un des pods de MongoDB StatefulSet.

Utilisez + kubectl + pour déployer le + web + ReplicaSet avec le service + web +

kubectl create -f web-rs-ss.yaml -f web-service.yaml

Vous verrez que les deux sont créés:

Outputreplicaset "web" created
service "web" created

Répertoriez les pods à nouveau:

kubectl get pods

Vous voyez maintenant tous les pods appartenant à MongoDB et à l’application Web.

OutputNAME                        READY     STATUS    RESTARTS   AGE
todo-mongodb-replicaset-0   1/1       Running   0          26m
todo-mongodb-replicaset-1   1/1       Running   0          24m
todo-mongodb-replicaset-2   1/1       Running   0          23m



Let’s check out the Kubernetes services

​```command
kubectl get svc
OutputNAME                      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
kubernetes                ClusterIP   10.3.0.1     <none>        443/TCP          1d
todo-mongodb-replicaset   ClusterIP   None         <none>        27017/TCP        27m

Les pods + web + parlent au cluster MongoDB via le service + todo-mongodb-replicaset +. L’application Web est disponible via le service + web + sur NodePort + 31201 +.

L’accès à ce port sur l’un des nœuds de travail affiche l’application Web.

image: https: //assets.digitalocean.com/articles/webinar_6_stateful_services/b6yZ4sD.jpg [L’application live de la liste Todo]

Vous pouvez mettre à l’échelle l’application Web en augmentant le nombre de pods dans le ReplicaSet.

kubectl scale rs/web --replicas=10
Outputreplicaset "web" scaled

Vous pouvez ensuite redimensionner l’application en deux pods.

kubectl scale rs/web --replicas=2
Outputreplicaset "web" scaled

Maintenant, exécutons quelques tests de disponibilité.

Étape 4 - Test de la haute disponibilité dans MongoDB ReplicaSet

L’un des avantages de l’exécution d’un StatefulSet est la haute disponibilité des charges de travail. Voyons cela en supprimant l’un des pods du MongoDB StatefulSet.

kubectl delete pod todo-mongodb-replicaset-2
Outputpod "todo-mongodb-replicaset-2" deleted

Vérifiez le nombre de pods:

kubectl get pods

Vous verrez que + todo-mongodb-replica set-2 + se termine:

OutputNAME                        READY     STATUS        RESTARTS   AGE
todo-mongodb-replicaset-0   1/1       Running       0          33m
todo-mongodb-replicaset-1   1/1       Running       0          32m

web-t5zzk                   1/1       Running       0          8m
web-x6dh8                   1/1       Running       0          8m

En quelques minutes, vous verrez que Kubernetes initialise un autre pod pour remplacer celui qui a été supprimé.

kubectl get pods

Vous verrez que + todo-mongodb-replica set-2 + est en cours d’initialisation:

NAME                        READY     STATUS     RESTARTS   AGE
todo-mongodb-replicaset-0   1/1       Running    0          34m
todo-mongodb-replicaset-1   1/1       Running    0          33m

web-t5zzk                   1/1       Running    0          8m
web-x6dh8                   1/1       Running    0          8m

Maintenant que vous savez que tout fonctionne, vous pouvez nettoyer les choses.

Supprimez tous les objets créés lors de ce didacticiel à l’aide des commandes suivantes:

helm delete --purge todo
kubectl delete -f web-rs-ss.yaml -f web-service.yaml
Outputreplicaset "web" deleted
service "web" deleted

Pour supprimer le cluster Kubernetes lui-même, visitez StackPointCloud et faites-le via son panneau de configuration.

Conclusion

Dans ce didacticiel, vous avez déployé un jeu de répliques MongoDB durable, persistant et hautement disponible en tant que Kubernetes StatefulSet. Vous avez également appris à accéder à StatefulSet à partir d’autres applications déployées dans le même cluster Kubernetes.