我有一个docker-compose文件,允许我启动和访问Web应用程序,使用原始docker-compose -f docker-compose-dev.yml up -d
文件上的compose命令:docker-compose-dev.yml
:
version: "3"
services:
learnintouch-startup:
image: localhost:5000/learnintouch-startup
container_name: learnintouch-startup
restart: always
volumes:
- "~/dev/docker/projects/learnintouch/volumes/engine:/usr/bin/learnintouch/engine"
- "~/dev/docker/projects/learnintouch/volumes/www.learnintouch/account/data:/usr/bin/learnintouch/www/learnintouch.com/account/data"
- "~/dev/docker/projects/learnintouch/volumes/www.thalasoft/account/data:/usr/bin/learnintouch/www/thalasoft.com/account/data"
- "~/dev/docker/projects/learnintouch/volumes/www.folkuniversitet/account/data:/usr/bin/learnintouch/www/folkuniversitet/account/data"
ports:
- "81:80"
links:
- mysql
- redis
- nodejs-learnintouch
nodejs-learnintouch:
image: localhost:5000/nodejs-learnintouch
container_name: nodejs-learnintouch
restart: always
volumes:
- "~/dev/docker/projects/learnintouch/volumes/engine:/usr/bin/learnintouch/engine"
ports:
- "9001:9001"
links:
- redis
mysql:
image: localhost:5000/mysql:5.6.30
container_name: mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
volumes:
- "~/dev/docker/projects/learnintouch/volumes/mysql/data:/usr/bin/mysql/install/data"
redis:
image: localhost:5000/redis:3.0.7
container_name: redis
restart: always
现在,我想以群集模式运行它。我知道swarm模式可用,因为我正在为引擎和客户端运行docker version 17.05.0-ce
。主持人是Ubuntu 16.04
。
我可以使用docker swarm init
命令初始化群组。
然后我尝试启动Web应用程序:
$ docker stack deploy --compose-file docker-compose-swarm-dev.yml learnintouch
Creating network learnintouch_default
Creating service learnintouch_mysql
Creating service learnintouch_redis
Creating service learnintouch_learnintouch-startup
Creating service learnintouch_nodejs-learnintouch
learnintouch-startup
容器有一个MySQL客户端正试图访问mysql
容器中的MySQL服务器。
但是没有这样的容器名称,因此不再有这样的主机名。
在非群集模式之前,当容器名称被用作主机名时,现在,没有这样的容器名称。
我在docker stack deploy --compose-file docker-compose-swarm-dev.yml learnintouch
文件中尝试使用以下docker-compose-swarm-dev.yml
命令:
version: "3"
services:
learnintouch-startup:
image: localhost:5000/learnintouch-startup
volumes:
- "~/dev/docker/projects/learnintouch/volumes/engine:/usr/bin/learnintouch/engine"
- "~/dev/docker/projects/learnintouch/volumes/www.learnintouch/account/data:/usr/bin/learnintouch/www/learnintouch.com/account/data"
- "~/dev/docker/projects/learnintouch/volumes/www.thalasoft/account/data:/usr/bin/learnintouch/www/thalasoft.com/account/data"
- "~/dev/docker/projects/learnintouch/volumes/www.folkuniversitet/account/data:/usr/bin/learnintouch/www/folkuniversitet/account/data"
ports:
- "81:80"
nodejs-learnintouch:
image: localhost:5000/nodejs-learnintouch
volumes:
- "~/dev/docker/projects/learnintouch/volumes/engine:/usr/bin/learnintouch/engine"
ports:
- "9001:9001"
mysql:
image: localhost:5000/mysql:5.6.30
environment:
- MYSQL_ROOT_PASSWORD=root
volumes:
- "~/dev/docker/projects/learnintouch/volumes/mysql/data:/usr/bin/mysql/install/data"
hostname: mysql
redis:
image: localhost:5000/redis:3.0.7
如何指定群组服务的主机名?
请注意,如果我使用docker-compose -f docker-compose-dev.yml up -d
命令以非群集模式启动应用程序,那么应用程序响应正常。只有当我使用docker stack deploy --compose-file docker-compose-swarm-dev.yml learnintouch
命令以群集模式启动它时,才会找不到mysql
主机名:The data source for the database db_learnintouch could not be initialized for the user learnintouch on the host mysql:3306
。实际上,在后一种情况下,容器名称为learnintouch_mysql.1.pu846rr8to5gwxwnxpdm4hdth
而不是mysql
。
更新:问题似乎不是主机名,而是swarm / mysql。
在mysql
容器中,我可以很好地登录MySQL:
$ docker exec -it learnintouch_mysql.1.m51o8deg8cslb8mzayp119m67 bash
root@mysql:/usr/bin/mysql-5.6.30# cd /usr/bin/mysql/install;
root@mysql:/usr/bin/mysql/install# bin/mysql --protocol=tcp -h mysql -P 3306 -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
但是在learnintouch-startup
客户端容器中,我只能ping mysql
服务但不能登录它:
$ docker exec -it learnintouch_learnintouch-startup.1.kf13qktlvxs9rgjzaea2xxd68 bash
root@aa0f0539ba52:/usr/bin/learnintouch/www/folkuniversitet# cd /usr/bin/mysql/install
root@aa0f0539ba52:/usr/bin/mysql/install# bin/mysql --protocol=tcp -h mysql -P 3306 -u root -p
Enter password:
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading authorization packet', system error: 0
root@aa0f0539ba52:/usr/bin/mysql/install# ping mysql
PING mysql (10.0.0.8) 56(84) bytes of data.
64 bytes from 10.0.0.8: icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from 10.0.0.8: icmp_seq=2 ttl=64 time=0.084 ms
64 bytes from 10.0.0.8: icmp_seq=3 ttl=64 time=0.075 ms
^C
--- mysql ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
我也可以实际telnet:
root@861cc3861e67:/usr/bin/learnintouch/www/folkuniversitet# telnet mysql 3306
Trying 10.0.0.6...
Connected to mysql.
Escape character is '^]'.
N
5.6.30-logs5L\i|Sj��=0t}62:k,8s]mysql_native_password
!#08S01Got packets out of orderConnection closed by foreign host.
我使用自定义构建的MySQL版本mysql:5.6.30和my.cnf
文件:
[mysqld]
bind-address = 0.0.0.0 # Allow client binding from any IP address instead of just 127.0.0.1
port = 3306
sql_mode = NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION # This is strict mode: NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
socket = /usr/bin/mysql/install/tmp/mysql.sock
user = root
basedir = /usr/bin/mysql/install
datadir = /usr/bin/mysql/install/data
log-bin = /usr/bin/mysql/install/mysql.bin.log
log-error = /usr/bin/mysql/install/mysql.error.log
general-log-file = /usr/bin/mysql/install/mysql.log
slow-query-log-file = /usr/bin/mysql/install/mysql.slow.queries.log
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
innodb_flush_method = O_DIRECT
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init-connect = 'SET NAMES utf8mb4'
character-set-client-handshake = FALSE
connect_timeout = 60
wait_timeout = 28800 # amount of seconds during inactivity that MySQL will wait before it will close a connection on a non-interactive connection
interactive_timeout = 28800 # same, but for interactive sessions
[client]
socket = /usr/bin/mysql/install/tmp/mysql.sock
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
protocol = tcp # Forces the client to use the TCP protocol, except for PHP which ignores it
/etc/hosts.allow
容器中没有/etc/hosts.deny
和mysql
个文件。
周围没有防火墙。
Docker版本在引擎和客户端都是17.05.0-ce,而docker-compose版本是1.16.1。
更新:删除swarm并再次启动它后,我可以在浏览器中运行该应用程序并看到它运行正常。因此,在此之后,我再次执行删除操作,然后再次出现相同的错误。所以错误,有时,但很少,不会发生。
更新:看来,从客户端容器中运行telnet mysql 3306
命令,可以解决问题并允许MySQL客户端连接继续。这是一致的:我删除了swarm并重新启动它,我在客户端容器中打开一个bash,我尝试登录MySQL服务器容器并且它失败了,我重试多次并且它都失败了,我运行{ {1}}命令,然后再次尝试连接多次,然后失败,然后我运行ping mysql
命令然后尝试连接并成功。
telnet mysql 3306
这是一个完整的演示版本作为证据:
root@2651380ce02e:/usr/bin/mysql/install# cd /usr/bin/mysql/install; bin/mysql --protocol=tcp -h mysql -P 3306 -u root -p
Enter password:
ERROR 2013 (HY000): Lost connection to MySQL server at 'reading authorization packet', system error: 0
root@2651380ce02e:/usr/bin/mysql/install#
root@2651380ce02e:/usr/bin/mysql/install# ping mysql
PING mysql (10.0.0.4) 56(84) bytes of data.
64 bytes from 10.0.0.4: icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from 10.0.0.4: icmp_seq=2 ttl=64 time=0.109 ms
64 bytes from 10.0.0.4: icmp_seq=3 ttl=64 time=0.091 ms
^C
--- mysql ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.088/0.096/0.109/0.009 ms
root@2651380ce02e:/usr/bin/mysql/install# telnet mysql 3306
Trying 10.0.0.4...
Connected to mysql.
Escape character is '^]'.
N
5.6.30-logf[tT)mlX��Pi@EwHCT\SkBmysql_native_password
Connection closed by foreign host.
root@2651380ce02e:/usr/bin/mysql/install# cd /usr/bin/mysql/install; bin/mysql --protocol=tcp -h mysql -P 3306 -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
答案 0 :(得分:0)
您可以使用您在docker-compose文件中指定的服务名称作为swarm中的主机名,例如您的mysql服务名称为mysql
,您可以将该名称用作主机名,此外还有一些选项可以使用docker stack https://docs.docker.com/compose/compose-file/#not-supported-for-docker-stack-deploy
如果您想在不同的网络中使用不同的主机名,则可以使用别名 https://docs.docker.com/compose/compose-file/#networks
答案 1 :(得分:0)
我怀疑这个mysql:5.6.30
中有一个错误,所以我将其移除并替换为mariadb:10.1.24
,问题就消失了。