วิธีรับที่อยู่ IP ของโฮสต์นักเทียบท่าจากภายในคอนเทนเนอร์นักเทียบท่า


358

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


คุณช่วยอธิบายรายละเอียดเกี่ยวกับวิธีการใช้ข้อมูลนี้ได้อย่างไร? คุณพูดว่า "นักเทียบท่าโฮสต์" - คุณใช้งานนักเทียบท่าบนโฮสต์มากกว่าหนึ่งแห่งหรือไม่ เมื่อคอนเทนเนอร์ของคุณรู้ที่อยู่ IP ของโฮสต์และแผนที่จะทำอะไร
Andy

วิธีที่ง่ายที่สุดในการส่งที่อยู่ IP ของโฮสต์นักเทียบท่าไปยังคอนเทนเนอร์นักเทียบท่าฉันคิดว่าคุณควรโทรภายในคอนเทนเนอร์โดยใช้ 'นักเทียบท่าที่คอนเทนเนอร์ exec' สมมติว่าคุณต้องการ ping โฮสต์จากภายใน busybox container ใช้ตัวอย่างเช่น: $ IP = '8.8.8.8' && docker container busybox ping $ IP 'วิธีหา IP โฮสต์ใช้สิ่งที่คุณชอบมากกว่านี้
SauloAlessandre

คำตอบ:


314
/sbin/ip route|awk '/default/ { print $3 }'

ตามที่ @MichaelNeale สังเกตว่าไม่มีความรู้สึกที่จะใช้วิธีนี้ในDockerfile(ยกเว้นเมื่อเราต้องการ IP นี้ในช่วงเวลาที่สร้างเท่านั้น) เพราะ IP นี้จะถูก hardcoded ในช่วงเวลาที่สร้าง


49
เมื่อคุณใช้นักเทียบท่าบริดจ์ (ค่าเริ่มต้น) สำหรับคอนเทนเนอร์สิ่งนี้จะส่งออกบริดจ์ IP เช่น 172.17.42.1 มากกว่า IP ของโฮสต์เช่น 192.168.1.x (ฉันสมมติว่าโฮสต์ของคุณอยู่ใน NAT ที่บ้าน) การใช้คำตอบ @Magno Torres อาจเป็นสิ่งที่ผู้คนต้องการในสถานการณ์เช่นนี้หากคุณต้องการที่อยู่ 192.168.1.x
Programster

2
RUN นั้นจะไม่ทำงานอย่างที่คุณคาดหวังมันจะคำนวณเฉพาะ IP ณ เวลาที่สร้างและจะคงที่ตลอดไปหลังจากนั้นและไม่มีประโยชน์ มันจะเป็น IP ของโฮสต์สร้าง
Michael Neale

7
@ โปรแกรมฉันสามารถสันนิษฐานได้ว่าผู้คนต้องการการเชื่อมต่อระหว่าง host docker และ container นั่นคือสิ่งที่ bridge IP สามารถให้ได้ (แน่นอนในการติดตั้ง stndard "home") ทำไมทุกคนต้องการ IP โฮสต์ของแท้ถ้ามันสามารถอยู่นอก Docker Bridge และไม่สามารถเข้าถึงได้ นี่เป็นวิธีแก้ปัญหาสำหรับทุกคนที่เพิ่งติดตั้ง Docker และต้องการเล่นกับมันในเวลาอันสั้น
spinus

1
@MichaelNeale เหมือนก่อนฉันจะสมมติว่าคนส่วนใหญ่ที่เริ่มต้นด้วยนักเทียบท่าต้องการการเชื่อมต่อระหว่างโฮสต์และคอนเทนเนอร์ของพวกเขานั่นแหล่ะ หากมีใครบางคนกำลังทำการปรับใช้อย่างเหมาะสมบางทีเขาอาจไม่ได้ใช้สะพานนักเทียบท่าเขากำลังใช้ระบบเครือข่ายที่กำหนดเองและกว่าที่เขาจะตระหนักถึงนิสัยใจคอของเครือข่ายทั้งหมดหรือพวกเขามี DNS (หรือการค้นพบอะไรก็ตาม)
spinus

