ความแตกต่างระหว่างพอร์ตนักเขียนประกอบด้วยพอร์ตเทียบกับการเปิดเผยคืออะไร


คำตอบ:


527

ตามที่อ้างอิงนักเทียบท่า-เขียน ,

พอร์ตถูกกำหนดเป็น:

เปิดเผยพอร์ต ระบุทั้งสองพอร์ต (โฮสต์: คอนเทนเนอร์) หรือเพียงแค่พอร์ตคอนเทนเนอร์ (เลือกพอร์ตโฮสต์แบบสุ่ม)

  • พอร์ตที่กล่าวถึงใน 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

24
มันจะเป็นไป eto อธิบายสิ่งที่ได้เปรียบที่มีการระบุexposeในdocker-compose? เท่าที่ฉันสามารถบอกได้คุณไม่จำเป็นต้องระบุการเปิดเผยเพื่อให้พอร์ตสามารถเข้าถึงบริการที่เชื่อมโยงได้
Juicy

3
ไม่ควรที่จะบอกว่าพอร์ตที่เปิดเผยจะมีให้บริการในเครือข่ายนักเทียบท่าเดียวกันเท่านั้น (การเชื่อมโยงจะถูกแทนที่สำหรับชิ้นส่วนส่วนใหญ่)
meow

8
@ Juicy ฉันคิดว่ามันคล้ายกับexposeใน Dockerfiles: "คำสั่ง EXPOSE ไม่ได้เผยแพร่พอร์ตจริงๆมันทำหน้าที่เป็นเอกสารประกอบ ... " docs.docker.com/engine/reference/builder/#expose
tsauerwein

1
พอร์ตแทนที่การตั้งค่าใด ๆ ที่ระดับไฟร์วอลล์หรือไม่ ฉันเพิ่งสังเกตเห็นว่าฉันไม่ได้เปิดพอร์ตสำหรับ mysql บนไฟร์วอลล์ แต่สามารถเข้าถึงได้จากระยะไกล ฉันตั้งค่าพอร์ตเป็น "3306: 3306" แทนที่จะเป็นที่เปิดเผย
TekiusFanatikus

3
และจำไว้ว่าถ้าคุณใช้docker-compose runนิยามพอร์ตdocker-compose.ymlจะถูกละเว้นโดยค่าเริ่มต้น ใช้docker-compose upหรือระบุพารามิเตอร์--service-ports
Juha Untinen

177

พอร์ต :

  1. เปิดใช้งานคอนเทนเนอร์เพื่อฟังพอร์ตที่ระบุจากโลกภายนอกนักเทียบท่า (สามารถเป็นเครื่องโฮสต์เดียวกันหรือเครื่องอื่น) และยังสามารถเข้าถึงโลกภายในนักเทียบท่าได้
  2. สามารถระบุได้มากกว่าหนึ่งพอร์ต (นั่นคือเหตุผลที่พอร์ตไม่ใช่พอร์ต)

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

เปิดเผย :

  1. เปิดใช้งานคอนเทนเนอร์เพื่อฟังพอร์ตเฉพาะจากโลกภายในนักเทียบท่าและไม่สามารถเข้าถึงโลกภายนอกตัวเชื่อมต่อได้
  2. สามารถระบุได้มากกว่าหนึ่งพอร์ต

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


3
โปรดทราบว่าการเปิดเผยอนุญาตให้มีหลายพอร์ต - docs.docker.com/compose/compose-file/#expose - อย่างไรก็ตามคุณจะจัดหาพอร์ตภายในแทนที่จะเป็นภายใน + ภายนอก
Stuart Moore

แต่จะทำอย่างไรถ้าฉันต้องการที่จะเข้าถึงโลกภายนอกจากภาชนะของฉัน? stackoverflow.com/questions/61322256/…
gstackoverflow

25

พอร์ต ส่วนนี้ใช้เพื่อกำหนดการแมประหว่างโฮสต์เซิร์ฟเวอร์และคอนเทนเนอร์ Docker

