Ana bilgisayardan bir docker kapsayıcısında mysql'ye bağlanın


109

(Docker veya mysql yönetimi ile ilgili sınırlı bilgimden dolayı muhtemelen aptalca bir soru, ancak bu konuda bütün bir akşam geçirdiğim için sormaya cesaret ediyorum.)

Kısaca

Mysql'yi bir docker kapsayıcısında çalıştırmak ve ana bilgisayarımdan ona bağlanmak istiyorum. Şimdiye kadar başardığım en iyi şey:

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

Daha fazla detay

Ben şunu kullanıyorum 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

Bu dosyanın bulunduğu dizinde, imajı başarıyla oluşturabilir ve şu şekilde çalıştırabilirim:

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

Resme eklediğimde, gayet iyi çalışıyor gibi görünüyor:

# 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.
[...]

Ancak sunucudan o kadar başarılı değilim:

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

Daha fazla ayrıntı

  • Benimkine benzeyen bir soru olduğunu gördüm . Ancak, aynı değil (ve yine de herhangi bir yanıtı yok)
    • Mysql'e adanmış resimler olduğunu gördüm , ancak onlarla daha başarılı olamadım
    • Benim grep -vgarip hissedebilirsiniz. Kuşkusuz, bunu yapmanın daha temiz bir yolu olabilir. Ama resmimi iliştirdiğimde, beklendiği gibi çalıştığını gözlemleyebiliyorum (yani: kaldırıldı bind-address). Ve kapta görebiliyorum /var/log/mysql/error.log:

Sunucu ana bilgisayar adı (bağlantı adresi): '0.0.0.0'; bağlantı noktası: 3306 - '0.0.0.0', '0.0.0.0' olarak çözümlenir; IP üzerinde oluşturulan sunucu soketi: '0.0.0.0'.


1
Muhtemelen o kadar aptal değil. Şimdi 10. kez buna tökezledim ve sonunda evde denemek için zamanım oldu.
kiltek

Yanıtlar:


171

Docker MySQL ana bilgisayarınız doğru çalışıyorsa yerel makineden ona bağlanabilirsiniz, ancak aşağıdaki gibi ana bilgisayar, bağlantı noktası ve protokol belirtmelisiniz:

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

3306'yı Docker konteynerinden ilettiğiniz port numarasıyla değiştirin (sizin durumunuzda 12345 olacaktır).

Docker konteyner içinde MySQL çalıştırdığınız için soket mevcut değildir ve TCP üzerinden bağlanmanız gerekir. Mysql komutunda "--protocol" ayarlanması bunu değiştirecektir.


1
Mysql soketinin neden mevcut olmadığını açıklayabilir misiniz? Komutunuz çalışıyor, ancak mysql soketini konteynırdan ana bilgisayara bağlamanın bir yolu olup olmadığını merak ediyorum.
Lucas

9
Unix iletişiminde uzman değilim, ancak anladığım kadarıyla soket bir dosya olarak temsil edilen bir bağlantıdır. Soket dosyası Docker konteyneri ile ana makine arasında paylaşılmadığından MySQL istemcisi Docker konteynerinin içinden birini kullanamaz. Docker konteynerinin içindeki MySQL sunucusuna ana makineden bağlanmak için şunları yapabilirsiniz: 1. MySQL sunucusunu belirtilen yere soketi yerleştirecek şekilde ayarlayın --socket=/var/run/mysqld/mysqld.sock2. Bu dosyayı Docker konteynerinin dışına monte edin 3. MySQL istemcisinde--socket=/host/mysql.sock
maniekq

@maniekq Harika yorum! Ama üç olasılığınızı da doğruladınız mı? Hepsi gerçekten çalışıyor mu?
Andru

7
Uzun bir mücadeleden sonra bu altın cevabı buldum, --protocol=tcpsonunda bağlantıyı kurdum . Hem güzel cevap hem de yorumunuz aracılığıyla soketlerdeki açıklamanız için @maniekq'e teşekkürler!
panepeter

1
UNIX dosya iletişimi hakkında hiçbir fikrinin olmadığını açıkça belirttiği için kabul edilen cevap olmamalıdır.
kiltek

50

Localhost yerine "127.0.0.1" kullanırsanız, mysql tcp yöntemini kullanır ve kapsayıcıya aşağıdakilerle bağlanabilmeniz gerekir:

mysql -h 127.0.0.1 -P 3306 -u root

4
Localhost'u 127.0.0.1 olarak değiştirdiğimde ve protokol bayrağını kaldırdıktan sonra aynı şekilde çalıştığını doğrulayabilirim
Craig Wayne

2
Bence bu kısa ve en iyi cevap;)
rezam

1
Kısa olabilir, ancak TCP'nin mysql ile iletişim kurmak için daha yavaş bir yöntem olduğu düşünüldüğünde, cevap bu değildir. (daha fazla cpu ve daha yüksek gecikme)
John

1
@John haklısın, daha yavaş ama var. Elbette /var/run/mysqld/mysqld.sock'u ana bilgisayar ve kapsayıcı arasında paylaşabilirsiniz.
Vasili Pascal

