จะเชื่อมโยงบริการ Docker ข้ามโฮสต์ได้อย่างไร?


115

เทียบท่าช่วยให้เซิร์ฟเวอร์จากหลายคอนเทนเนอร์เพื่อเชื่อมต่อกับแต่ละอื่น ๆ ผ่านการเชื่อมโยงและการค้นพบบริการ อย่างไรก็ตามจากสิ่งที่ฉันเห็นการค้นพบบริการนี้เป็นแบบโฮสต์ในพื้นที่ ฉันต้องการใช้บริการที่ใช้บริการอื่นที่โฮสต์บนเครื่องอื่น

มีหลายวิธีในการแก้ปัญหานี้ใน Docker เช่นCoreOS ของjumpersโฮสต์ - บริการท้องถิ่นที่พร็อกซีไปยังเครื่องอื่นเป็นหลักและโครงการ github ทั้งหมดสำหรับจัดการการปรับใช้ Docker ที่ดูเหมือนจะพยายามรองรับกรณีการใช้งานนี้ .

เมื่อพิจารณาถึงการพัฒนาจึงเป็นเรื่องยากที่จะปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดในปัจจุบัน ดังนั้นคำถามของฉันโดยพื้นฐานแล้ว:

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

คำตอบ:


58

ปรับปรุง

Docker เพิ่งประกาศเครื่องมือใหม่ชื่อว่าSwarm for Docker orchestration

Swarmช่วยให้คุณ "เข้าร่วม" docker daemons หลายตัว: ก่อนอื่นคุณต้องสร้างฝูงเริ่มต้นผู้จัดการฝูงในเครื่องเดียวและให้นักเทียบท่า "เข้าร่วม" ตัวจัดการฝูงโดยใช้ตัวระบุของฝูง ไคลเอนต์นักเทียบท่าเชื่อมต่อกับตัวจัดการฝูงราวกับว่าเป็นเซิร์ฟเวอร์นักเทียบท่าทั่วไป

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

$ docker run -d -P -e constraint:storage=ssd mysql

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

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

Swarmอยู่ในช่วงเบต้า


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

นอกจากนี้ยังมีส่วนขยายของ บริษัท อื่นอีกหลายรายการที่ทำให้คลัสเตอร์ Docker สามารถใช้งานได้ โซลูชันของบุคคลที่สาม ได้แก่ :

  • การเชื่อมต่อบริดจ์เครือข่าย Docker บนโฮสต์สองโฮสต์มีน้ำหนักเบาและมีโซลูชันที่หลากหลาย แต่โดยทั่วไปจะมีข้อแม้บางประการ
  • การค้นหาโดยใช้ DNS เช่นด้วยskydockและ SkyDNS
  • เครื่องมือการจัดการนักเทียบท่าเช่นอู่ต่อเรือและเครื่องมือจัดเตรียมนักเทียบท่า ดูคำถามนี้สำหรับรายการที่ครอบคลุม: วิธีปรับขนาดคอนเทนเนอร์ Docker ในการผลิต

2
ดังนั้นโดยพื้นฐานแล้วยังไม่มีวิธีเชื่อมโยงคอนเทนเนอร์ข้ามโฮสต์ที่ไม่เกี่ยวข้องกับรูปแบบ ambasador หรือข้ามนักเทียบท่าและพูดคุยกับ lxc โดยตรง?
user3012759

@ user3012759 Ambassador Pattern เป็นวิธีดั้งเดิมที่กำหนดขึ้นเท่านั้น แต่ Swarm (ในอัลฟา) เป็นอีกวิธีดั้งเดิมที่ใช้งานได้โดยแทนที่ Docker Scheduler ขอโทษที่ตอบช้า.
lyschoening

SkyDock ไม่ได้ (ยัง: 03/2015) รวมถึงการสนับสนุนหลายโฮสต์ Registrator (โปรเจ็กต์แบบง่ายที่สามารถทำงานกับ SkyDNS) ทำได้ แต่การกำหนดค่าเป็นแบบแมนนวลมากกว่า (บริการต้องมีพอร์ตที่แมปกับพอร์ตโฮสต์)
Turtlemonvh

