Application à plusieurs conteneursMulti-container apps

Jusqu’à présent, vous travaillez avec des applications à un seul conteneur.Up to this point, you've been working with single-container apps. Toutefois, vous allez maintenant ajouter MySQL à la pile d’applications.But, you'll now add MySQL to the application stack. La question suivante se pose souvent : «où MySQL s’exécutera-t-il ?The following question often arises - "Where will MySQL run? L’installer dans le même conteneur ou l’exécuter séparément ?Install it in the same container or run it separately?" En général, chaque conteneur doit faire une chose et le faire correctement.In general, each container should do one thing and do it well. Voici quelques raisons :A few reasons:

  • Il y a de bonnes chances que vous deviez mettre à l’échelle les API et les serveurs frontaux différemment des bases de donnéesThere's a good chance you'd have to scale APIs and front-ends differently than databases
  • Des conteneurs distincts vous permettent d’isoler les versions et les mises à jourSeparate containers let you version and update versions in isolation
  • Si vous pouvez utiliser un conteneur pour la base de données localement, vous souhaiterez peut-être utiliser un service géré pour la base de données en production.While you may use a container for the database locally, you may want to use a managed service for the database in production. Vous ne souhaitez pas expédier votre moteur de base de données avec votre application.You don't want to ship your database engine with your app then.
  • L’exécution de plusieurs processus nécessite un gestionnaire de processus (le conteneur démarre un seul processus), ce qui complique le démarrage/l’arrêt du conteneur.Running multiple processes will require a process manager (the container only starts one process), which adds complexity to container startup/shutdown.

Et il y a plus de raisons.And there are more reasons. Par conséquent, vous allez mettre à jour votre application pour qu’elle fonctionne de la manière suivante :So, you will update your application to work like this:

Application todo connectée au conteneur MySQL

Mise en réseau de conteneursContainer networking

N’oubliez pas que les conteneurs, par défaut, s’exécutent de manière isolée et ne savent rien sur d’autres processus ou conteneurs sur le même ordinateur.Remember that containers, by default, run in isolation and don't know anything about other processes or containers on the same machine. Donc, comment autoriser un conteneur à communiquer avec un autre ?So, how do you allow one container to talk to another? La réponse est la mise en réseau.The answer is networking. À présent, vous n’êtes pas obligé d’être un ingénieur réseau (Hourra !).Now, you don't have to be a network engineer (hooray!). Mémorisez simplement cette règle...Simply remember this rule...

Notes

Si deux conteneurs se trouvent sur le même réseau, ils peuvent communiquer entre eux.If two containers are on the same network, they can talk to each other. Si ce n’est pas le cas, ils ne le sont pas.If they aren't, they can't.

Démarrez MySQLStart MySQL

