อะไรคือความแตกต่างระหว่างports
และexpose
ตัวเลือกในdocker-compose.yml
อะไรคือความแตกต่างระหว่างports
และexpose
ตัวเลือกในdocker-compose.yml
คำตอบ:
ตามที่อ้างอิงนักเทียบท่า-เขียน ,
เปิดเผยพอร์ต ระบุทั้งสองพอร์ต (โฮสต์: คอนเทนเนอร์) หรือเพียงแค่พอร์ตคอนเทนเนอร์ (เลือกพอร์ตโฮสต์แบบสุ่ม)
docker-compose.yml
หน้าตาของฉัน:
mysql:
image: mysql:5.7
ports:
- "3306"
ถ้าฉันทำdocker-compose ps
มันจะมีลักษณะดังนี้:
Name Command State Ports
-------------------------------------------------------------------------------------
mysql_1 docker-entrypoint.sh mysqld Up 0.0.0.0:32769->3306/tcp
เปิดเผยพอร์ตโดยไม่ต้องเผยแพร่ไปยังเครื่องโฮสต์ - จะสามารถเข้าถึงบริการที่เชื่อมโยงได้เท่านั้น สามารถระบุได้เฉพาะพอร์ตภายใน
พอร์ตไม่ได้สัมผัสกับเครื่องโฮสต์ แต่สัมผัสกับบริการอื่น ๆ เท่านั้น
mysql:
image: mysql:5.7
expose:
- "3306"
ถ้าฉันทำdocker-compose ps
มันจะมีลักษณะดังนี้:
Name Command State Ports
---------------------------------------------------------------
mysql_1 docker-entrypoint.sh mysqld Up 3306/tcp
expose
ใน Dockerfiles: "คำสั่ง EXPOSE ไม่ได้เผยแพร่พอร์ตจริงๆมันทำหน้าที่เป็นเอกสารประกอบ ... " docs.docker.com/engine/reference/builder/#expose
docker-compose run
นิยามพอร์ตdocker-compose.yml
จะถูกละเว้นโดยค่าเริ่มต้น ใช้docker-compose up
หรือระบุพารามิเตอร์--service-ports
พอร์ต :
เปิดเผย :
พอร์ต ส่วนนี้ใช้เพื่อกำหนดการแมประหว่างโฮสต์เซิร์ฟเวอร์และคอนเทนเนอร์ Docker
ports:
- 10005:80
หมายความว่าแอปพลิเคชันที่ทำงานอยู่ภายในคอนเทนเนอร์ได้รับการเปิดเผยที่พอร์ต 80 แต่ระบบ / เอนทิตีภายนอกไม่สามารถเข้าถึงได้ดังนั้นจึงจำเป็นต้องแมปกับพอร์ตเซิร์ฟเวอร์โฮสต์
หมายเหตุ: คุณต้องเปิดพอร์ตโฮสต์ 1,0005 และแก้ไขกฎไฟร์วอลล์เพื่ออนุญาตให้เอนทิตีภายนอกเข้าถึงแอปพลิเคชัน
พวกเขาสามารถใช้
http: // {host IP}: 10005
อะไรแบบนี้
เปิดเผย ใช้เพื่อกำหนดพอร์ตที่แอปพลิเคชันทำงานอยู่ภายในคอนเทนเนอร์นักเทียบท่าเท่านั้น
คุณสามารถกำหนดได้ใน dockerfile เช่นกัน โดยทั่วไปแล้วมันเป็นวิธีที่ดีและใช้กันอย่างแพร่หลายเพื่อกำหนด EXPOSE ภายใน dockerfile เพราะไม่ค่อยมีใครเรียกใช้พวกเขาในพอร์ตอื่น ๆ กว่า 80 พอร์ตเริ่มต้น
ports
ส่วนจะเผยแพร่พอร์ตบนโฮสต์ นักเทียบท่าจะตั้งค่าการส่งต่อสำหรับพอร์ตเฉพาะจากเครือข่ายโฮสต์ลงในคอนเทนเนอร์ โดยค่าเริ่มต้นสิ่งนี้จะถูกนำไปใช้กับกระบวนการพร็อกซี userspace ( docker-proxy
) ที่รับฟังพอร์ตแรกและส่งต่อไปยังคอนเทนเนอร์ซึ่งจำเป็นต้องฟังในจุดที่สอง หากคอนเทนเนอร์ไม่ได้ฟังบนพอร์ตปลายทางคุณจะยังคงเห็นบางสิ่งที่กำลังฟังอยู่บนโฮสต์ แต่รับการเชื่อมต่อที่ถูกปฏิเสธหากคุณพยายามเชื่อมต่อกับพอร์ตโฮสต์นั้น
หมายเหตุคอนเทนเนอร์จะต้องฟังบนอินเทอร์เฟซเครือข่ายทั้งหมดเนื่องจากพร็อกซีนี้ไม่ได้ทำงานอยู่ภายในเนมสเปซเครือข่ายของคอนเทนเนอร์และไม่สามารถเข้าถึง 127.0.0.1 ภายในคอนเทนเนอร์ วิธี IPv4 0.0.0.0
ที่คือการกำหนดค่าใบสมัครของคุณเพื่อฟังบน
นอกจากนี้โปรดทราบว่าพอร์ตที่เผยแพร่ไม่ทำงานในทิศทางตรงกันข้าม คุณไม่สามารถเชื่อมต่อกับบริการบนโฮสต์จากคอนเทนเนอร์โดยการเผยแพร่พอร์ต แต่คุณจะพบข้อผิดพลาดนักเทียบท่าที่พยายามฟังพอร์ตโฮสต์ที่ใช้งานแล้ว
เปิดเผยเป็นเอกสาร มันตั้งค่าเมทาดาทาบนรูปภาพและเมื่อทำงานบนคอนเทนเนอร์ด้วย โดยทั่วไปแล้วคุณกำหนดค่านี้ใน Dockerfile ด้วยEXPOSE
คำสั่งและทำหน้าที่เป็นเอกสารสำหรับผู้ใช้ที่เรียกใช้อิมเมจของคุณเพื่อให้พวกเขารู้ว่าพอร์ตใดที่แอปพลิเคชันของคุณจะรับฟัง เมื่อกำหนดค่าด้วยไฟล์เขียนข้อมูลเมตานี้จะถูกตั้งค่าบนคอนเทนเนอร์เท่านั้น คุณสามารถเห็นพอร์ตที่เปิดเผยเมื่อคุณเรียกใช้docker inspect
บนรูปภาพหรือคอนเทนเนอร์
มีเครื่องมือบางอย่างที่ใช้พอร์ตที่เปิดเผย ในนักเทียบท่า-P
ธงจะเผยแพร่พอร์ตที่เปิดเผยทั้งหมดไปยังพอร์ตชั่วคราวบนโฮสต์ นอกจากนี้ยังมีพร็อกซีย้อนกลับต่าง ๆ ที่จะใช้พอร์ตที่เปิดเผยเมื่อส่งการรับส่งข้อมูลไปยังแอปพลิเคชันของคุณหากคุณไม่ได้ตั้งค่าพอร์ตคอนเทนเนอร์ไว้อย่างชัดเจน
นอกเหนือจากเครื่องมือภายนอกเหล่านั้นการเปิดเผยไม่มีผลกระทบใด ๆ ต่อระบบเครือข่ายระหว่างคอนเทนเนอร์ คุณต้องการเครือข่ายนักเทียบท่าทั่วไปและเชื่อมต่อกับพอร์ตคอนเทนเนอร์เพื่อเข้าถึงคอนเทนเนอร์หนึ่งจากอีกพอร์ตหนึ่ง หากเครือข่ายนั้นเป็นผู้ใช้ที่สร้างขึ้น (เช่นไม่ใช่เครือข่ายบริดจ์เริ่มต้นที่ตั้งชื่อbridge
) คุณสามารถใช้ DNS เพื่อเชื่อมต่อกับคอนเทนเนอร์อื่น ๆ
ฉันเห็นด้วยกับคำตอบทั้งหมดก่อน ฉันแค่พูดถึงความแตกต่างระหว่างการเปิดเผยและพอร์ตเป็นส่วนหนึ่งของแนวคิดความปลอดภัยในนักเทียบท่า มันไปจับมือกับเครือข่ายของนักเทียบท่า ตัวอย่างเช่น:
ลองนึกภาพแอปพลิเคชั่นที่มีส่วนหน้าเว็บและฐานข้อมูลส่วนหลัง โลกภายนอกต้องการเข้าถึงเว็บฟรอนต์เอนด์ (อาจจะอยู่ที่พอร์ต 80) แต่มีเพียงแบ็คเอนด์เท่านั้นที่ต้องการเข้าถึงโฮสต์ฐานข้อมูลและพอร์ต การใช้บริดจ์ที่ผู้ใช้กำหนดจะต้องเปิดเว็บพอร์ตเท่านั้นและแอปพลิเคชันฐานข้อมูลไม่จำเป็นต้องเปิดพอร์ตใด ๆ เนื่องจากเว็บส่วนหน้าสามารถเข้าถึงได้ผ่านทางบริดจ์ที่ผู้ใช้กำหนดเอง
นี่เป็นกรณีการใช้งานทั่วไปเมื่อตั้งค่าสถาปัตยกรรมเครือข่ายในตัวเทียบท่า ตัวอย่างเช่นในเครือข่ายบริดจ์เริ่มต้นไม่ใช่พอร์ตที่สามารถเข้าถึงได้จากโลกภายนอก ดังนั้นคุณสามารถเปิดจุดเข้าใช้งานด้วย "พอร์ต" ด้วยการใช้ "เปิดเผย" คุณจะกำหนดการสื่อสารภายในเครือข่าย หากคุณต้องการแสดงพอร์ตเริ่มต้นคุณไม่จำเป็นต้องกำหนด "expose" ในไฟล์ที่ประกอบขึ้นด้วยนักเทียบท่า
expose
ในdocker-compose
? เท่าที่ฉันสามารถบอกได้คุณไม่จำเป็นต้องระบุการเปิดเผยเพื่อให้พอร์ตสามารถเข้าถึงบริการที่เชื่อมโยงได้