ホストからDockerコンテナーでmysqlに接続する


109

(Dockerやmysqlの管理に関する知識が限られているため、おそらく馬鹿げた質問ですが、この問題に一晩を費やしたので、あえて質問します。)

一言で言えば

mysqlをdockerコンテナーで実行し、ホストからそれに接続したいと考えています。これまでのところ、私が達成した最高のものは:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

もっと詳しく

私は以下を使用していますDockerfile

FROM ubuntu:14.04.3
RUN apt-get update && apt-get install -y mysql-server

# Ensure we won't bind to localhost only
RUN grep -v bind-address /etc/mysql/my.cnf > temp.txt \
  && mv temp.txt /etc/mysql/my.cnf

# It doesn't seem needed since I'll use -p, but it can't hurt
EXPOSE 3306

CMD /etc/init.d/mysql start && tail -F /var/log/mysql.log

このファイルがあるディレクトリで、イメージを正常にビルドして実行できます。

> docker build -t my-image .
> docker run -d -p 12345:3306 my-image

画像に添付すると、問題なく動作するようです。

# from the host
> docker exec -it <my_image_name> bash

#inside of the container now
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
[...]

しかし、私はホストからそれほど多くの成功を収めていません:

> mysql -P 12345 -uroot
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

さらに詳細

  • 私のよう見える質問があるのを見てきました。しかし、それは同じではありません(そして、とにかく答えはありません)
    • mysql専用の画像があることを確認しましたがあることを確認しましたが、それ以上の成功はありませんでした
    • 私はgrep -v変な感じがあります。確かに、よりクリーンな方法があるかもしれません。しかし、自分の画像を添付すると、実際に期待どおりに機能する(つまり、を削除したbind-address)ことがわかります。そして、私はコンテナで見ることができます/var/log/mysql/error.log

サーバーのホスト名(バインドアドレス): '0.0.0.0'; ポート:3306-「0.0.0.0」は「0.0.0.0」に解決されます。IPで作成されたサーバーソケット: '0.0.0.0'。


1
おそらくそれほど馬鹿ではありません。私はこれを10回目に遭遇し、ついに自宅で試す時間を得ました。
kiltek 2018

回答:


171

Docker MySQLホストが正しく実行されている場合は、ローカルマシンから接続できますが、ホスト、ポート、プロトコルを次のように指定する必要があります。

mysql -h localhost -P 3306 --protocol=tcp -u root

3306をDockerコンテナーから転送したポート番号に変更します(この場合は12345になります)。

Dockerコンテナ内でMySQLを実行しているため、ソケットは使用できず、TCP経由で接続する必要があります。mysqlコマンドで「--protocol」を設定すると、それが変更されます。


1
mysqlソケットが使用できない理由を明確にできますか?コマンドは機能しますが、コンテナーからホストにmysqlソケットをマウントする方法があるかどうか疑問に思っています。
Lucas

9
私はUnix通信の専門家ではありませんが、私が理解しているところでは、ソケットはファイルとして表される接続です。ソケットファイルはDockerコンテナーとホストマシン間で共有されないため、MySQLクライアントはDockerコンテナー内からソケットファイルを使用できません。ホストマシンからDockerコンテナ内のMySQLサーバーに接続するには、次のようにします。1.指定された場所にソケットを配置するようにMySQLサーバーを設定します。--socket=/var/run/mysqld/mysqld.sock 2山でMySQLクライアントソケットへのパスを指定します。3.ドッカーコンテナのこのファイルの外側--socket=/host/mysql.sock
maniekq

@maniekq素晴らしいコメント!しかし、3つの可能性をすべて確認しましたか?それらはすべて本当に機能しますか?
Andru 2018

7
長い苦労の末、この黄金の答えを見つけ、--protocol=tcpようやく接続が機能しました。素敵な答えとあなたのコメントによるソケットの説明の両方を@maniekqに感謝します!
ペインピーター