Il existe deux façons de placer un conteneur sur un réseau : l’assigner au démarrage ou connecter un conteneur existant.There are two ways to put a container on a network: assign it at start or connect an existing container. Pour le moment, vous allez d’abord créer le réseau et attacher le conteneur MySQL au démarrage.For now, you will create the network first and attach the MySQL container at startup.

  1. Créez le réseau.Create the network.

    docker network create todo-app
    
  2. Démarrez un conteneur MySQL et attachez-le au réseau.Start a MySQL container and attach it the network. Nous allons également définir quelques variables d’environnement que la base de données utilisera pour initialiser la base de données (consultez la section « variables d’environnement » dans la liste des hubs de l' arrimeur MySQL) (remplacez les \ caractères par ` dans Windows PowerShell).We're also going to define a few environment variables that the database will use to initialize the database (see the "Environment Variables" section in the MySQL Docker Hub listing) (replace the \ characters with ` in Windows PowerShell).

    docker run -d \
        --network todo-app --network-alias mysql \
        -v todo-mysql-data:/var/lib/mysql \
        -e MYSQL_ROOT_PASSWORD=secret \
        -e MYSQL_DATABASE=todos \
        mysql:5.7
    

    Vous verrez également que vous avez spécifié l' --network-alias indicateur.You'll also see you specified the --network-alias flag. Nous reviendrons ici dans un instant.We'll come back to that in just a moment.

    Conseil

    Vous remarquerez que vous utilisez un nom de volume ici et que vous le todo-mysql-data Montez à l' /var/lib/mysql emplacement où MySQL stocke ses données.You'll notice you're using a volume name todo-mysql-data here and mounting it at /var/lib/mysql, which is where MySQL stores its data. Toutefois, vous n’avez jamais exécuté une docker volume create commande.However, you never ran a docker volume create command. L’ancrage reconnaît que vous souhaitez utiliser un volume nommé et en crée un automatiquement pour vous.Docker recognizes that you want to use a named volume and creates one automatically for you.

  3. Pour confirmer que la base de données est en cours d’exécution, connectez-vous à la base de données et vérifiez qu’elle se connecte.To confirm you have the database up and running, connect to the database and verify it connects.

    docker exec -it <mysql-container-id> mysql -p
    

    Lorsque l’invite de mot de passe apparaît, tapez secret.When the password prompt comes up, type in secret. Dans l’interpréteur de commandes MySQL, répertoriez les bases de données et vérifiez que la todos base de données s’affiche.In the MySQL shell, list the databases and verify you see the todos database.

    mysql> SHOW DATABASES;
    

    La sortie doit ressembler à ceci :You should see output that looks like this:

    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | todos              |
    +--------------------+
    5 rows in set (0.00 sec)
    

    Hourra!Hooray! Vous avez votre todos base de données et celle-ci est prête à être utilisée.You have your todos database and it's ready for use!

Se connecter à MySQLConnect to MySQL

Maintenant que MySQL est en cours d’exécution, utilisons-le !Now that you know MySQL is up and running, let's use it! Mais la question est... utilisation?But, the question is... how? Si vous exécutez un autre conteneur sur le même réseau, comment trouver le conteneur (souvenez-vous que chaque conteneur a sa propre adresse IP) ?If you run another container on the same network, how do you find the container (remember each container has its own IP address)?

Pour le déterminer, vous allez utiliser le conteneur nicolaka/netpousse , qui est fourni avec un grand nombre d’outils utiles pour le dépannage ou le débogage des problèmes de réseau.To figure it out, you're going to make use of the nicolaka/netshoot container, which ships with a lot of tools that are useful for troubleshooting or debugging networking issues.

  1. Démarrez un nouveau conteneur à l’aide de l' nicolaka/netshoot image.Start a new container using the nicolaka/netshoot image. Veillez à le connecter au même réseau.Make sure to connect it to the same network.

    docker run -it --network todo-app nicolaka/netshoot
    
  2. À l’intérieur du conteneur, utilisez la dig commande, qui est un outil DNS utile.Inside the container, use the dig command, which is a useful DNS tool. Recherchez l’adresse IP du nom d’hôte mysql .Look up the IP address for the hostname mysql.

    dig mysql
    

    Et vous obtiendrez une sortie similaire à celle-ci...And you'll get an output like this...

    ; <<>> DiG 9.14.1 <<>> mysql
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32162
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
    
    ;; QUESTION SECTION:
    ;mysql.             IN  A
    
    ;; ANSWER SECTION:
    mysql.          600 IN  A   172.23.0.2
    
    ;; Query time: 0 msec
    ;; SERVER: 127.0.0.11#53(127.0.0.11)
    ;; WHEN: Tue Oct 01 23:47:24 UTC 2019
    ;; MSG SIZE  rcvd: 44
    

    Dans la SECTION « réponse », vous verrez un A enregistrement pour mysql ce qui correspond à 172.23.0.2 (votre adresse IP aura probablement une valeur différente).In the "ANSWER SECTION," you will see an A record for mysql that resolves to 172.23.0.2 (your IP address will most likely have a different value). Bien qu' mysql il ne s’agit pas d’un nom d’hôte valide, l’ancrage a pu le résoudre en adresse IP du conteneur qui avait cet alias réseau (n’oubliez pas l' --network-alias indicateur que vous avez utilisé précédemment ?).While mysql isn't normally a valid hostname, Docker was able to resolve it to the IP address of the container that had that network alias (remember the --network-alias flag you used earlier?).

    Ce que cela signifie... Il suffit à votre application de se connecter à un ordinateur hôte nommé mysql et de communiquer avec la base de données !What this means is... your app only simply needs to connect to a host named mysql and it'll talk to the database! Il n’est pas encore plus simple que cela !It doesn't get much simpler than that!

Exécuter votre application avec MySQLRun your app with MySQL

L’application todo prend en charge le paramètre de quelques variables d’environnement pour spécifier les paramètres de connexion MySQL.The todo app supports the setting of a few environment variables to specify MySQL connection settings. Les voici :They are:

  • MYSQL_HOST -nom d’hôte du serveur MySQL en cours d’exécutionMYSQL_HOST - the hostname for the running MySQL server
  • MYSQL_USER : nom d’utilisateur à utiliser pour la connexion.MYSQL_USER - the username to use for the connection
  • MYSQL_PASSWORD : mot de passe à utiliser pour la connexion.MYSQL_PASSWORD - the password to use for the connection
  • MYSQL_DB -la base de données à utiliser une fois connectéMYSQL_DB - the database to use once connected

Avertissement

Définition des paramètres de connexion via des variables d’environnement Bien que l’utilisation de variables d’environnement pour définir les paramètres de connexion soit généralement possible pour le développement, elle est fortement déconseillée lors de l’exécution d’applications en production.Setting Connection Settings via Environment Variables While using environment variables to set connection settings is generally okay for development, it is highly discouraged when running applications in production. Pour comprendre pourquoi, découvrez pourquoi vous ne devez pas utiliser de variables d’environnement pour les données secrètes.To understand why, see Why you shouldn't use environment variables for secret data. Un mécanisme plus sécurisé consiste à utiliser la prise en charge du secret fournie par votre infrastructure d’orchestration de conteneur.A more secure mechanism is to use the secret support provided by your container orchestration framework. Dans la plupart des cas, ces secrets sont montés en tant que fichiers dans le conteneur en cours d’exécution.In most cases, these secrets are mounted as files in the running container. Vous verrez de nombreuses applications (y compris l’image MySQL et l’application TODO) prennent également en charge les variables env avec un _FILE suffixe pour pointer vers un fichier contenant le fichier.You'll see many apps (including the MySQL image and the todo app) also support env vars with a _FILE suffix to point to a file containing the file. Par exemple, la définition MYSQL_PASSWORD_FILE de la fonction var fait en sorte que l’application utilise le contenu du fichier référencé comme mot de passe de connexion.As an example, setting the MYSQL_PASSWORD_FILE var will cause the app to use the contents of the referenced file as the connection password. La station d’accueil ne fait rien pour prendre en charge ces variables env.Docker doesn't do anything to support these env vars. Votre application doit savoir comment rechercher la variable et obtenir le contenu du fichier.Your app will need to know to look for the variable and get the file contents.

Tout comme expliqué, commencez votre conteneur de développement !With all of that explained, start your dev-ready container!

  1. Spécifiez chacune des variables d’environnement ci-dessus et connectez le conteneur à votre réseau d’applications (en remplaçant les \ caractères par ` dans Windows PowerShell).Specify each of the environment variables above, and connect the container to your app network (replace the \ characters with ` in Windows PowerShell).

    docker run -dp 3000:3000 \
      -w /app -v ${PWD}:/app \
      --network todo-app \
      -e MYSQL_HOST=mysql \
      -e MYSQL_USER=root \
      -e MYSQL_PASSWORD=secret \
      -e MYSQL_DB=todos \
      node:12-alpine \
      sh -c "yarn install && yarn run dev"
    
  2. Si vous examinez les journaux du conteneur ( docker logs <container-id> ), vous devez voir un message indiquant qu’il utilise la base de données MySQL.If you look at the logs for the container (docker logs <container-id>), you should see a message indicating it's using the MySQL database.

    # Previous log messages omitted
    $ nodemon src/index.js
    [nodemon] 1.19.2
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching dir(s): *.*
    [nodemon] starting `node src/index.js`
    Connected to mysql db at host mysql
    Listening on port 3000
    
  3. Ouvrez l’application dans votre navigateur et ajoutez quelques éléments à votre liste TODO.Open the app in your browser and add a few items to your todo list.

  4. Connectez-vous à la base de données MySQL et prouvez que les éléments sont écrits dans la base de données.Connect to the MySQL database and prove that the items are being written to the database. N’oubliez pas que le mot de passe est secret.Remember, the password is secret.

    docker exec -ti <mysql-container-id> mysql -p todos
    

    Et dans le shell MySQL, exécutez la commande suivante :And in the MySQL shell, run the following:

    mysql> select * from todo_items;
    +--------------------------------------+--------------------+-----------+
    | id                                   | name               | completed |
    +--------------------------------------+--------------------+-----------+
    | c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! |         0 |
    | 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome!        |         0 |
    +--------------------------------------+--------------------+-----------+
    

    Évidemment, votre table aura une apparence différente, car elle contient vos éléments.Obviously, your table will look different because it has your items. Toutefois, vous devez les y stocker !But, you should see them stored there!

Si vous examinez rapidement l’extension de la station d’accueil, vous verrez que deux conteneurs d’applications sont en cours d’exécution.If you take a quick look at the Docker extension, you'll see that you have two app containers running. Toutefois, il n’y a pas d’indication réelle qu’elles sont regroupées dans une seule application.But, there's no real indication that they're grouped together in a single app. Vous verrez comment faire plus rapidement !You'll see how to make that better shortly!

Extension de l’ancrage qui montre deux conteneurs d’applications non groupés

RécapitulatifRecap

À ce stade, vous disposez d’une application qui stocke ses données dans une base de données externe qui s’exécute dans un conteneur distinct.At this point, you have an application that now stores its data in an external database running in a separate container. Vous avez appris quelques instants sur la mise en réseau des conteneurs et vu comment la découverte de service peut être effectuée à l’aide de DNS.You learned a little bit about container networking and saw how service discovery can be performed using DNS.

Toutefois, il y a de bonnes chances que vous commençons par tout ce que vous devez faire pour démarrer cette application.But, there's a good chance you are starting to feel a little overwhelmed with everything you need to do to start up this application. Vous devez créer un réseau, démarrer des conteneurs, spécifier toutes les variables d’environnement, exposer des ports et bien plus encore.You have to create a network, start containers, specify all of the environment variables, expose ports, and more! C’est beaucoup à retenir et c’est certainement ce qui complique le passage à quelqu’un d’autre.That's a lot to remember and it's certainly making things harder to pass along to someone else.

Dans la section suivante, nous aborderons Docker Compose.In the next section, we'll talk about Docker Compose. Avec Docker Compose, vous pouvez partager vos piles d’applications de manière beaucoup plus simple et permettre aux autres de les faire tourner avec une seule commande (et simple) !With Docker Compose, you can share your application stacks in a much easier way and let others spin them up with a single (and simple) command!

Étapes suivantesNext steps

Poursuivez avec le didacticiel.Continue with the tutorial!