호스트에서 Docker 컨테이너의 mysql에 연결


109

(Docker 또는 mysql 관리에 대한 제한된 지식으로 인해 어리석은 질문 일 수 있지만이 문제에 대해 저녁을 보냈으므로 감히 묻습니다.)

간단히 말해서

도커 컨테이너에서 mysql을 실행하고 호스트에서 연결하고 싶습니다. 지금까지 내가 달성 한 최고는 다음과 같습니다.

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

답변:


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
나는 유닉스 통신 전문가는 아니지만 내가 이해하는 소켓은 파일로 표현되는 연결입니다. 소켓 파일은 Docker 컨테이너와 호스트 컴퓨터간에 공유되지 않으므로 MySQL 클라이언트는 Docker 컨테이너 내부에서 사용할 수 없습니다. 호스트 컴퓨터에서 Docker 컨테이너 내부의 MySQL 서버에 연결하려면 다음을 수행 할 수 있습니다. 1. 지정된 위치에 소켓을 배치하도록 MySQL 서버를 설정합니다 --socket=/var/run/mysqld/mysqld.sock. 2. Docker 컨테이너 외부에이 파일을 마운트합니다. 3.--socket=/host/mysql.sock
maniekq

@maniekq 좋은 코멘트! 하지만 세 가지 가능성을 모두 확인 했습니까? 모두 실제로 작동합니까?
Andru

7
오랫동안 고군분투 한 끝에이 황금 답을 찾았고 --protocol=tcp마침내 연결이 작동하게되었습니다. 댓글을 통해 소켓에 대한 좋은 답변과 설명에 대해 @maniekq에게 감사드립니다!
panepeter

1
그가 UNIX 파일 통신에 대해 전혀 모른다고 명시 적으로 말 했으므로 받아 들여지는 대답이되어서는 안됩니다.
kiltek

50

localhost 대신 "127.0.0.1"을 사용하면 mysql은 tcp 메소드를 사용하며 다음과 같이 컨테이너를 연결할 수 있어야합니다.

mysql -h 127.0.0.1 -P 3306 -u root

4
난 내가 127.0.0.1에 로컬 호스트 및 프로토콜 플래그를 제거 변경된 후,이 같은 일을 확인할 수 있습니다
크레이그 웨인

2
나는이 짧고 가장 좋은 대답이라고 생각)
rezam

1
짧을 수도 있지만 TCP가 mysql과 통신하는 데 더 느린 방법이라는 점을 감안할 때 답이 아닙니다. (더 많은 CPU 및 더 높은 지연 시간)
John

1
@John 당신이 맞습니다, 느리지 만 존재합니다. 물론 호스트와 컨테이너간에 /var/run/mysqld/mysqld.sock을 공유 할 수 있습니다.
Vasili Pascal

2
그것이 내가 더 높은 의무 DB에 권장하는 것입니다. tcp / ip 스택을 오염시키지 않고 "-v socketfile.sock"다음에 mysql --socket /path/file.sock만큼 간단합니다.
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

노트:

이제 다음과 같이 mysql 콘솔에 액세스 할 수 있습니다.

$ mysql -P 8083 --protocol = tcp -u 루트 -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를 사용한 후 수정되었습니다. 도커 네트워크에 문제가 있다고 생각했습니다.
지리 키

16

간단한 방법은 mysql 유닉스 소켓을 호스트 머신에 공유하는 것입니다. 그런 다음 소켓을 통해 연결

단계 :

  • 호스트 컴퓨터에 대한 공유 폴더 만들기 예 : mkdir /host
  • 볼륨 마운트 옵션으로 도커 컨테이너를 실행합니다 docker run -it -v /host:/shared <mysql image>.
  • 그런 다음 mysql 구성 파일 /etc/my.cnf을 변경하고 파일의 소켓 항목을 다음과 같이 변경하십시오.socket=/shared/mysql.sock
  • service mysql restartDocker에서 MySQL 서비스 다시 시작
  • 마지막으로 소켓을 통해 호스트에서 MySQL 서버에 연결합니다 mysql -u root --socket=/host/mysql.sock. 암호가 -p 옵션을 사용하는 경우

1
MySQL 클라이언트가 다른 컨테이너에있는 경우이 작업을 수행해야합니까?
Stephane

나는 그것을 모른다. tcp-ip 포트 방법이 작동하지 않았기 때문에이 방법을 선택했습니다. 서버와 클라이언트에 두 개의 컨테이너를 사용하는 경우 두 컨테이너에 공통 디렉토리를 공유하고 Unix 소켓을 사용하여 MySQL에 연결할 수 있습니다.
Jobin

1
내 질문에 대한 대답은 컨테이너의 링크와 함께 docker-compose를 사용할 때 아니오입니다.
Stephane

9

docker-machine에서 docker를 실행하는 경우?

IP를 얻으려면 실행하십시오.

docker-machine ip <machine>

머신의 IP를 반환하고 mysql 연결을 시도합니다.

mysql -h<docker-machine-ip>

Docker-Toolbox에서 해결되었습니다. :) 대단히 감사합니다.
Vuong

5

내 서버에 대해 임시 도커 컨테이너를 실행하여이 작업을 수행하므로 호스트에 설치된 항목에 대해 걱정할 필요가 없습니다. 먼저 필요한 사항을 정의합니다 (목적에 맞게 수정해야 함).

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

항상 다른 컨테이너에 필요한 새 도커 네트워크를 만듭니다.

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 여기서 주어진 IP는 내 호스트 IP이고 3307은 포트 forwaded in mysql docker. 명령을 입력 한 후 myql에 대한 암호를 입력합니다. 이제 호스트 컴퓨터에서 mysql 도커 컨테이너에 연결됩니다.


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'명령은 소켓 파일을 통해 로컬 인스턴스에 연결됩니다.
Rich

@Rich 그래서 그 문제를 해결하기 위해 무엇을 했습니까? 비슷한 설정이 있는데 하나는 호스트에서 실행되고 다른 하나는 도커 컨테이너에서 실행됩니다.
NITHIN RAJ T

@NITHINRAJT 도커 인스턴스가 동일한 포트에서 수신 대기하지 않는지 확인한 후이를 수행하는 두 가지 방법이 있습니다 (예 :이 답변, 8306). (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가이 작업을 수행하는 열쇠입니다.
Rich


0

확인. 마침내이 문제를 해결했습니다. 다음은 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 루트 -p


그게 끝날 것입니다ERROR 1524 (HY000): Plugin 'unix_socket' is not loaded
Enerccio

@Enerccio 다시 시도해 주시겠습니까?
Ajay Singh

-5


mysql_connect ()이기 때문에 "localhost"를 실제 con ip addr로 변경하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.