1
彼はUNIXファイル通信について何も考えていないことを明確に述べているので、これは受け入れられる答えではありません。
kiltek 2018

50

localhostの代わりに "127.0.0.1"を使用すると、mysqlはtcpメソッドを使用し、コンテナを次のように接続できるはずです。

mysql -h 127.0.0.1 -P 3306 -u root

4
localhostを127.0.0.1に変更してプロトコルフラグを削除すると、同じように機能することを確認できます
Craig Wayne

2
これは短くて最良の答えだと思います;)
rezam

1
短いかもしれませんが、TCPがmysqlと通信するためのより遅い方法であることを考えると、それは答えではありません。(CPUの増加とレイテンシの増加)
John

1
@ジョンあなたは正しい、それは遅いですが、それは存在します。もちろん、ホストとコンテナの間で/var/run/mysqld/mysqld.sockを共有できます。
Vasili Pascal、

2
それは私がどんなより高い義務DBにもお勧めするものです。「-v socketfile.sock」、次にmysql --socket /path/file.sockのように、tcp / ipスタックを汚染することなく簡単です。
John

27

docker-composeをチェックすることをお勧めします。これがどのように機能するかは次のとおりです。

次のようなdocker-compose.ymlという名前のファイルを作成します。

version: '2'

services:

  mysql:
    image: mariadb:10.1.19
    ports:
      - 8083:3306
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: wp

次に、実行します:

$ docker-compose up

ノート:

  • 最新のmariadbイメージタグについては、https: //hub.docker.com/_/mariadb/を参照してください

これで、mysqlコンソールにアクセスできます。

$ mysql -P 8083 --protocol = tcp -u root -p

Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.5.5-10.1.19-MariaDB-1~jessie mariadb.org binary distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

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>

ノート:

  • -dフラグを渡して、mysql / mariadbコンテナーをデタッチ/バックグラウンドモードで実行できます。

  • パスワードは、docker-compose.ymlファイルで定義されている「wp」です。

  • maniekqと同じアドバイスですが、docker-composeの完全な例です。


3
--protocol=tcp私のためにすべてを修正しました。ありがとうございました!
Charlie L

この回答をありがとう、トピックと同じ問題が発生しましたが、-protocol = tcpを使用した後、修正されました。docker networkに問題があると思いました。
ジリキ

16

単純な方法は、mysql unixソケットをホストマシンと共有することです。次に、ソケットを介して接続します

手順:

  • ホストマシンの共有フォルダを作成します。例: mkdir /host
  • ボリュームマウントオプションでDockerコンテナーを実行する docker run -it -v /host:/shared <mysql image>
  • 次に、mysql構成ファイル/etc/my.cnfを変更し、ファイルのソケットエントリを次のように変更します。socket=/shared/mysql.sock
  • DockerでMySQLサービスservice mysql restartを再起動します
  • 最後に、ホストからソケットを介してMySQLサーバーに接続しますmysql -u root --socket=/host/mysql.sock。パスワードが-pオプションを使用する場合

1
MySQLクライアントが別のコンテナにある場合、これを行う必要がありますか?
ステファン

それは知りません。tcp-ipポートメソッドが機能しなかったため、この方法を選択しました。サーバーとクライアントに2つのコンテナーを使用している場合は、両方のコンテナーに共通のディレクトリを共有し、Unixソケットを使用してMySQLに接続できます。
Jobin

1
私の質問に対する答えは、コンテナーにリンクを指定してdocker-composeを使用する場合はノーです。
Stephane

9

ドッカーマシンの下でドッカーを実行している場合?

ipを取得するために実行:

docker-machine ip <machine>

マシンのIPを返し、mysqlに接続してみます。

mysql -h<docker-machine-ip>

Docker-Toolboxで解決:)どうもありがとうございました。
Vuong、2017年

5

