Dokcer crée un conteneur MySQL et se connecte à la base de données du conteneur mysql sur l'hôte ou à l'outil de visualisation mysql

Cet article résumera comment créer un conteneur MySQL via Docker et connecter la base de données du conteneur MySQL via l'hôte ou l'outil de visualisation MySQL (il y a eu des problèmes au milieu, et ils ont finalement été résolus avec succès)

  • Erreur 1 :ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 2
  • Erreur 2 :ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

Remarque :
j'utilise docker desktop for windowset suis basé sur WSL2 后端的, et WSL2distribué en utilisant Ubuntu, la plupart des commandes des exemples de démonstration suivants sont Ubuntuaccessibles via Docker.

1. Docker crée un conteneur MySQL

1. Extrayez l'image MySQL

Extrayez la dernière version de MySQL

docker pull mysql

ou

Extrayez la version spécifiée de MySQL (telle que 5.7)

docker pull mysql:5.7

Comme suit, utilisez docker images mysqlpour afficher l'image MySQL extraite

root@GC:~# docker images mysql
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
mysql        latest    99afc808f15b   4 weeks ago   577MB
mysql        5.7       92034fe9a41f   5 weeks ago   581MB
root@GC:~#

2. Créez et exécutez le conteneur MySQL

Utiliser pour docker runcréer et exécuter un conteneur MySQL
Utiliser docker pspour afficher les conteneurs en cours d'exécution

root@GC:~# docker run -d --name mysql5.7 -p 33065:33065 -e MYSQL_ROOT_PASSWORD=1234qwer mysql:5.7
10124d6b026e8442e7250196a1c979ff3fdd7ad5021fc50865cb871cfa662ee6
root@GC:~# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED              STATUS              PORTS                                           NAMES
10124d6b026e   mysql:5.7   "docker-entrypoint.s…"   About a minute ago   Up About a minute   3306/tcp, 33060/tcp, 0.0.0.0:33065->33065/tcp   mysql5.7

docker run: Créer et exécuter le conteneur
-d: Mode d'exécution en arrière-plan
--name mysql5.7: Donnez un nom au conteneur créé, s'il n'est pas spécifié, un nom par défaut sera généré aléatoirement
-p 33065:33065: Mappez le port du conteneur sur le port de l'hôte (le premier est le port de l'hôte). hôte, et ce dernier est le port mysql exposé par le conteneur)
-e MYSQL_ROOT_PASSWORD=1234qwer: Définissez une variable d'environnement pour le conteneur (définissez le mot de passe de l'utilisateur root de myslq)
mysql:5.7: Spécifiez le nom et la balise de l'image utilisée pour créer le conteneur, vous pouvez également utiliser image identifiant à la place

Remarque : Il existe un problème avec "-p 33065:33065" utilisé ici, qui sera abordé plus tard.
(C'est aussi un piège que j'ai moi-même créé et que je me suis piégé pendant une journée...)

3. Créez et exécutez le conteneur MySQL (mappage de répertoires)

En utilisation réelle, les répertoires importants tels que les données, les journaux et les fichiers de configuration dans le conteneur Docker doivent être mappés sur l'hôte local pour éviter la perte de données après la suppression du conteneur Docker.

Mappage vers le mode répertoire Windows :

docker run -d -p 3306:3306 --name mysql5.7 ^
-v /e/mysql/docker-mysql/my.cnf:/etc/my.cnf ^
-v /e/mysql/docker-mysql/logs:/var/log/mysql ^
-v /e/mysql/docker-mysql/data:/var/lib/mysql ^
-e MYSQL_ROOT_PASSWORD=1234qwer ^
mysql:5.7

Méthode de mappage vers le répertoire Linux :

docker run -d -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/my.cnf:/etc/my.cnf \
-e MYSQL_ROOT_PASSWORD=1234qwer \
mysql:5.7

Dans la commande ci-dessus, :la partie avant les deux points correspond aux informations de configuration de l'hôte et la partie après les deux points correspond aux informations de configuration du conteneur.