1
@spinus - แต่มันจะใช้ได้ก็ต่อเมื่อมันทำงานบนโฮสต์ที่มันถูกสร้างขึ้น - ในกรณีนั้น - คุณสามารถรหัสยาก - หรือดูมัน - ฉันคิดว่ามันไม่ใช่คำตอบที่เป็นประโยชน์และจะทำให้เข้าใจผิดมาก ของคน - แนะนำให้คุณลบออก (The RUN bit)
Michael Neale

182

ตั้งแต่เวอร์ชัน 18.03 คุณสามารถใช้host.docker.internalเป็น IP ของโฮสต์

ทำงานได้ในDocker สำหรับ Mac , Docker สำหรับ Windowsและบางทีอาจเป็นแพลตฟอร์มอื่นเช่นกัน

นี่คือการอัปเดตจาก Mac เฉพาะdocker.for.mac.localhostใช้ได้ตั้งแต่รุ่น 17.06 และdocker.for.mac.host.internalมีให้ตั้งแต่รุ่น 17.12 ซึ่งอาจยังใช้งานได้บนแพลตฟอร์มนั้น

หมายเหตุเช่นเดียวกับในเอกสารMacและWindowsสิ่งนี้มีวัตถุประสงค์เพื่อการพัฒนาเท่านั้น

ตัวอย่างเช่นฉันมีการตั้งค่าตัวแปรสภาพแวดล้อมบนโฮสต์ของฉัน:

MONGO_SERVER=host.docker.internal

ในdocker-compose.ymlไฟล์ของฉันฉันมีสิ่งนี้:

version: '3'

services:
  api:
    build: ./api
    volumes:
      - ./api:/usr/src/app:ro
    ports:
      - "8000"
    environment:
      - MONGO_SERVER
    command: /usr/local/bin/gunicorn -c /usr/src/app/gunicorn_config.py -w 1 -b :8000 wsgi

2
@allanberry น่าเสียดายที่ Docker folks ไม่ต้องการให้เรามีวิธีที่เป็นอิสระในการทำเช่นนี้เพราะพวกเขาไม่ต้องการยอมรับกรณีการใช้งานที่ไม่ตั้งใจ (เช่นการเข้าถึงบริการใด ๆ บนเครื่องท้องถิ่นจากตู้เทียบท่า)
Andy

21
ฉันถูกแนะนำให้รู้จักกับ Docker เช่นBuild มันหนึ่งครั้งรันทุกที่ แต่นี่เป็นเท็จโดยอัตโนมัติเนื่องจากคุณต้องกำหนดค่าระบบโฮสต์เช่นกัน ดังนั้นจึงdocker.for.mac..ไม่มีประโยชน์เนื่องจากในกรณีส่วนใหญ่คุณไม่มีสภาพแวดล้อม Linux หรือ Mac อย่างเดียวใน บริษัท ของคุณ มันผสมกันคุณมี devs ใช้ Linux และ Mac และ Windows โดเมนนี้ไม่สมเหตุสมผลเนื่องจาก 99% เป็นสภาพแวดล้อมแบบผสมของโฮสต์ ฉันไม่พัฒนาคอนเทนเนอร์ภายใต้ macOS และปรับใช้กับเซิร์ฟเวอร์ macOS ฉันปรับใช้กับ Linux นี่คือสิ่งที่ทุกคนทำ ดังนั้นสิ่งที่จะยิ่งจุดรวมของdocker.for.mac..?
TheFox

1
@allanberry ไม่สำคัญว่าคุณจะใช้หางมีหรือไม่มีdocker.for.mac.host.internal docker-composeฉันต้องการใช้โฮสต์คงที่ในไฟล์กำหนดค่า IDK ตัวอย่างเช่นdocker.host.internalซึ่งมักจะชี้ไปยังที่อยู่ IP โฮสต์ ไม่ว่าฉันจะใช้ระบบโฮสต์ใด นี่เป็นจุดรวมของการใช้ Docker เลย: ฉันต้องการอิสระ ฉันเข้าใจว่ามันยิ่งซับซ้อนมากขึ้นใน macOS เพราะคุณมีเลเยอร์อื่นระหว่างระบบโฮสต์และคอนเทนเนอร์ แต่อย่างไรก็ตามในความคิดของฉันdocker.for.mac.host.internalไม่มีประโยชน์ถ้าคุณสามารถใช้มันสำหรับ macOS เท่านั้น
TheFox