6
การตรวจสอบ swarm คร่าวๆของฉันแสดงให้เห็นว่ามันมุ่งเน้นไปที่การจัดการคลัสเตอร์ไม่ใช่การเชื่อมต่อระหว่างโฮสต์ ข้อบกพร่องนี้ระบุไว้อย่างชัดเจนโดยการสาธิตของ Docker youtube.com/watch?v=M4PFY6RZQHQ&t=3m37s
Bruno Bronosky

1
@lyschoening Docker ประกาศเครือข่ายโฮสต์หลายโฮสต์ที่คุณอาจต้องการอัปเดตคำตอบของคุณ
Thomasleveil

15

อัปเดต 3

Libswarm ถูกเปลี่ยนชื่อเป็นswarmและตอนนี้เป็นแอปพลิเคชันแยกต่างหาก

นี่คือตัวอย่างหน้า github เพื่อใช้เป็นจุดเริ่มต้น:

# create a cluster
$ swarm create
6856663cdefdec325839a4b7e1de38e8

# on each of your nodes, start the swarm agent
#  <node_ip> doesn't have to be public (eg. 192.168.0.X),
#  as long as the other nodes can reach it, it is fine.
$ swarm join --token=6856663cdefdec325839a4b7e1de38e8 --addr=<node_ip:2375>

# start the manager on any machine or your laptop
$ swarm manage --token=6856663cdefdec325839a4b7e1de38e8 --addr=<swarm_ip:swarm_port>

# use the regular docker cli
$ docker -H <swarm_ip:swarm_port> info
$ docker -H <swarm_ip:swarm_port> run ... 
$ docker -H <swarm_ip:swarm_port> ps 
$ docker -H <swarm_ip:swarm_port> logs ...
...

# list nodes in your cluster
$ swarm list --token=6856663cdefdec325839a4b7e1de38e8
http://<node_ip:2375>

อัปเดต 2

แนวทางอย่างเป็นทางการคือการใช้libswarmดูการสาธิตที่นี่

UPDATE

มีส่วนสำคัญที่ดีสำหรับการสื่อสารโฮสต์ openvswitch ในนักเทียบท่าโดยใช้แนวทางเดียวกัน

ในการอนุญาตให้บริการการค้นพบที่นั่นเป็นวิธีการที่น่าสนใจบนพื้นฐานของ DNS ที่เรียกว่าskydock

นอกจากนี้ยังมีscreencast


นี่เป็นบทความที่ดีโดยใช้ปริศนาชิ้นเดียวกัน แต่เพิ่ม vlans ไว้ด้านบนด้วย:

http://fbevmware.blogspot.it/2013/12/coupling-docker-and-open-vswitch.html

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

ดังนั้นคุณสามารถใช้โซลูชันได้อย่างปลอดภัยและรอให้สามารถทำได้ด้วยวิธีที่ง่ายกว่าเมื่อ Docker นำไปใช้


2
ช่วงนี้ไม่ค่อยมีกิจกรรมใน libswarm ฉันสงสัยว่าทีมนักเทียบท่ากำลังก้าวไปในทิศทางอื่นหรือไม่?
รามัน

12

Weaveเป็นเทคโนโลยีเครือข่ายเสมือน Docker ใหม่ที่ทำหน้าที่เป็นสวิตช์อีเธอร์เน็ตเสมือนบน TCP / UDP สิ่งที่คุณต้องมีคือคอนเทนเนอร์ Docker ที่รัน Weave บนโฮสต์ของคุณ

สิ่งที่น่าสนใจคือ

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

สิ่งนี้นำไปสู่สถานการณ์ที่น่าสนใจเช่น

  • สร้างเครือข่ายเสมือนผ่าน WAN ไม่มีคอนเทนเนอร์ Docker ใดที่จะรู้หรือสนใจว่าเครือข่ายจริงนั้นอยู่ในเครือข่ายใด
  • ย้ายคอนเทนเนอร์ของคุณไปยังโฮสต์นักเทียบท่าที่แตกต่างกัน Weave จะตรวจจับเพียร์ตามนั้น

