เข้าถึงฐานข้อมูลโฮสต์จากคอนเทนเนอร์นักเทียบท่า


133

หากฉันมีฐานข้อมูล mysql ที่ทำงานบนเครื่องโฮสต์บางเครื่องและโฮสต์นั้นกำลังเรียกใช้คอนเทนเนอร์นักเทียบท่าด้วย: ฉันจะเข้าถึงฐานข้อมูล mysql จากภายในคอนเทนเนอร์นักเทียบท่าที่ทำงานบนโฮสต์ได้อย่างไร

ตัวอย่างเช่นมีวิธีเผยแพร่พอร์ตโฮสต์ไปยังคอนเทนเนอร์หรือไม่ (สิ่งที่ตรงกันข้ามกับที่นักเทียบท่ารัน -p ทำ)


1
หากเซิร์ฟเวอร์ MySQL กำลังรับฟังพอร์ตคอนเทนเนอร์ไม่สามารถเชื่อมต่อกับโฮสต์บนพอร์ตนั้นเหมือนกับการเชื่อมต่ออินเทอร์เน็ตอื่น ๆ ได้หรือไม่?
jwodder

คำตอบ:


87

มีการอภิปรายกันมานานหลายครั้งเกี่ยวกับวิธีการทำเช่นนี้อย่างสม่ำเสมอเข้าใจได้ดีและสามารถพกพาได้ ไม่มีการแก้ปัญหาที่สมบูรณ์ แต่ฉันจะเชื่อมโยงคุณไปยังการสนทนาด้านล่าง

ในกรณีใด ๆ ที่คุณต้องการลองใช้อ็อพชัน --add-host เพื่อให้นักเทียบท่าทำงานเพื่อเพิ่มที่อยู่ IP ของโฮสต์ลงในไฟล์ / etc / host ของคอนเทนเนอร์ จากนั้นการเชื่อมต่อกับโฮสต์บนพอร์ตที่ต้องการนั้นเป็นเรื่องเล็กน้อย:

การเพิ่มรายการลงในไฟล์โฮสต์ของคอนเทนเนอร์

คุณสามารถเพิ่มโฮสต์อื่นลงในไฟล์ / etc / hosts ของคอนเทนเนอร์โดยใช้แฟล็ก --add-host อย่างน้อยหนึ่งรายการ ตัวอย่างนี้เพิ่มที่อยู่แบบคงที่สำหรับโฮสต์ชื่อนักเทียบท่า:

 $ docker run --add-host=docker:10.180.0.1 --rm -it debian
    $$ ping docker
    PING docker (10.180.0.1): 48 data bytes
    56 bytes from 10.180.0.1: icmp_seq=0 ttl=254 time=7.600 ms
    56 bytes from 10.180.0.1: icmp_seq=1 ttl=254 time=30.705 ms
    ^C--- docker ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 7.600/19.152/30.705/11.553 ms

หมายเหตุ: บางครั้งคุณต้องเชื่อมต่อกับโฮสต์ Docker ซึ่งหมายถึงการรับที่อยู่ IP ของโฮสต์ คุณสามารถใช้คำสั่งเชลล์ต่อไปนี้เพื่อลดความซับซ้อนของกระบวนการนี้:

 $ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }'"
 $ docker run  --add-host=docker:$(hostip) --rm -it debian

เอกสารอ้างอิง:

https://docs.docker.com/engine/reference/commandline/run/

การสนทนาเกี่ยวกับการเข้าถึงโฮสต์จากคอนเทนเนอร์:

https://github.com/docker/docker/issues/1143

https://github.com/docker/docker/issues/10023


มันจะทำงานหลังพร็อกซีย้อนกลับ NGINX หรือไม่?
kta

89

จากเอกสาร 18.03:

ฉันต้องการเชื่อมต่อจากคอนเทนเนอร์ไปยังบริการบนโฮสต์

โฮสต์มีที่อยู่ IP ที่เปลี่ยนแปลง (หรือไม่มีเลยหากคุณไม่มีการเข้าถึงเครือข่าย) ตั้งแต่เวลา 18.03 น. เป็นต้นไปคำแนะนำของเราคือการเชื่อมต่อกับชื่อ DNS พิเศษhost.docker.internalซึ่งจะแก้ไขไปยังที่อยู่ IP ภายในที่โฮสต์ใช้

เกตเวย์สามารถเข้าถึงได้เช่นgateway.docker.internalกัน

ตัวอย่าง: นี่คือสิ่งที่ฉันใช้สำหรับสตริงการเชื่อมต่อ MySQL ภายในคอนเทนเนอร์ของฉันเพื่อเข้าถึงอินสแตนซ์ MySQL บนโฮสต์ของฉัน:

mysql://host.docker.internal:3306/my_awesome_database

31
คำใบ้เช่นเดียวกับ: ตอนนี้ใช้ได้กับ Mac และ Win เท่านั้น
flp

คุณบันทึกวันของฉัน :)
amjad

4
upvote ไม่ใช่เพียงเพราะคำตอบ แต่เป็นเพราะคุณควรใช้อย่างไรกับตัวอย่าง
granadaCoder