1
host.docker.internal ทำงานบน Docker สำหรับ Windowsด้วยเช่นกันอย่างน้อยตอนที่เขียนความคิดเห็นนี้
joanlofe

1
มันทำงานได้อย่างสมบูรณ์แบบฉันมี dockerCe สำหรับ windows และใช้งาน jenkins ในภาชนะหนึ่ง ฉันต้องการเรียกใช้คำสั่งนักเทียบท่าภายในเจนกินส์ แต่นักเทียบท่าไม่สามารถเชื่อมต่อที่เพิ่มขั้นตอนคลาวด์ฉันใช้ tcp: //host.docker.internal: 2375 และเปิดใช้งาน 'expose daemon บน localhost: 2375' และใช้งานได้ บันทึกมากเวลา ขอบคุณ!
Vikash

84

อัปเดต: บนDocker สำหรับ Macในเวอร์ชัน 18.03 คุณสามารถใช้host.docker.internalเป็น IP ของโฮสต์ ดูคำตอบของ allanberry สำหรับ Docker for Mac รุ่นก่อนคำตอบต่อไปนี้อาจยังมีประโยชน์:

ใน Docker for Mac docker0ไม่มีบริดจ์ดังนั้นคำตอบอื่น ๆ ที่นี่อาจใช้ไม่ได้ อย่างไรก็ตามทราฟฟิกขาออกทั้งหมดจะถูกกำหนดเส้นทางผ่านโฮสต์หลักของคุณดังนั้นตราบใดที่คุณพยายามเชื่อมต่อกับ IP จะรับรู้เป็นตัวเอง (และคอนเทนเนอร์นักเทียบท่าไม่คิดว่าเป็นตัวเอง) คุณควรจะเชื่อมต่อได้ ตัวอย่างเช่นถ้าคุณเรียกใช้จากเครื่องแม่รัน:

ipconfig getifaddr en0

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

sudo ifconfig lo0 alias 192.168.46.49

จากนั้นคุณสามารถทดสอบการเชื่อมต่อจากภายในคอนเทนเนอร์ของนักเทียบท่าด้วย telnet ในกรณีของฉันฉันต้องการเชื่อมต่อกับเซิร์ฟเวอร์ xdebug ระยะไกล:

telnet 192.168.46.49 9000

ตอนนี้เมื่อปริมาณการใช้ข้อมูลเข้าสู่ Mac ของคุณสำหรับ 192.168.46.49 (และปริมาณข้อมูลทั้งหมดที่ออกจากคอนเทนเนอร์ของคุณไม่ผ่านเครื่อง Mac) Mac ของคุณจะถือว่า IP เป็นของตัวเอง เมื่อคุณใช้ IP นี้เสร็จแล้วคุณสามารถลบชื่อแทนลูปแบ็คได้ดังนี้:

sudo ifconfig lo0 -alias 192.168.46.49

สิ่งหนึ่งที่ต้องระวังคือคอนเทนเนอร์นักเทียบท่าจะไม่ส่งทราฟฟิกไปยังโฮสต์หลักหากคิดว่าปลายทางของทราฟฟิกนั้นเป็นของตัวเอง ดังนั้นตรวจสอบอินเตอร์เฟสย้อนกลับภายในคอนเทนเนอร์หากคุณมีปัญหา:

sudo ip addr show lo

ในกรณีของฉันนี่แสดงให้เห็นinet 127.0.0.1/8ซึ่งหมายความว่าฉันไม่สามารถใช้ IP ใด ๆ ใน127.*ช่วง นั่นเป็นเหตุผลที่ฉันใช้192.168.*ในตัวอย่างด้านบน ตรวจสอบให้แน่ใจว่า IP ที่คุณใช้ไม่ขัดแย้งกับบางสิ่งในเครือข่ายของคุณ


