ความแตกต่างระหว่างลิงก์และ depend_on ใน docker_compose.yml


292

ตามเอกสารประกอบการเขียนของไฟล์ Docker Compose :

  • depends_on - แสดงการพึ่งพาระหว่างบริการอย่างชัดเจน
  • links- เชื่อมโยงไปยังภาชนะในการให้บริการอื่นและยังแสดงการพึ่งพาระหว่างบริการในลักษณะเดียวกับdepends_on

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

มันจะง่ายขึ้นถ้ามีตัวอย่าง แต่ฉันไม่สามารถหาได้

ฉันสังเกตเห็นเมื่อฉันเชื่อมโยงคอนเทนเนอร์ B กับคอนเทนเนอร์ A คอนเทนเนอร์ B จะเป็น "pingable" ภายในเชลล์ของคอนเทนเนอร์ A

ฉันวิ่งping Bเข้าไปใน container A bashและได้ผลเช่นนี้ (เพื่อการอ้างอิงภาพจากอินเทอร์เน็ต)

ป้อนคำอธิบายรูปภาพที่นี่


6
--linkธงตอนนี้เป็นคุณลักษณะมรดกเลิกของหางและเอกสารที่แสดงให้เห็น "มันอาจจะถูกลบออกในที่สุด" หาง: การเชื่อมโยงภาชนะมรดก แนะนำให้ใช้คุณสมบัติเครือข่าย DockerหรือวิธีการเขียนDocker ฉันคิดว่านี่จะเป็นประโยชน์กับทุกคนที่เรียนรู้เกี่ยวกับคุณลักษณะนี้
ดาว

คำตอบ:


122

โพสต์ต้องการการอัปเดตหลังจากlinksตัวเลือกเลิกใช้แล้ว

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

สำหรับdocker run, --linkเลิกใช้แล้วและควรถูกแทนที่ด้วยเครือข่ายที่กำหนดเอง

docker network create mynet
docker run -d --net mynet --name container1 my_image
docker run -it --net mynet --name container1 another_image

depends_onเป็นการแสดงออกเพื่อเริ่มต้น (และโดยปริยายภาพดึงคำสั่งซื้อ) linksซึ่งเป็นผลข้างเคียงที่ดีของ


13
StackOverflow ทั่วไปเหตุใดฉันต้องเลื่อนคำตอบด้านล่าง 147 และ 43 จุดเพื่อค้นหาคำตอบ 1 ข้อที่ดีที่สุด
u8it

3
@ u8it มันเป็นธรรมชาติของเวลาและอินเทอร์เน็ต
Michael Cole

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

ฉันไม่สามารถดูข้อมูลเกี่ยวกับการเชื่อมโยงถูกคัดค้านในนักเทียบท่า-เขียนรุ่น 3 เอกสาร: docs.docker.com/compose/compose-file/#links ฉันไม่เห็นตัวเลือกที่มีประโยชน์มากเกินไปเนื่องจากเรามีเครือข่ายที่ใช้ร่วมกันและขึ้นอยู่กับว่า แต่มันไม่ได้ถูกคัดค้านถ้าฉันอ่านเอกสารอย่างถูกต้อง
rideronthestorm

หมายเหตุ: คอนเทนเนอร์ (บริการจริง) ในเครือข่ายเดียวกันสามารถเข้าถึงได้โดยชื่อบริการไม่ใช่ชื่อคอนเทนเนอร์ เอกสารอย่างเป็นทางการ: docs.docker.com/compose/networking/#links
GarryOne

194

คำตอบนี้มีไว้สำหรับนักเทียบท่าเขียนรุ่น 2และยังใช้งานได้กับรุ่น 3

คุณยังสามารถเข้าถึงข้อมูลได้เมื่อคุณใช้ depend_on

ถ้าคุณดูที่ docker docs Docker Compose และ Djangoคุณยังสามารถเข้าถึงฐานข้อมูลเช่นนี้:

version: '2'
services:
  db:
    image: postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

อะไรคือความแตกต่างระหว่างลิงค์และ dependent_on?

ลิงค์:

เมื่อคุณสร้างคอนเทนเนอร์สำหรับฐานข้อมูลตัวอย่างเช่น:

docker run -d --name=test-mysql --env="MYSQL_ROOT_PASSWORD=mypassword" -P mysql

docker inspect d54cf8a0fb98 |grep HostPort

และคุณอาจพบว่า

"HostPort": "32777"

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

web:
  links:
   - db

ขึ้นอยู่กับ:

ฉันพบบล็อกที่ดีจาก Giorgio Ferraris Docker-compose.yml: จาก V1 ถึง V2

เมื่อนักเทียบท่าเขียนไฟล์ V2 มันจะสร้างเครือข่ายโดยอัตโนมัติระหว่างคอนเทนเนอร์ทั้งหมดที่กำหนดไว้ในไฟล์และทุกคอนเทนเนอร์จะสามารถอ้างถึงไฟล์อื่น ๆ ได้ทันทีโดยใช้ชื่อที่กำหนดไว้ในไฟล์ docker-compose.yml

และ

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

ปรับปรุง

ขึ้นอยู่กับ

แสดงการพึ่งพาระหว่างบริการซึ่งมีสองลักษณะพิเศษ:

  • docker-compose upจะเริ่มให้บริการตามลำดับการพึ่งพา ในตัวอย่างต่อไปนี้ db และ redis จะเริ่มต้นก่อนเว็บ
  • docker-compose up SERVICEจะรวมการขึ้นต่อกันของ SERVICE โดยอัตโนมัติ ในตัวอย่างต่อไปนี้เว็บประกอบนักเทียบท่าจะสร้างและเริ่มต้น db และ redis

