होस्ट से एक डॉक कंटेनर में mysql से कनेक्ट करें


109

(यह संभवतः डॉकटर या 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' का समाधान करता है; सर्वर सॉकेट आईपी पर बनाया गया: '0.0.0.0'।


1
शायद इतना गूंगा नहीं। मैंने 10 वीं बार इस पर ठोकर खाई और आखिरकार इसे घर पर आजमाने का समय मिल गया।
किलटेक

जवाबों:


171

यदि आपका डॉकटर MySQL होस्ट सही ढंग से चल रहा है, तो आप इसे स्थानीय मशीन से कनेक्ट कर सकते हैं, लेकिन आपको होस्ट, पोर्ट और प्रोटोकॉल को इस तरह निर्दिष्ट करना चाहिए:

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

3306 को पोर्ट संख्या में बदलें जिसे आपने डॉकटर कंटेनर से अग्रेषित किया है (आपके मामले में यह 12345 होगा)।

क्योंकि आप Docker कंटेनर के अंदर MySQL चला रहे हैं, सॉकेट उपलब्ध नहीं है और आपको टीसीपी के माध्यम से कनेक्ट करने की आवश्यकता है। Mysql कमांड में "--protocol" सेट करने से वह बदल जाएगी।


1
क्या आप स्पष्ट कर सकते हैं कि mysql सॉकेट क्यों उपलब्ध नहीं है? आपकी कमांड काम करती है, लेकिन मैं सोच रहा हूं कि क्या कंटेनर से मेजबान को mysql सॉकेट माउंट करने का कोई तरीका है।
लुकास

9
मैं यूनिक्स संचार में एक विशेषज्ञ नहीं हूं, लेकिन जो मैं समझता हूं कि सॉकेट एक कनेक्शन है जो एक फ़ाइल के रूप में दर्शाया गया है। चूंकि सॉकेट फ़ाइल डॉकर कंटेनर और होस्ट मशीन के बीच साझा नहीं की जाती है इसलिए MySQL क्लाइंट डॉकटर कंटेनर के अंदर से एक का उपयोग नहीं कर सकता है। मेजबान मशीन आप सका से डोकर कंटेनर के अंदर MySQL सर्वर से कनेक्ट करने के लिए: 1. सेट MySQL सर्वर निर्दिष्ट स्थान में सॉकेट डाल करने के लिए --socket=/var/run/mysqld/mysqld.sock2. माउंट डोकर कंटेनर 3. साथ MySQL ग्राहक में सॉकेट के लिए पथ निर्दिष्ट करें की इस फाइल के बाहर--socket=/host/mysql.sock
maniekq

@maniekq महान टिप्पणी! लेकिन क्या आपने अपनी सभी तीन संभावनाओं को सत्यापित किया है? क्या वे सभी वास्तव में काम करते हैं?
एंडरू

7
लंबे संघर्ष के बाद मुझे यह सुनहरा जवाब मिला, --protocol=tcpअंत में कनेक्शन का काम किया। धन्यवाद @maniekq आपकी टिप्पणी के माध्यम से सॉकेट पर अच्छा जवाब और आपकी व्याख्या दोनों के लिए!
पैनेटर

1
यह स्वीकृत उत्तर नहीं होना चाहिए, क्योंकि वह स्पष्ट रूप से कहता है कि उसे UNIX फाइल संचार का कोई पता नहीं है।
किलटेक

50

यदि आप लोकलहोस्ट के बजाय "127.0.0.1" का उपयोग करते हैं तो mysql tcp मेथड का उपयोग करेगा और आपको कंटेनर से कनेक्ट करने में सक्षम होना चाहिए:

mysql -h 127.0.0.1 -P 3306 -u root

4
मैं यह सत्यापित कर सकता हूं कि एक बार जब मैंने लोकलहोस्ट को 127.0.0.1 में बदल दिया और प्रोटोकॉल ध्वज को हटा दिया, तो यह उसी तरह काम कर गया
क्रेग वेन

2
मुझे लगता है कि यह छोटा और सबसे अच्छा जवाब है;)

1
कम हो सकता है लेकिन यह जवाब नहीं है, यह देखते हुए कि टीसीपी mysql के साथ संवाद करने की धीमी विधि है। (अधिक सीपीयू और उच्च विलंबता)
जॉन

1
@ आप सही हैं, यह धीमा है, लेकिन यह मौजूद है। बेशक आप होस्ट और कंटेनर के बीच /var/run/mysqld/mysqld.sock साझा कर सकते हैं।
वासिलि पास्कल

2
यही कारण है कि मैं किसी भी उच्च शुल्क DB के लिए सिफारिश करेंगे। यह tcp / ip स्टैक को प्रदूषित किए बिना "-v socketfile.sock" और फिर mysql --socket /path/file.sock जितना सरल है।
जॉन

27