จะล้างการตั้งค่าลูปแบ็คเหล่านี้หลังจากระบบรีสตาร์ทหรือไม่
Robbo_UK

@Robbo_UK ใช่แล้วนามแฝงวนรอบจะหายไปหลังจากที่คุณรีสตาร์ท Mac
ผู้บัญชาการรหัส

1
การใช้ชื่อโฮสต์นี้ไม่สมเหตุสมผลเนื่องจากไม่ทำงานภายใต้ Docker for Linux ทำไมพวกเขาถึงไม่เพิ่มมันเข้าไปในลีนุกซ์ด้วย?
TheFox

พวกเขากำลังดูอยู่ในขณะนี้ @TheFox: github.com/docker/libnetwork/pull/2348
Ivo Pereira

46

สำหรับผู้ที่ใช้งาน Docker ใน AWS ข้อมูลเมตาดาต้าสำหรับโฮสต์นั้นยังคงมีอยู่จากภายในคอนเทนเนอร์

curl http://169.254.169.254/latest/meta-data/local-ipv4

ตัวอย่างเช่น:

$ docker run alpine /bin/sh -c "apk update ; apk add curl ; curl -s http://169.254.169.254/latest/meta-data/local-ipv4 ; echo"
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
v3.3.1-119-gb247c0a [http://dl-cdn.alpinelinux.org/alpine/v3.3/main]
v3.3.1-59-g48b0368 [http://dl-cdn.alpinelinux.org/alpine/v3.3/community]
OK: 5855 distinct packages available
(1/4) Installing openssl (1.0.2g-r0)
(2/4) Installing ca-certificates (20160104-r2)
(3/4) Installing libssh2 (1.6.0-r1)
(4/4) Installing curl (7.47.0-r0)
Executing busybox-1.24.1-r7.trigger
Executing ca-certificates-20160104-r2.trigger
OK: 7 MiB in 15 packages
172.31.27.238

$ ifconfig eth0 | grep -oP 'inet addr:\K\S+'
172.31.27.238

นี่เป็นวิธีที่สะดวกมากสำหรับผู้ใช้ AWS ฉันใช้สิ่งนี้เพื่อกำหนดค่าไคลเอนต์ของตัวแทนกงสุลและที่อยู่ผูก เหมาะอย่างยิ่งเมื่อคุณอยู่ในสถานการณ์ที่คุณไม่สามารถใช้เครือข่ายโฮสต์ (เช่นการปรับใช้คอนเทนเนอร์ใน Elastic Beanstalk และ ECS)
Richard Clayton

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

บนพื้นฐานของ Phusion (บน Ubuntu) ฉันต้องเปลี่ยนคำสั่งของคุณเล็กน้อย:ifconfig eth0 | grep -oP 'inet \K\S+'
Meuoi

25

วิธีเดียวที่จะส่งผ่านข้อมูลโฮสต์เป็นสภาพแวดล้อมเมื่อคุณสร้างคอนเทนเนอร์

run --env <key>=<value>

19
โดยเฉพาะอย่างยิ่งที่อยู่ IP ของบริดจ์สามารถส่งผ่านโดยใช้ตัวเลือกบรรทัดคำสั่งเช่น: -e "DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')"(ใช้คำตอบที่ยอมรับจากunix.stackexchange.com/questions/87468/… )
ncoghlan

7
ฉันคิดว่ามันไม่ทำงานใน Docker สำหรับ Mac / Windows (IP บริดจ์)
zx1986

22

--add-hostอาจจะเป็นวิธีการแก้ปัญหาการทำความสะอาดมากขึ้น ( แต่ไม่มีส่วนพอร์ตเพียงโฮสต์สามารถจะจัดการกับการแก้ปัญหานี้) ดังนั้นในdocker runคำสั่งของคุณทำสิ่งที่ชอบ:

docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print  $3}'` [my container]

(จากhttps://stackoverflow.com/a/26864854/127400 )


ฉันพูดว่า "ทำเพื่อสิ่งนี้" เมื่อมีคนต้องการรายการใน / etc / hosts; ในคำถามนี้มันไม่เป็นความจริง OP ขอให้ "host and portmaps" และคุณครอบคลุมโฮสต์เท่านั้น
ไบรอัน

ตกลง. ฉันสับสนเล็กน้อยเนื่องจากโซลูชันที่ได้รับการยอมรับครอบคลุมเฉพาะส่วนโฮสต์เท่านั้น และฉันคิดว่าทางออกของคุณเหนือกว่า spinus ตัวใดตัวหนึ่ง
Augunrik

สิ่งนี้ไม่ทำงานหากคุณต้องการใช้ dind - docker-in-docker นักเทียบท่าด้านในจะมีไอพีที่แตกต่าง
เสียงดัง

12

แนวปฏิบัติที่ดีที่สุดมาตรฐานสำหรับแอพส่วนใหญ่ที่ต้องการทำสิ่งนี้โดยอัตโนมัติคือ: คุณไม่คุณทำไม่ได้แต่คุณมีคนที่ใช้ภาชนะบรรจุฉีดชื่อโฮสต์ / ที่อยู่ IP ภายนอกเป็นการกำหนดค่าเช่นตัวแปรสภาพแวดล้อมหรือไฟล์กำหนดค่า การอนุญาตให้ผู้ใช้ฉีดสิ่งนี้ให้การออกแบบที่พกพาได้มากที่สุด

ทำไมเรื่องนี้ถึงยากนัก เนื่องจากคอนเทนเนอร์จะออกแบบแอปพลิเคชันแยกจากสภาพแวดล้อมโฮสต์ เครือข่ายเนมสเปซไปที่คอนเทนเนอร์นั้นตามค่าเริ่มต้นและรายละเอียดของโฮสต์จะได้รับการปกป้องจากกระบวนการที่ทำงานอยู่ภายในคอนเทนเนอร์ซึ่งอาจไม่น่าเชื่อถืออย่างเต็มที่


มีตัวเลือกต่าง ๆ ขึ้นอยู่กับสถานการณ์ของคุณ:

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

ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'

ตัวอย่างที่แสดงสิ่งนี้กับเครือข่ายโฮสต์ในคอนเทนเนอร์ดูเหมือนว่า

docker run --rm --net host busybox /bin/sh -c \
  "ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'"

สำหรับ Docker Desktop บางเวอร์ชันพวกเขาฉีดรายการ DNS ลงใน VM ที่ฝังไว้:

getent hosts host.docker.internal | awk '{print $1}'

หากคุณกำลังทำงานในสภาพแวดล้อมแบบคลาวด์คุณสามารถตรวจสอบบริการข้อมูลเมตาได้จากผู้ให้บริการคลาวด์เช่น AWS one:

curl http://169.254.169.254/latest/meta-data/local-ipv4

หากคุณต้องการที่อยู่ภายนอก / อินเทอร์เน็ตของคุณคุณสามารถสอบถามบริการระยะไกลเช่น:

curl ifconfig.co

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

export HOST_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
docker run --rm -e HOST_IP busybox printenv HOST_IP

curl ifconfig.coคำสั่งที่เป็นประโยชน์จริงๆ.. ขอบคุณ :)
MadAboutProgramming

8

หากคุณต้องการที่อยู่จริงIP(ไม่ใช่บริดจ์IP) Windowsและคุณมีนักเทียบท่า18.03(หรือที่ใหม่กว่า) ทำสิ่งต่อไปนี้:

เรียกใช้ bash บนคอนเทนเนอร์จากโฮสต์ที่ชื่ออิมเมจnginx(ใช้งานได้Alpine Linux distribution):

 docker run -it nginx /bin/ash

จากนั้นเรียกใช้ภายในภาชนะ

/ # nslookup host.docker.internal

Name:      host.docker.internal
Address 1: 192.168.65.2

192.168.65.2เป็น IP ของโฮสต์ไม่ใช่บริดจ์ IP เหมือนกับspinusคำตอบที่ยอมรับได้

ฉันใช้ที่นี่host.docker.internal :

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


2
ฉันลองใช้วิธีแก้ปัญหาแล้วและดูเหมือนว่าไม่พบคำสั่ง nslookup
Sergey

@Sergey รูปภาพของคุณอ้างอิงจากAlpine Linuxอะไร? linux distributionถ้าไม่ได้แล้วตรวจสอบที่เทียบเท่าสำหรับคุณโดยเฉพาะ
Kamil Witkowski

ไม่ฉันใช้คำสั่งของคุณอย่างแน่นอน - นักเทียบท่าเรียกใช้ - มัน nginx / bin / ash
Sergey

OK - ถ้าคุณอยู่ในหน้าต่างแล้วฉันเปลี่ยนไปlinux containersและฉันไม่ได้ใช้windows containersเตอร์คุณสามารถทำได้โดยการคลิกที่เหมาะสมและเลือกdocker icon Switch to Linux containersฉันคิดว่าอาจมีความสำคัญเมื่อคุณกำลังดาวน์โหลดภาพ หากคุณมีการwindows containerตรวจสอบว่าการลบnginxภาพเก่าและดาวน์โหลดอีกครั้งจะได้รับภาชนะอื่น ถ้ามันยังจะไม่ทำงานให้คุณ - กว่าที่คุณสามารถพยายามที่จะติดตั้งในnslookup ash
Kamil Witkowski

หากคุณไม่สามารถทำ nslookup ให้ทำ ping มันจะแสดง IP ที่ได้รับการแก้ไข สำหรับฉันคำตอบนี้ใช้งานได้และฉันแค่ใช้ชื่อโฮสต์นี้ ( host.docker.internal) จากภายในภาชนะ
Dmitry Minkovsky

7

TLDR สำหรับ Mac และ Windows

docker run -it --rm alpine nslookup host.docker.internal

... พิมพ์ที่อยู่ IP ของโฮสต์ ...

nslookup: can't resolve '(null)': Name does not resolve

Name:      host.docker.internal
Address 1: 192.168.65.2

รายละเอียด

บนMacและWindows ที่คุณสามารถใช้ชื่อ DNS พิเศษhost.docker.internalคุณสามารถใช้ชื่อ

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


1
กรุณาอย่าเพิ่มคำตอบเดียวกันกับหลายคำถาม ตอบคำถามที่ดีที่สุดและทำเครื่องหมายส่วนที่เหลือเป็นข้อมูลซ้ำเมื่อคุณได้รับชื่อเสียงมากพอ หากไม่ใช่รายการที่ซ้ำกันให้ปรับแต่งโพสต์ไปที่คำถามและตั้งค่าสถานะสำหรับการลบ
Bhargav Rao

6

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

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

เกตเวย์สามารถเข้าถึงได้เช่น gateway.docker.internal https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds


5

หากคุณเปิดใช้งานAPI ระยะไกลนักเทียบท่า (ผ่านทาง-Htcp://0.0.0.0:4243ตัวอย่าง) และรู้ว่าชื่อโฮสต์หรือที่อยู่ IP ของเครื่องโฮสต์สามารถทำได้ด้วยการทุบตีจำนวนมาก

ภายในผู้ใช้คอนเทนเนอร์ของฉันbashrc:

export hostIP=$(ip r | awk '/default/{print $3}')
export containerID=$(awk -F/ '/docker/{print $NF;exit;}' /proc/self/cgroup)
export proxyPort=$(
  curl -s http://$hostIP:4243/containers/$containerID/json |
  node -pe 'JSON.parse(require("fs").readFileSync("/dev/stdin").toString()).NetworkSettings.Ports["DESIRED_PORT/tcp"][0].HostPort'
)

บรรทัดที่สองคว้า ID คอนเทนเนอร์จากเครื่องของคุณ /proc/self/cgroupไฟล์

บรรทัดที่สามหยิกออกไปยังเครื่องโฮสต์ (สมมติว่าคุณกำลังใช้ 4243 เป็นพอร์ตของนักเทียบท่า) แล้วใช้โหนดที่จะแยกกลับ JSON DESIRED_PORTสำหรับ


สิ่งนี้ใช้ได้เฉพาะเมื่อคุณใช้การส่งต่อพอร์ต อันที่จริงHostPortอาจจะเป็นข้อมูลที่เป็นประโยชน์ที่นี่โชคร้ายHostIpอาจจะมี0.0.0.0
Arnout Engelen

4

ฉันมี Ubuntu 16.03 สำหรับฉัน

docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print  $3}'` [image]

ไม่ไม่ทำงาน (IP ไม่ถูกต้องการสร้าง)

โซลูชันการทำงานของฉันคือ:

docker run --add-host dockerhost:`docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge` [image]

3

นี่เป็นอีกตัวเลือกสำหรับผู้ที่ใช้งาน Docker ใน AWS ตัวเลือกนี้หลีกเลี่ยงการใช้ apk เพื่อเพิ่มแพ็คเกจ curl และประหยัดพื้นที่ 7mb อันมีค่า ใช้ wget ในตัว (ส่วนหนึ่งของไบนารี BusyBox แบบ monolithic):

wget -q -O - http://169.254.169.254/latest/meta-data/local-ipv4

3

AFAIK ในกรณีของ Docker for Linux (การกระจายมาตรฐาน) ที่อยู่ IP ของโฮสต์จะเป็นเสมอ 172.17.0.1ของโฮสต์จะเป็น

วิธีที่ง่ายที่สุดในการรับมันคือifconfig(interface docker0) จากโฮสต์:

ifconfig

จากภายในนักเทียบท่าคำสั่งต่อไปนี้จากนักเทียบท่า: ip -4 route show default | cut -d" " -f3

คุณสามารถรันได้อย่างรวดเร็วในตัวเทียบท่าด้วยบรรทัดคำสั่งต่อไปนี้:

# 1. Run an ubuntu docker
# 2. Updates dependencies (quietly)
# 3. Install ip package   (quietly)
# 4. Shows (nicely) the ip of the host
# 5. Removes the docker (thanks to `--rm` arg)
docker run -it --rm ubuntu:19.10 bash -c "apt-get update && apt-get install iproute2 -y && ip -4 route show default | cut -d' ' -f3"

ฉันหวังว่ามันจะช่วย


2

ใน linux คุณสามารถเรียกใช้

HOST_IP=`hostname -I | awk '{print $1}'`

ใน macOS เครื่องโฮสต์ของคุณไม่ใช่โฮสต์ Docker นักเทียบท่าจะติดตั้งระบบปฏิบัติการโฮสต์ใน VirtualBox

HOST_IP=`docker run busybox ping -c 1 docker.for.mac.localhost | awk 'FNR==2 {print $4}' | sed s'/.$//'`

1
การบล็อกโค้ดครั้งแรกจะคว้า IP ของคอนเทนเนอร์และไม่ใช่ IP ของโฮสต์
Ari

mandoc of hostname -Iเตือนไม่ให้ "ทำสมมติฐานใด ๆ เกี่ยวกับลำดับของผลลัพธ์"
cannot_mutably_borrow

1

นี่เป็นการใช้งานแบบมินิมอลในNode.jsสำหรับผู้ที่กำลังเรียกใช้โฮสต์บนอินสแตนซ์ AWS EC2โดยใช้อินสแตนซ์เมทาดาทา EC2 ที่กล่าวถึงข้างต้น

const cp = require('child_process');
const ec2 = function (callback) {
    const URL = 'http://169.254.169.254/latest/meta-data/local-ipv4';
    // we make it silent and timeout to 1 sec
    const args = [URL, '-s', '--max-time', '1'];
    const opts = {};
    cp.execFile('curl', args, opts, (error, stdout) => {
        if (error) return callback(new Error('ec2 ip error'));
        else return callback(null, stdout);
    })
        .on('error', (error) => callback(new Error('ec2 ip error')));
}//ec2

และใช้เป็น

ec2(function(err, ip) {
        if(err) console.log(err)
        else console.log(ip);
    })


0

นี่คือวิธีที่ฉันทำ ในกรณีนี้มันจะเพิ่มรายการโฮสต์ลงใน / etc / hosts ภายในอิมเมจ docker ที่ชี้ไปยังราศีพฤษภ - โฮสต์ไปยัง IP ในเครื่องของฉัน:

TAURUS_HOST=`ipconfig getifaddr en0`
docker run -it --rm -e MY_ENVIRONMENT='local' --add-host "taurus-host:${TAURUS_HOST}" ...

จากนั้นภายในคอนเทนเนอร์ Docker สคริปต์สามารถใช้ชื่อโฮสต์ราศีพฤษภ - โฮสต์เพื่อออกไปยังเครื่องท้องถิ่นของฉันซึ่งโฮสต์คอนเทนเนอร์นักเทียบท่า


0

บางทีคอนเทนเนอร์ที่ฉันสร้างก็มีประโยชน์เช่นกันhttps://github.com/qoomon/docker-host

คุณสามารถใช้ชื่อคอนเทนเนอร์เพื่อเข้าถึงระบบโฮสต์เช่น curl http: // dockerhost: 9200ดังนั้นไม่จำเป็นต้องยุ่งกับที่อยู่ IP ใด ๆ


0

โซลูชันที่ฉันใช้จะขึ้นอยู่กับ "เซิร์ฟเวอร์" ที่ส่งคืนที่อยู่ภายนอกของโฮสต์ Docker เมื่อได้รับการร้องขอ http

ใน "เซิร์ฟเวอร์":

1) เริ่ม jwilder / nginx-proxy