2. Connectez-vous à la base de données MySQL

1. Dans le conteneur MySQL, connectez-vous à MySQL

Entrez dans le conteneur MySQL et connectez MySQL dans le conteneur

root@GC:~# docker exec -it mysql5.7 /bin/bash
bash-4.2# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.43 MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit
Bye

bash-4.2#

Comme ci-dessus, vous pouvez vous connecter à la base de données mysql normalement dans le conteneur mysql.

2. Connectez-vous à MySQL sur la machine hôte (problèmes rencontrés et solutions)

root@GC:~# mysql -h 127.0.0.1 -P 33065 -u root -p
Enter password:
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 2

Ce problème me dérange depuis un jour. J'ai recherché sur Internet le mot clé [ERREUR 2013 (HY000) : connexion perdue au serveur MySQL lors de la "lecture du paquet de communication initial", erreur système : 2] et j'ai trouvé de nombreux articles connexes, mais aucun. d'entre eux pourraient résoudre cette question.

Solutions essayées (échouées)

(Bien qu'aucun d'entre eux n'ait résolu mon problème, je le liste toujours ici) :

1) Autoriser l'utilisateur root de mysql à accéder au réseau externe ;

root@GC:~# docker exec -it mysql5.7 /bin/bash
bash-4.2# mysql -u root -p
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '1234qwer' WITH GRANT OPTION;   
mysql> FLUSH PRIVILEGES;

En fait, c'est un peu redondant. Après la création du conteneur mysql, cette autorisation a été donnée par défaut
(vous pouvez le découvrir via l'instruction sql suivante. Notez que la commande grant ci-dessus n'est pas exécutée après la création du conteneur mysql. Les résultats sont les suivants)

mysql> select user,host from mysql.user;
+---------------+-----------+
| user          | host      |
+---------------+-----------+
| root          | %         |
| mysql.session | localhost |
| mysql.sys     | localhost |
| root          | localhost |
+---------------+-----------+
4 rows in set (0.00 sec)

mysql>

2) Modifier my.cnfle fichier de configuration

(Emplacement général : /etc/my.cnfou /etc/mysql/my.cnf)
Commentez-le dans le fichier de configuration bind-address = 127.0.0.1et [mysqld]ajoutez-le sous configurationskip-name-resolve

Cette solution ne fonctionne pas pour moi, car sous ma configuration, elle n'existe pas bind-address = 127.0.0.1, et en même [mysqld]temps elle est déjà skip-name-resolveconfigurée par défaut.

Voici ma my.cnfconfiguration par défaut :

bash-4.2# cat /etc/my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

#log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

3) Désactivez le pare-feu de l'hôte où se trouve le conteneur mysql

(Je suis ici Windows docker desktop(Use the WSL 2 based engine), la distribution par défaut de Linux est Ubuntu)
J'ai Windowsdésactivé le pare-feu (Ubuntu n'a pas du tout démarré le pare-feu), puis j'y ai accédé via Windows cmd ou Ubuntu bash, mysql -h 127.0.0.1 -P 33065 -u root -ptoutes les erreurs ont été signalées : Lost connection to MySQL server at 'reading initial communication packet'.

La solution consistant à désactiver le pare-feu n'est donc pas valide pour moi.

4) Redémarrez le service MySQL

On dit également sur Internet que le redémarrage du service MySQL résoudra le problème.
Mais j'ai redémarré le conteneur MySQL ici, et même redémarré le système Windows, mais cela n'a pas fonctionné.

J’ai aussi essayé d’autres solutions, mais je ne m’en souviens plus, mais de toute façon, cela m’a pris une journée entière.



Solution finale au problème (réussi)

Après avoir fini le dîner, j'ai recréé un conteneur mysql, et le mysql de ce conteneur pouvait être connecté depuis window cmd ou Ubuntu bash.

Voici les causes profondes et les solutions :