मैं डॉकटर-कंपोज़ की जाँच करने की सलाह देता हूँ। यहाँ है कि कैसे काम करेगा:

एक फ़ाइल बनाएं, जिसका नाम 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

अगला, भागो:

$ डॉकटर-रचना

टिप्पणियाँ:

अब, आप 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>

टिप्पणियाँ:

  • आप mydql / mariadb कंटेनर को अलग / पृष्ठभूमि मोड में चलाने के लिए -d ध्वज पास कर सकते हैं।

  • पासवर्ड "wp" है जो docker-compose.yml फ़ाइल में परिभाषित है।

  • Maniekq के रूप में एक ही सलाह लेकिन docker- रचना के साथ पूर्ण उदाहरण।


3
--protocol=tcpमेरे लिए सब कुछ तय किया। धन्यवाद!
चार्ली एल

इस उत्तर के लिए धन्यवाद, मेरे पास विषय के रूप में एक ही मुद्दा था लेकिन --protocol = tcp का उपयोग करने के बाद इसे ठीक कर दिया गया। मुझे लगा कि docker नेटवर्क में कुछ गड़बड़ है।
जिरिकी

16

सरल विधि मेजबान मशीन के लिए mysql यूनिक्स सॉकेट को साझा करना है। फिर सॉकेट के माध्यम से कनेक्ट करें

कदम:

  • होस्ट मशीन के लिए साझा फ़ोल्डर बनाएँ जैसे: mkdir /host
  • वॉल्यूम माउंट विकल्प के साथ डॉकटर कंटेनर चलाएँ docker run -it -v /host:/shared <mysql image>
  • फिर mysql कॉन्फ़िगरेशन फ़ाइल /etc/my.cnfबदलें और फ़ाइल में सॉकेट प्रविष्टि बदलेंsocket=/shared/mysql.sock
  • डॉकटर में MySQL सेवा service mysql restartको पुनरारंभ करें
  • अंत में सॉकेट के माध्यम से होस्ट से MySQL सेवर से कनेक्ट करें mysql -u root --socket=/host/mysql.sock। यदि पासवर्ड उपयोग -p विकल्प

1
यदि MySQL क्लाइंट किसी अन्य कंटेनर में है, तो क्या आपको यह करना होगा?
स्टीफन

मुझे नहीं पता। मैंने इस विधि को चुना क्योंकि tcp-ip पोर्ट विधि ने मेरे लिए काम नहीं किया। यदि आप सर्वर और क्लाइंट के लिए दो कंटेनरों का उपयोग कर रहे हैं, तो आप दोनों कंटेनरों के लिए एक सामान्य निर्देशिका साझा कर सकते हैं और MySQL से कनेक्ट करने के लिए यूनिक्स सॉकेट का उपयोग कर सकते हैं।
जॉबिन

1
मेरे प्रश्न का उत्तर तब नहीं है जब मैं कंटेनरों के लिंक के साथ डॉकटर-कम्पोज़ का उपयोग करता हूं।
स्टीफन

9

यदि आप डॉक-मशीन के तहत डॉक करते हैं?

IP पाने के लिए निष्पादित करें:

docker-machine ip <machine>

मशीन के लिए आईपी लौटाता है और mysql को जोड़ने का प्रयास करता है:

mysql -h<docker-machine-ip>

Docker-Toolbox में हल किया गया :) बहुत बहुत धन्यवाद।
वुंग

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 जहां दिया गया आईपी मेरा होस्ट आईपी है और 3307 है mysql docker में forwaded पोर्ट। कमांड में टाइप करने के बाद myql.that के लिए पासवर्ड टाइप करें। यह क्या है। यदि आप hostmachine से 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 होस्ट पर और दूसरा डॉकटर कंटेनर में चल रहा हूं।
नितांत राज टी

@NITHINRAJT इस तरीके को पूरा करने के लिए 2 तरीके हैं जो यह सुनिश्चित करते हैं कि आपका docker इंस्टेंस एक ही पोर्ट पर नहीं सुन रहा है (जैसे, इस उत्तर में, 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इस कार्य को बनाने की कुंजी है।
रिच


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 (सभी आईपी) से बाँधने का मौका देता है

जानकारी के लिए, कृपया मेरे 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 क्लोन aforementioned repo।
    git clone https://github.com/wangkuiyi/mysql-server-in-docker
    cd mysql-server-in-docker
  2. MySQL सर्वर डॉकर छवि बनाएँ
    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 सर्वर डॉकर छवि बनाने की आवश्यकता नहीं है। इसके बजाय, हम --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 = पास --name sql-db -p 3306: 3306 mysql

  • docker निष्पादित -it sql-db bash

  • mysql -u रूट -p


इसके साथ समाप्त होगाERROR 1524 (HY000): Plugin 'unix_socket' is not loaded
Enerccio 12

@Enerccio क्या आप फिर से कोशिश कर सकते हैं?
अजय सिंह

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.