サーバーに対して一時的なDockerコンテナーを実行することでこれを行うので、ホストに何がインストールされているかを心配する必要はありません。まず、必要なものを定義します(目的に合わせて変更する必要があります)。

export MYSQL_SERVER_CONTAINER=mysql-db
export MYSQL_ROOT_PASSWORD=pswd 
export DB_DOCKER_NETWORK=db-net
export MYSQL_PORT=6604

私は常に、他のコンテナーが必要とする新しいDockerネットワークを作成します。

docker network create --driver bridge $DB_DOCKER_NETWORK

mySQLデータベースサーバーを起動します。

docker run --detach --name=$MYSQL_SERVER_CONTAINER --net=$DB_DOCKER_NETWORK --env="MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD" -p ${MYSQL_PORT}:3306 mysql

新しいサーバーコンテナーのIPアドレスをキャプチャする

export DBIP="$(docker inspect ${MYSQL_SERVER_CONTAINER} | grep -i 'ipaddress' | grep -oE '((1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9][0-9]?|2[0-4][0-9]|25[0-5])')"

サーバーへのコマンドラインインターフェイスを開きます。

docker run -it -v ${HOST_DATA}:/data --net=$DB_DOCKER_NETWORK --link ${MYSQL_SERVER_CONTAINER}:mysql --rm mysql sh -c "exec mysql -h${DBIP} -uroot -p"

この最後のコンテナは、サーバーが稼働している間、mySQLインターフェースを終了すると自動的に削除されます。サーバーとホスト間でボリュームを共有して、データやスクリプトのインポートを容易にすることもできます。お役に立てれば!


5
mysql -u root -P 4406 -h localhost --protocol=tcp -p

ユーザー、ポート、ホストを変更して、構成に一致するようにしてください。データベースユーザーがパスワードで構成されている場合は、-pフラグが必要です。


2

変換のために~/.my.cnf、ホストでファイルを作成でき ます:

[Mysql]
user=root
password=yourpass
host=127.0.0.1
port=3306

次にmysql、mysqlクライアントで接続を開くために実行します。


1

以下のコマンドを使用して、ホスト上で実行しているSQL Server5.7に接続できました。mysql-h 10.10.1.7 -P 3307 --protocol = tcp -u root -p mysql dockerでポートが転送されました。コマンドを入力した後、myqlのパスワードを入力してください。つまり、ホストマシンからmysql dockerコンテナーに接続されています。


0

次のコマンドを実行してコンテナを実行します

docker run --name db_name -e MYSQL_ROOT_PASSWORD=PASS--publish 8306:3306 db_name

このコマンドを実行して、ホストマシンでmysql dbを取得します

mysql -h 127.0.0.1 -P 8306 -uroot  -pPASS

あなたの場合はそれです

mysql -h 127.0.0.1 -P 12345 -uroot  -pPASS

これは、アドレスとして127.0.0.1を使用する場合にのみ機能します。ホストの非ローカルアドレスを使用する場合は、--protocol=tcp他のいくつかのコメント/回答で説明されているように、フラグを追加する必要があります。私の場合、ドッキングされていないローカルのmysqlインスタンスも実行していたため、さらに混乱しました。デフォルトでは、ポートが指定されている場合でも、ポートが正しくない場合でも、「mysql」コマンドはソケットファイルを介してローカルインスタンスに接続します。
リッチ

@リッチだから、その問題を解決するために何をしましたか?私も同様の設定をしています。1つのMySqlをホストで実行し、もう1つをdockerコンテナーで実行しています。
NITHIN RAJ T