Quelle est la différence entre ce conteneur MySQL nouvellement créé et celui créé à l'origine ?
Le fait est : des ports, des ports, des ports ! ! !

La commande initiale de création du conteneur MySQL :

root@GC:~$ docker run -d --name mysql5.7 -p 33065:33065 -e MYSQL_ROOT_PASSWORD=1234qwer mysql:5.7

La commande de création de conteneur mysql créée plus tard :

root@GC:~$ docker run -d --name mysql5.7-2 -p 33062:3306 -e MYSQL_ROOT_PASSWORD=1234qwer mysql:5.7

L'accent est -p <宿主机端口>:<容器的端口>mis sur les paramètres.
<容器的端口>Il doit être spécifié comme le port sur lequel MySQL écoute. La valeur par défaut est 3306:
<宿主机端口>cela peut être n'importe quel numéro de port (tant qu'il n'est pas occupé par d'autres programmes) ;

Dans MySQL, vous pouvez show variables like 'port';afficher le port d'écoute MySQL via des instructions

root@GC:~$ mysql -h 127.0.0.1 -P 33062 -uroot -p

mysql> show variables like 'port';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| port          | 3306 |
+---------------+-------+
1 row in set (0.00 sec)

Si vous modifiez le port d'écoute du conteneur mysql comme suit (certains commentaires sont supprimés), précisez-le ci- [mysqld]dessous port=33065( portce champ n'est pas configuré par défaut, et le service mysql écoutera le port 3306 par défaut)

root@GC:~$ docker exec -it mysql5.7 /bin/bash
bash-4.2# vim /etc/my.cnf
bash-4.2# cat /etc/my.cnf
[mysqld]
port=33065
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

symbolic-links=0

#log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

Après modification, redémarrez le conteneur mysql.
Vérifiez ensuite le port sur lequel MySQL écoute, il a été remplacé par33065

root@GC:~$ docker restart mysql5.7
root@GC:~$ docker exec -it mysql5.7 /bin/bash
bash-4.2# mysql -uroot -p
mysql> show variables like 'port';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| port          | 33065 |
+---------------+-------+
1 row in set (0.00 sec)

mysql>

-p 33605:33605À ce stade, vous pouvez vous connecter à la base de données MySQL du conteneur MySQL que vous avez créé initialement via window cmd ou Ubuntu bash ou l'outil de connexion à distance .

root@GC:~$ mysql -h127.0.0.1 -P33065 -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.43 MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql>

Insérer la description de l'image ici

Remarque : Assurez-vous de spécifier -hles paramètres et la valeur est 127.0.0.1ou<宿主机的网桥IP地址>

Insérer la description de l'image ici

Encore une erreur de connexion

Lorsque l'hôte se connecte au conteneur mysql, si -hles paramètres ne sont pas spécifiés, ou s'ils le sont -h localhost, l'erreur suivante sera signalée :

root@GC:~$ mysql -P33065 -uroot -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
cyinl@GC:~$ mysql -hlocalhost -P33065 -uroot -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

En effet, lorsque les -hparamètres par défaut (ou -h localhost) sont utilisés, le client MySQL utilise par défaut la méthode de fichier Unix Socket pour se connecter au serveur de base de données local , et le port exposé par le conteneur mysql est le protocole TCP 127.0.0.1. <宿主机的网桥IP地址>name peut forcer le client MySQL à utiliser TCP/IPla méthode de connexion .Au lieu Unix Socket文件de se connecter, la connexion peut réussir.



En conclusion, la raison pour laquelle j'ai rencontré le problème ci-dessus est que je tenais pour acquis que s'il passait -p <宿主机端口>:<容器端口>et <容器端口>était spécifié comme 33065, alors le mysql créé et exécuté écouterait 33065le port, et pendant tout le processus de dépannage, je n'y ai pas pensé. vérifier quel port mysql écoutait. . (C'est vraiment idiot maintenant que j'y pense)

おすすめ

転載: blog.csdn.net/B11050729/article/details/132802683