从compose到swarm:在阅读授权数据包'

时间:2017-11-05 16:16:52

标签: mysql docker docker-compose telnet docker-swarm

我有一个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.denymysql个文件。

周围没有防火墙。

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.

2 个答案:

答案 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,问题就消失了。