ports:
   - 10005:80

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

หมายเหตุ: คุณต้องเปิดพอร์ตโฮสต์ 1,0005 และแก้ไขกฎไฟร์วอลล์เพื่ออนุญาตให้เอนทิตีภายนอกเข้าถึงแอปพลิเคชัน

พวกเขาสามารถใช้

http: // {host IP}: 10005

อะไรแบบนี้

เปิดเผย ใช้เพื่อกำหนดพอร์ตที่แอปพลิเคชันทำงานอยู่ภายในคอนเทนเนอร์นักเทียบท่าเท่านั้น

คุณสามารถกำหนดได้ใน dockerfile เช่นกัน โดยทั่วไปแล้วมันเป็นวิธีที่ดีและใช้กันอย่างแพร่หลายเพื่อกำหนด EXPOSE ภายใน dockerfile เพราะไม่ค่อยมีใครเรียกใช้พวกเขาในพอร์ตอื่น ๆ กว่า 80 พอร์ตเริ่มต้น


19

พอร์ต

portsส่วนจะเผยแพร่พอร์ตบนโฮสต์ นักเทียบท่าจะตั้งค่าการส่งต่อสำหรับพอร์ตเฉพาะจากเครือข่ายโฮสต์ลงในคอนเทนเนอร์ โดยค่าเริ่มต้นสิ่งนี้จะถูกนำไปใช้กับกระบวนการพร็อกซี userspace ( docker-proxy) ที่รับฟังพอร์ตแรกและส่งต่อไปยังคอนเทนเนอร์ซึ่งจำเป็นต้องฟังในจุดที่สอง หากคอนเทนเนอร์ไม่ได้ฟังบนพอร์ตปลายทางคุณจะยังคงเห็นบางสิ่งที่กำลังฟังอยู่บนโฮสต์ แต่รับการเชื่อมต่อที่ถูกปฏิเสธหากคุณพยายามเชื่อมต่อกับพอร์ตโฮสต์นั้น

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

นอกจากนี้โปรดทราบว่าพอร์ตที่เผยแพร่ไม่ทำงานในทิศทางตรงกันข้าม คุณไม่สามารถเชื่อมต่อกับบริการบนโฮสต์จากคอนเทนเนอร์โดยการเผยแพร่พอร์ต แต่คุณจะพบข้อผิดพลาดนักเทียบท่าที่พยายามฟังพอร์ตโฮสต์ที่ใช้งานแล้ว

เปิดเผย

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

มีเครื่องมือบางอย่างที่ใช้พอร์ตที่เปิดเผย ในนักเทียบท่า-Pธงจะเผยแพร่พอร์ตที่เปิดเผยทั้งหมดไปยังพอร์ตชั่วคราวบนโฮสต์ นอกจากนี้ยังมีพร็อกซีย้อนกลับต่าง ๆ ที่จะใช้พอร์ตที่เปิดเผยเมื่อส่งการรับส่งข้อมูลไปยังแอปพลิเคชันของคุณหากคุณไม่ได้ตั้งค่าพอร์ตคอนเทนเนอร์ไว้อย่างชัดเจน

นอกเหนือจากเครื่องมือภายนอกเหล่านั้นการเปิดเผยไม่มีผลกระทบใด ๆ ต่อระบบเครือข่ายระหว่างคอนเทนเนอร์ คุณต้องการเครือข่ายนักเทียบท่าทั่วไปและเชื่อมต่อกับพอร์ตคอนเทนเนอร์เพื่อเข้าถึงคอนเทนเนอร์หนึ่งจากอีกพอร์ตหนึ่ง หากเครือข่ายนั้นเป็นผู้ใช้ที่สร้างขึ้น (เช่นไม่ใช่เครือข่ายบริดจ์เริ่มต้นที่ตั้งชื่อbridge) คุณสามารถใช้ DNS เพื่อเชื่อมต่อกับคอนเทนเนอร์อื่น ๆ


3

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

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

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

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