ตัวอย่างเช่นมีคำแนะนำตัวอย่างเกี่ยวกับวิธีสร้างคลัสเตอร์ Cassandra แบบหลายโหนดในแล็ปท็อปของคุณและโฮสต์บนคลาวด์ (EC2) สองสามคำสั่งที่มีสองคำสั่งต่อโฮสต์ ฉันเปิดตัวคลัสเตอร์ CoreOS ด้วย AWS CloudFormation ซึ่งติดตั้งสานบนแต่ละใน / home / core รวมถึง VM ของนักเทียบท่าแล็ปท็อปที่เร่ร่อนของฉันและได้รับคลัสเตอร์ภายในหนึ่งชั่วโมง แล็ปท็อปของฉันถูกไฟไหม้ แต่ Weave ดูเหมือนจะโอเคกับสิ่งนั้นเพียงแค่เชื่อมต่อกับ EC2 peers


จากสิ่งที่ฉันเข้าใจสานคือการซ้อนทับเครือข่ายที่ทำงานภายในคอนเทนเนอร์สำหรับการเชื่อมต่อบริการในขณะที่ swarm เป็นเทคโนโลยีคลัสเตอร์ที่ขยาย Docker CLI สำหรับการจัดโครงสร้างพื้นฐาน การเชื่อมต่อโครงสร้างพื้นฐานจำเป็นต้องทำนอกฝูง (เช่นการใช้สวิตช์ปกติ) และการจัดเตรียมบริการด้านนอกสาน (ใช้เช่น Mesos / Kubernetes) ตรงกับความคิดของคุณเกี่ยวกับวิธีการทำงานหรือไม่?
Henrik

นี่คือวิธีที่ฉันจะดู: นักเทียบท่าเขียนเกี่ยวกับการเชื่อมโยงคอนเทนเนอร์และการจัดระเบียบกลุ่มนักเทียบท่าเป็นเรื่องเกี่ยวกับการเรียกใช้นักเทียบท่าในโฮสต์นักเทียบท่าหลายคนซ็อกเก็ตเพลน (ปัจจุบันเป็นของนักเทียบท่า) และการสานเป็นเครือข่ายซ้อนทับ Socketplane ขึ้นอยู่กับ openvswitch ซึ่งมักใช้สำหรับการวางซ้อนใน VMs (เช่น openstack) ในทางกลับกันการสานเป็นนักเทียบท่าเท่านั้น จากทั้งหมดนี้ Mesos / Kubernetes / Lattice จะมาแทนที่กลุ่มนักเทียบท่าที่มีประสบการณ์การใช้งานและระดับความสามารถในการปรับขนาดที่แตกต่างจาก Docker CLI
Stuart Charlton

7

ปรับปรุง

Docker 1.12 มีโหมดที่เรียกว่า swarm และยังเพิ่มสิ่งที่เป็นserviceนามธรรม พวกเขาอาจไม่สมบูรณ์เพียงพอสำหรับทุกกรณีการใช้งาน แต่ฉันขอแนะนำให้คุณสังเกตดู อย่างน้อยโหมดจับกลุ่มก็ช่วยในการตั้งค่าหลายโฮสต์ซึ่งไม่จำเป็นต้องทำให้การเชื่อมโยงง่ายขึ้น เซิร์ฟเวอร์ DNS ภายในของ Docker (ตั้งแต่ 1.11) ควรช่วยให้คุณเข้าถึงชื่อคอนเทนเนอร์ได้หากเป็นที่รู้จักกันดีนั่นหมายความว่าชื่อที่สร้างขึ้นในบริบท Swarm จะไม่สามารถระบุได้ง่าย


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

คุณจะต้องมีร้านค้า K / V (เช่น Consul) ซึ่งอนุญาตให้แชร์สถานะกับเครื่องมือ Docker ต่างๆในทุกโฮสต์ เครื่องมือ Docker ทุกตัวต้องได้รับการกำหนดค่าด้วยที่เก็บ K / V นั้นจากนั้นคุณสามารถใช้ Swarm เพื่อเชื่อมต่อโฮสต์ของคุณได้