1
ฉันใช้เวลาเกือบ 2 ชั่วโมงในการบรรลุสิ่งนี้ขอบคุณมาก
Ashish Bainade

ยังไม่รองรับ linux ตามที่ @flp เขียนไว้สำหรับผู้ที่อยากรู้อยากเห็น นี่คือปัญหา GitHub
GAltelino

34

ตั้งแต่ Docker 17.06 เป็นต้นไปชื่อ DNS เฉพาะสำหรับ Mac เท่านั้นมีอยู่ในคอนเทนเนอร์นักเทียบท่าที่แก้ไขเป็นที่อยู่ IP ของโฮสต์ มันคือ:

docker.for.mac.localhost

เอกสารอยู่ที่นี่: https://docs.docker.com/docker-for-mac/networking/#httphttps-proxy-support


3
docker.for.mac.host.internalนับจากนี้Docker 17.12.0 ceเป็นต้นไป docs.docker.com/docker-for-mac/release-notes/…
Zangetsu

docker.for.mac.localhost ทำงานบน18.03.1-ce-mac65
cdignam

25

ใช้host.docker.internalตั้งแต่ Docker 18.03 เป็นต้นไป


2
ยังไง ช่วยยกตัวอย่างวิธีใช้งานได้ไหม
danfromisrael

ทำไมคุณไม่เรียกใช้ mysql dockerized
Igor De Oliveira Sá

ไม่ได้ผลสำหรับฉันที่Docker version 18.03.0-ce, build 0520e24
scythargon

@ IgorDeOliveiraSáลองนึกภาพสถานการณ์ต่อไปนี้ในสภาพแวดล้อม dev คุณมีฐานข้อมูลบางส่วนที่รับฟัง 127.0.0.1:3306 ใน env การผลิตที่คุณมีฐานข้อมูลที่ฟัง 127.0.0.1:3306 ในเครื่องเป็นฐานข้อมูลท้องถิ่นการผลิตเป็นพร็อกซีไปยังคลาวด์คุณต้องทำอย่างใดอย่างหนึ่ง นักเทียบท่า mysql ในพื้นที่และสำหรับการผลิตหาวิธีแก้ปัญหาอื่นหรือคุณสามารถเชื่อมต่อจากนักเทียบท่าไปยังพอร์ตมันจะใช้ได้กับทั้งสองกรณี
Drachenfels

1
docker.for.mac.localhostทำงานให้ฉันใน18.03.1-ce-mac65
cdignam

21

คำตอบอื่น ๆ ไม่ได้ผลสำหรับฉัน ภาชนะของฉันไม่สามารถแก้ไข IP โฮสต์ใช้host.docker.internal มีสองวิธี

  1. การแชร์เครือข่ายโฮสต์ --net = host:

    docker run -it --net=host  myimage
    
  2. โดยใช้ที่อยู่ IP นักเทียบท่าซึ่งมักจะ172.17.0.1 คุณสามารถตรวจสอบได้โดยเรียกใช้คำสั่ง ifconfig และคว้า inet addr ของ docker interface

    user@ubuntu:~$ ifconfig
    docker0   Link encap:Ethernet  HWaddr 02:42:a4:a2:b2:f1  
      inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::42:a4ff:fea2:b2f1/64 Scope:Link
    

เมื่อคุณมีที่อยู่ IP นี้คุณสามารถส่งเป็นอาร์กิวเมนต์เพื่อให้นักเทียบท่ารันจากนั้นไปที่แอปพลิเคชันหรืออย่างที่ฉันทำแมปตำแหน่งของ jdbc.properties ผ่านโวลุ่มไปยังไดเร็กทอรีบนเครื่องโฮสต์ดังนั้นคุณจึงสามารถจัดการไฟล์ภายนอกได้ .

  docker run -it -v /host_dir/docker_jdbc_config:${jetty_base}/var/config myimage

หมายเหตุ: ฐานข้อมูลของคุณอาจไม่อนุญาตให้เชื่อมต่อภายนอก ในกรณีของ postgresql คุณต้องแก้ไข 2 ไฟล์ตามที่อธิบายไว้ที่นี่และที่นี่ :

  1. แก้ไข postgresql.conf เพื่อฟังที่อยู่ทั้งหมด โดยค่าเริ่มต้นจะชี้ไปที่ localhost

    listen_addresses = '*'
    
  2. แก้ไข pg_hba.conf เพื่ออนุญาตการเชื่อมต่อจากที่อยู่ทั้งหมด เพิ่มในบรรทัดสุดท้าย:

    host     all             all             0.0.0.0/0               md5
    

สิ่งสำคัญ: ไม่แนะนำให้อัปเดตการเข้าถึงฐานข้อมูลขั้นตอนสุดท้ายสำหรับการใช้งานจริงเว้นแต่คุณจะแน่ใจจริงๆว่ากำลังทำอะไรอยู่


--net = โฮสต์ทำงานให้ฉันในสภาพแวดล้อม CI ขอบคุณมาก!
Samy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.