# docker run -d -p <external server port>:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy

2) เริ่ม ipify container

# docker run -e VIRTUAL_HOST=<external server name/address> --detach --name ipify osixia/ipify-api:0.1.0

ตอนนี้เมื่อคอนเทนเนอร์ส่งคำขอ http ไปยังเซิร์ฟเวอร์เช่น

# curl http://<external server name/address>:<external server port>

ที่อยู่ IP ของโฮสต์นักเทียบท่าจะถูกส่งคืนโดย ipify ผ่านส่วนหัว http "X-Forwarded-For"

ตัวอย่าง (เซิร์ฟเวอร์ ipify มีชื่อ "ipify.example.com" และทำงานบนพอร์ต 80 โฮสต์ของนักเทียบท่ามี IP 10.20.30.40):

# docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
# docker run -e VIRTUAL_HOST=ipify.example.com --detach --name ipify osixia/ipify-api:0.1.0

ภายในคอนเทนเนอร์คุณสามารถโทรหา:

# curl http://ipify.example.com
10.20.30.40


-2

บน Ubuntu hostnameคำสั่งสามารถใช้กับตัวเลือกต่อไปนี้:

  • -i, --ip-address อยู่สำหรับชื่อโฮสต์
  • -I, --all-ip-addressesที่อยู่ทั้งหมดสำหรับโฮสต์

ตัวอย่างเช่น:

$ hostname -i
172.17.0.2

หากต้องการกำหนดให้กับตัวแปรสามารถใช้หนึ่งซับต่อไปนี้:

IP=$(hostname -i)

นี่จะให้ที่อยู่ IP ของตัวเชื่อมต่อคอนเทนเนอร์ไม่ใช่ของโฮสต์
Mario Camou

-7

กับ https://docs.docker.com/machine/install-machine/

a) $ docker-machine ip

b) รับที่อยู่ IP ของเครื่องหนึ่งเครื่องขึ้นไป

  $ docker-machine ip host_name

  $ docker-machine ip host_name1 host_name2

10
สิ่งนี้จะดึง IP ของเครื่องเสมือนที่รันคอนเทนเนอร์ docker ไม่ใช่ IP ของโฮสต์ที่คอนเทนเนอร์นั้นทำงาน
Spencer Williams

2
สิ่งนี้ใช้ได้กับนักเทียบท่าที่ทำงานบนเครื่องเทียบท่าเท่านั้น นักเทียบท่าใหม่สำหรับ Mac ไม่ได้ทำงานบนเครื่องเทียบท่า
thomas.han
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.