ตัวอย่างง่ายๆ:

version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

หมายเหตุ: depend_on จะไม่รอให้ db และ redis เป็น“ พร้อม” ก่อนเริ่มต้นเว็บ - จนกว่าจะเริ่มต้นเท่านั้น หากคุณต้องรอให้บริการพร้อมให้ดูการควบคุมคำสั่งเริ่มต้นสำหรับข้อมูลเพิ่มเติมเกี่ยวกับปัญหานี้และกลยุทธ์ในการแก้ไข


ฉันได้อัปเดตคำตอบของฉันเพื่อชี้แจงว่าคำตอบนั้นมีไว้สำหรับเขียนไฟล์ v1
Xiongbing Jin

1
ยังคงใช้ได้สำหรับรุ่น 3 หรือไม่
fabiomaia

ใช่คุณอาจจะดูhttps://docs.docker.com/compose/compose-file/compose-versioning/
Windsooon

"ซึ่งหมายความว่าคุณสามารถเชื่อมต่อฐานข้อมูลจากพอร์ต localhost ของคุณ 32777 (3306 ในคอนเทนเนอร์) แต่พอร์ตนี้จะเปลี่ยนทุกครั้งที่คุณรีสตาร์ทหรือลบคอนเทนเนอร์" ไม่ใช่ถ้าคุณระบุการเชื่อมพอร์ตในไฟล์นักเทียบท่ามันจะไม่ . และเนื่องจากคำถามนี้เกี่ยวกับนักแต่งเพลงโดยเฉพาะฉันรู้สึกว่าตัวอย่างdocker runที่นี่ไม่เกี่ยวข้องอย่างสมบูรณ์นั่นไม่ใช่วิธีที่คอนเทนเนอร์จะทำงานอยู่ดี ฉันพลาดอะไรไป
Andrew Savinykh

ใช่คุณพูดถูกถ้าคุณระบุพอร์ต docker run ตัวอย่างของฉันต้องการชี้ให้เห็นว่าทำไมเราต้องใช้ depend_on หรือลิงก์แทนการใช้ hard-code หมายเลขพอร์ตเพียงเพราะถ้าคุณไม่ได้ระบุมันจะเปลี่ยนทุกครั้ง ฉันคิดว่าสิ่งนี้จะช่วยให้ผู้คนเข้าใจมากขึ้นเกี่ยวกับ depend_on หรือลิงก์
Windsooon

50

[อัพเดต ก.ย. 2559]: คำตอบนี้มีไว้สำหรับนักเทียบท่าเขียนไฟล์ v1 (ดังที่แสดงโดยไฟล์เขียนตัวอย่างด้านล่าง) สำหรับ v2 ดูคำตอบอื่น ๆ โดย @Windsooon

[คำตอบเดิม]:

มันค่อนข้างชัดเจนในเอกสารประกอบ depends_onตัดสินใจการพึ่งพาและลำดับของการสร้างคอนเทนเนอร์และlinksไม่เพียง แต่ทำสิ่งเหล่านี้เท่านั้น

ภาชนะบรรจุสำหรับบริการที่เชื่อมโยงจะสามารถเข้าถึงได้ที่ชื่อโฮสต์เหมือนกับชื่อแทนหรือชื่อบริการหากไม่ได้ระบุนามแฝง

ตัวอย่างเช่นสมมติว่าdocker-compose.ymlไฟล์ต่อไปนี้:

web:
  image: example/my_web_app:latest
  links:
    - db
    - cache

db:
  image: postgres:latest

cache:
  image: redis:latest

ด้วยlinksโค้ดภายในwebจะสามารถเข้าถึงฐานข้อมูลโดยใช้db:5432สมมติว่าพอร์ต 5432 เปิดอยู่ในdbภาพ หากdepends_onมีการใช้งานจะไม่สามารถทำได้ แต่ลำดับการเริ่มต้นของคอนเทนเนอร์จะถูกต้อง


คุณยกตัวอย่างให้ฉันได้ไหม เพราะส่วนนั้นเป็นสิ่งที่ฉันยังไม่ชัดเจน อาจมีตัวเลือกไฟล์เขียนอื่น ๆ ที่อาจทำให้เฉพาะเจาะจงมากขึ้น โปรดระบุรายละเอียดเพิ่มเติม ขอบคุณ!
itsjef

ขอบคุณมาก! ฉันเข้าใจแล้ว. หนึ่งคำถามสุดท้ายโปรด ดังนั้นในกรณีโดยเฉพาะอย่างยิ่งของฉันฉันปรับใช้แอพพลิเครางของฉันฉันควรใช้linksหรือdepends_onหรือทั้งของพวกเขาก็โอเค? การdocker-compose.ymlใช้งานในปัจจุบันของฉันdepends_onและสิ่งต่าง ๆ ดูเหมือนจะใช้ได้ดี :)
itsjef

หากคุณไม่จำเป็นต้องเข้าถึงคอนเทนเนอร์อื่นโดยตรงผ่านname:portก็depends_onสามารถทำได้
Xiongbing Jin

9
ชื่อ: พอร์ตทำงานได้โดยไม่ต้องเชื่อมโยงเมื่อคุณใช้เปิดเผย:
Amit Goldstein

7
"ถ้าใช้ depend_on สิ่งนี้จะเป็นไปไม่ได้ แต่คำสั่งเริ่มต้นของคอนเทนเนอร์จะถูกต้อง" สิ่งนี้ไม่ถูกต้อง มันจะทำงานถ้าคุณเพียงแค่ใช้ depend_on คุณยังสามารถเข้าถึงของคุณdbในwebการใช้ฐานข้อมูลชื่อโฮสต์
prog.Dusan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.