2
Herhangi bir yüksek görev DB için tavsiye ettiğim şey budur. tcp / ip yığınını kirletmeden "-v socketfile.sock" ve sonra mysql --socket /path/file.sock kadar basittir.
John

27

Docker-compose'a bakmanızı öneririm. İşte bunun nasıl çalışacağı:

Aşağıdaki gibi görünen docker-compose.yml adlı bir dosya oluşturun:

version: '2'

services:

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

Ardından, çalıştırın:

$ docker-compose up

Notlar:

Artık mysql konsoluna şu şekilde erişebilirsiniz:

$ 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>

Notlar:

  • Mysql / mariadb kapsayıcısını ayrılmış / arka plan modunda çalıştırmak için -d bayrağını geçebilirsiniz.

  • Parola docker-compose.yml dosyasında tanımlanan "wp" dir.

  • Maniekq ile aynı tavsiye ancak docker-compose ile tam örnek.


3
--protocol=tcpbenim için her şeyi düzeltti. Teşekkür ederim!
Charlie L

Bu cevap için teşekkürler, konudakiyle aynı sorunu yaşadım ancak --protocol = tcp kullandıktan sonra düzeldi. Docker ağında bir sorun olduğunu düşündüm.
jiriki

16

Basit yöntem, mysql unix soketini ana makineye paylaşmaktır. Ardından soket aracılığıyla bağlayın

Adımlar:

  • Ana makine için paylaşılan klasör oluşturun, örneğin: mkdir /host
  • Docker container'ı birim bağlama seçeneğiyle çalıştırın docker run -it -v /host:/shared <mysql image>.
  • Ardından mysql yapılandırma dosyasını /etc/my.cnfdeğiştirin ve dosyadaki soket girişini şu şekilde değiştirin:socket=/shared/mysql.sock
  • Yeniden MySQL hizmet service mysql restartdocker içinde
  • Son olarak, ana bilgisayardan soket aracılığıyla MySQL sunucusuna bağlanın mysql -u root --socket=/host/mysql.sock. Parola -p seçeneğini kullanırsa

1
MySQL istemcisi başka bir kapsayıcıdaysa bunu yapmak zorunda mısınız?
Stephane

Bunu bilmiyorum Bu yöntemi seçtim çünkü tcp-ip bağlantı noktası yöntemi benim için işe yaramadı. Sunucu ve istemci için iki konteyner kullanıyorsanız, ortak bir dizini her iki konteyner için paylaşabilir ve MySQL'e bağlanmak için Unix soketini kullanabilirsiniz.
Jobin

1
Docker-compose'u container'larda bir bağlantıyla kullandığımda sorumun cevabı hayır.
Stephane

9

Docker'ı docker-machine altında çalıştırıyorsanız?

ip almak için çalıştır:

docker-machine ip <machine>

makine için ip'i döndürür ve mysql'i bağlamayı deneyin:

mysql -h<docker-machine-ip>

Docker-Toolbox'ta çözüldü :) Çok teşekkür ederim.
Vuong

5

Bunu sunucuma karşı geçici bir docker konteyneri çalıştırarak yapıyorum, böylece ana makinemde neyin yüklü olduğu konusunda endişelenmeme gerek kalmıyor. İlk olarak, neye ihtiyacım olduğunu tanımlıyorum (bunu amaçlarınız doğrultusunda değiştirmeniz gerekir):

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

Her zaman diğer konteynerlerin ihtiyaç duyacağı yeni bir docker ağı oluşturuyorum:

docker network create --driver bridge $DB_DOCKER_NETWORK

Bir mySQL veritabanı sunucusu başlatın:

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

Yeni sunucu kapsayıcısının IP adresini yakalayın

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])')"

Sunucuya bir komut satırı arayüzü açın:

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"

Bu son konteyner, mySQL arayüzünden çıktığınızda, sunucu çalışmaya devam ederken kendini kaldıracaktır. Ayrıca, verileri veya komut dosyalarını içe aktarmayı kolaylaştırmak için sunucu ve ana bilgisayar arasında bir birimi paylaşabilirsiniz. Bu yardımcı olur umarım!


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

Kullanıcı, bağlantı noktası ve ana bilgisayarı yapılandırmalarınızla eşleşecek şekilde değiştirmeyi unutmayın. Veritabanı kullanıcınız bir parola ile yapılandırıldıysa -p bayrağı gereklidir


2

Dönüştürme için ,~/.my.cnfana bilgisayarda dosya oluşturabilirsiniz :

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

Sonra bir dahaki sefere mysqlmysql istemcisinin bağlantıyı açması için çalıştırın .


1

Aşağıdaki komutu kullanarak ana bilgisayarımda çalışan sql sunucumu5.7 bağlayabildim: mysql -h 10.10.1.7 -P 3307 --protocol = tcp -u root -p burada verilen ip ana bilgisayarım ip ve 3307 mysql docker'da bağlantı noktası forwaded. Komutu girdikten sonra myql için şifreyi yazın. işte bu. Şimdi ana makinenizden mysql docker konteynerine bağlandınız.