@NITHINRAJT Dockerインスタンスが同じポートでリッスンしていないことを確認した後(たとえば、この回答のように、8306)、これを行うには2つの方法があります。。 - (1)は、この答えは、我々は(例えば、127.0.0.1への接続(2)は、次の回答を試してみてくださいにコメントしているお試しくださいmysql -u root -P <EXPOSED_DOCKER_PORT_HERE> -h <YOUR_HOST_IP_ADDRESS_HERE> --protocol=tcp -p。フラグは、--protocol=tcpこの作品を作るための鍵である
リッチ


0

OK。ようやくこの問題を解決しました。https://sqlflow.org/sqlflowで使用されている私のソリューションを次に示します

完全なソリューション

デモを自己完結型にするために、必要なすべてのコードをhttps://github.com/wangkuiyi/mysql-server-in-dockerに移動しました

ソリューションの鍵

DockerHub.com https://hub.docker.com/r/mysql/mysql-serverの公式イメージを使用していません。代わりに、Ubuntu 18.04にMySQLをインストールして自分で作成しました。このアプローチにより、mysqldを起動して0.0.0.0(すべてのIP)にバインドする機会が得られますます。

詳細については、GitHubリポジトリのこれらの行を参照してください。

SQLFLOW_MYSQL_HOST=${SQLFLOW_MYSQL_HOST:-0.0.0.0}

echo "Start mysqld ..."
sed -i "s/.*bind-address.*/bind-address = ${SQLFLOW_MYSQL_HOST}/" \
    /etc/mysql/mysql.conf.d/mysqld.cnf
service mysql start

私のソリューションを確認するには

  1. Gitは前述のレ​​ポを複製します。
    git clone https://github.com/wangkuiyi/mysql-server-in-docker
    cd mysql-server-in-docker
  2. MySQLサーバーのDockerイメージをビルドする
    docker build -t mysql:yi .
  3. コンテナでMySQLサーバーを起動します
    docker run --rm -d -p 23306:3306 mysql:yi
  4. MySQLクライアントをホストにインストールします(まだインストールしていない場合)。ホスト(ワークステーション)でUbuntu 18.04を実行しているので、を使用しますapt-get
    sudo apt-get install -y mysql-client
  5. ホストからコンテナで実行されているMySQLサーバーに接続します。
    mysql --host 127.0.0.1 --port 23306 --user root -proot

同じホスト上の別のコンテナーから接続する

(同じホスト上の)別のコンテナからでもMySQLクライアントを実行できます。

docker run --rm -it --net=host mysql/mysql-server mysql \
   -h 127.0.0.1 -P 13306 -u root -proot

別のホストから接続

私のiMacでは、Homebrewを使用してMySQLクライアントをインストールします。

brew install mysql-client
export PATH="/usr/local/opt/mysql-client/bin:$PATH"

その後、上記のUbuntuホスト(192.168.1.22)にアクセスできます。

mysql -h 192.168.1.22 -P 13306 -u root -proot

別のホストで実行されているコンテナから接続する

iMacで実行されているコンテナでMySQLクライアントを実行して、UbuntuワークステーションのコンテナにあるMySQLサーバーに接続することもできます。

docker run --rm -it --net=host mysql/mysql-server mysql \
    -h 192.168.1.22 -P 13306 -u root -proot

特別なケース

MySQLクライアントとサーバーを同じホスト上で実行されている別々のコンテナーで実行する場合-これは、CIを設定しているときに発生する可能性があるため、独自のMySQLサーバーDockerイメージを構築する必要はありません。代わりに、--net=container:mysql_server_container_nameクライアントコンテナーを実行するときにを。

サーバーを起動するには

docker run --rm -d --name mysql mysql/mysql-server

クライアントを起動するには

docker run --rm -it --net=container:mysql mysql/mysql-server mysql \
 -h 127.0.0.1 -P 3306 -u root -proot

-1
  • docker run -e MYSQL_ROOT_PASSWORD = pass --name sql-db -p 3306:3306 mysql

  • docker exec -it sql-db bash

  • mysql -u root -p


終了するERROR 1524 (HY000): Plugin 'unix_socket' is not loaded
Enerccio

@Enerccioもう一度やり直していただけませんか?
Ajay Singh

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.