จากนั้นสร้างเครือข่ายการวางซ้อนใหม่ดังนี้:

$ docker network create --driver overlay my-network

ขณะนี้คอนเทนเนอร์สามารถรันโดยใช้ชื่อเครือข่ายเป็นพารามิเตอร์ run:

$ docker run -itd --net=my-network busybox

นอกจากนี้ยังสามารถเชื่อมต่อกับเครือข่ายเมื่อทำงานอยู่แล้ว:

$ docker network connect my-network my-container

รายละเอียดเพิ่มเติมมีอยู่ในเอกสาร


6

บทความต่อไปนี้อธิบายถึงวิธีการเชื่อมต่อคอนเทนเนอร์นักเทียบท่าบนโฮสต์หลายเครื่อง: http://goldmann.pl/blog/2014/01/21/connecting-docker-containers-on-multiple-hosts/


1
นั่นเป็นทางออกที่ดีมาก ฉันเจอมาแล้วเช่นกัน สิ่งที่ฉันกังวลคือบทความเพิ่งโพสต์เมื่อวานนี้และเรียกร้องให้มีแพตช์ Docker (เนื่องจากมีการโพสต์เมื่อเร็ว ๆ นี้ฉันจะรอสักครู่เพื่อดูว่าพวกเขารวมแพตช์นั้นเข้ากับ Docker หรือไม่)
lyschoening

นักเทียบท่าอยู่ในขั้นตอนการพัฒนาขั้นต้นอาจยังไม่ชัดเจนข้อกำหนดทั้งหมดและข้อกำหนดที่กำหนดไว้ยังไม่ได้นำไปใช้ทั้งหมด ดังนั้นการแก้ไขจึงจำเป็น
paweloque

2
นี่คือคำตอบที่ไม่ใช่ คัดลอกคำตอบจากบทความที่เชื่อมโยง นั่นคือมาตรฐาน SO
Bruno Bronosky

6

เป็นไปได้ที่จะเชื่อมโยงเครือข่ายย่อย Docker หลายเครือข่ายเข้าด้วยกันโดยใช้ Open vSwitch หรือ Tinc ฉันได้เตรียม Gists เพื่อแสดงวิธีการทำ:

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

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


คุณจะตรวจหาบริการได้อย่างไร? สมมติว่าฉันมี Redis ในเครื่องหนึ่งและแอปพลิเคชันไคลเอนต์ในเครื่องอื่นแอปพลิเคชันไคลเอนต์จะรับ IP ของบริการ Redis ได้อย่างไร
lyschoening

ในลักษณะเดียวกับที่คุณทำบนโฮสต์เดียว: ให้ IP / พอร์ตแก่ตัวเองสำหรับบริการที่เพิ่งเริ่มต้นหรือใช้ที่เก็บคีย์ / ค่า (เช่น etcd) หรือใช้ DNS ที่บริการสามารถสืบค้นได้ ฉันชอบใช้ DNS เนื่องจากบริการที่มีอยู่จำนวนมากสามารถใช้งานได้โดยไม่ต้องแก้ไข
บันทึกเมื่อ

1

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

ในทางกลับกันมี Flannel ของ CoreOS และ Opencontrail ของ Juniper สำหรับเดินสายคอนเทนเนอร์ข้ามโฮสต์


1

ดูเหมือนว่าฝูงนักเทียบท่า1.14ช่วยให้คุณ:

  • การกำหนดชื่อโฮสต์ให้กับคอนเทนเนอร์โดยใช้--hostnameแท็ก แต่ฉันไม่สามารถทำให้ใช้งานได้คอนเทนเนอร์ไม่สามารถ ping ซึ่งกันและกันโดยใช้ชื่อโฮสต์ที่กำหนด

  • กำหนดบริการให้กับเครื่องโดยใช้ --constraint 'node.hostname == <host>'

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