0

konteyneri çalıştırmak için aşağıdaki komutu çalıştırın

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

ana makinede mysql db almak için bu komutu çalıştırın

mysql -h 127.0.0.1 -P 8306 -uroot  -pPASS

senin durumunda öyle

mysql -h 127.0.0.1 -P 12345 -uroot  -pPASS

Bu, yalnızca adres olarak 127.0.0.1 kullanıyorsanız çalışır. Toplantı sahibinin yerel olmayan adresini kullanıyorsanız, --protocol=tcpdiğer birkaç yorumda / yanıtta açıklandığı gibi bayrağı eklemeniz gerekir . Benim durumumda ekstra kafa karıştırıcıydı çünkü yerel, dockerize olmayan, mysql örneğim de çalışıyordu. Varsayılan olarak, bağlantı noktası belirtilse bile, bağlantı noktası yanlış olsa bile, 'mysql' komutu soket dosyası aracılığıyla yerel örneğe bağlanacaktır.
Zengin

@Rich peki bu sorunu çözmek için ne yaptın? Ben bile benzer bir kurulum yapıyorum, bir MySql ana bilgisayarda ve diğeri docker konteynerinde çalışıyor.
NITHIN RAJ T

@NITHINRAJT Docker örneğinizin aynı bağlantı noktasında dinleme yapmadığından emin olduktan SONRA bunu gerçekleştirmenin 2 yolu vardır (örneğin, bu yanıtta olduğu gibi, 8306). (1) Yorum yaptığımız bu yanıtı deneyin (örneğin, 127.0.0.1'e bağlanmak. (2) Sonraki yanıtı deneyin - mysql -u root -P <EXPOSED_DOCKER_PORT_HERE> -h <YOUR_HOST_IP_ADDRESS_HERE> --protocol=tcp -p. Bayrak, --protocol=tcpbu işi yapmanın anahtarıdır.
Zengin


0

TAMAM. Sonunda bu sorunu çözdüm. İşte https://sqlflow.org/sqlflow'da kullanılan çözümüm .

Eksiksiz Çözüm

Demoyu kendi kendine yeten yapmak için, gerekli tüm kodu https://github.com/wangkuiyi/mysql-server-in-docker adresine taşıdım .

Çözümün Anahtarı

DockerHub.com https://hub.docker.com/r/mysql/mysql-server adresindeki resmi resmi kullanmıyorum . Bunun yerine MySQL'i Ubuntu 18.04'e kurarak kendim yaptım. Bu yaklaşım bana mysqld'yi başlatma ve onu 0.0.0.0'a (tüm IP'ler) bağlama şansı veriyor .

Ayrıntılar için lütfen GitHub depomdaki bu satırlara bakın .

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

Çözümümü Doğrulamak İçin

  1. Git yukarıda belirtilen depoyu klonlayın.
    git clone https://github.com/wangkuiyi/mysql-server-in-docker
    cd mysql-server-in-docker
  2. MySQL sunucusu Docker görüntüsünü oluşturun
    docker build -t mysql:yi .
  3. MySQL sunucusunu bir kapsayıcıda başlatın
    docker run --rm -d -p 23306:3306 mysql:yi
  4. Henüz kurulmadıysa, MySQL istemcisini ana bilgisayara kurun. Ana bilgisayarda (iş istasyonumda) Ubuntu 18.04 çalıştırıyorum, bu yüzden kullanıyorum apt-get.
    sudo apt-get install -y mysql-client
  5. Ana bilgisayardan kapsayıcıda çalışan MySQL sunucusuna bağlanın.
    mysql --host 127.0.0.1 --port 23306 --user root -proot

Aynı Ana Bilgisayardaki Başka Bir Kaptan Bağlanın

MySQL istemcisini başka bir konteynerden (aynı ana bilgisayarda) çalıştırabiliriz.

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

Başka Bir Ana Bilgisayardan Bağlanın

İMac'imde, MySQL istemcisini Homebrew kullanarak kuruyorum.

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

Ardından, yukarıdaki Ubuntu ana bilgisayarına (192.168.1.22) erişebilirim.

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

Başka Bir Ana Bilgisayarda Çalışan Bir Konteynerden Bağlanma

MySQL istemcisini, Ubuntu iş istasyonumdaki bir kapta MySQL sunucusuna bağlanmak için iMac üzerinde çalışan bir kapta bile çalıştırabilirim.

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

Özel Durum

MySQL istemcisini ve sunucusunu aynı ana bilgisayarda çalışan ayrı kapsayıcılarda çalıştırmamız durumunda - bu, bir CI kurarken gerçekleşebilir, kendi MySQL sunucusu Docker imajımızı oluşturmamız gerekmez. Bunun yerine, --net=container:mysql_server_container_nameistemci konteynerini çalıştırdığımızda kullanabiliriz .

Sunucuyu başlatmak için

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

Müşteriyi başlatmak için

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 kök -p


bu ile bitecekERROR 1524 (HY000): Plugin 'unix_socket' is not loaded
Enerccio

@Enerccio Tekrar deneyebilir misin?
Ajay Singh

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.