เร่งความเร็วการปรับใช้ซอฟต์แวร์ - บทช่วยสอน Docker Swarm

เผยแพร่แล้ว: 2022-03-11

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

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

ดีโชคดีที่เราเป็นวันนี้

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

Docker Swarm คืออะไร?

โลโก้โหมด Docker Swarm

ก่อนที่เราจะดำดิ่งสู่การสร้างและปรับใช้กับกลุ่มแรกของเรา คุณควรมีความคิดว่า Docker Swarm คืออะไร Docker มีมานานหลายปีแล้ว และคนส่วนใหญ่ในปัจจุบันคิดว่ามันเป็นคอนเทนเนอร์รันไทม์ ในความเป็นจริง Docker ประกอบด้วยชิ้นส่วนต่างๆ มากมาย ซึ่งทั้งหมดทำงานร่วมกัน ตัวอย่างเช่น ส่วนรันไทม์ของคอนเทนเนอร์นั้นได้รับการจัดการโดยส่วนประกอบที่มีขนาดเล็กกว่าสองส่วนประกอบ เรียกว่า runC และ containerd เนื่องจาก Docker ได้พัฒนาและมอบคืนให้กับชุมชน พวกเขาพบว่าการสร้างส่วนประกอบที่มีขนาดเล็กลงเหล่านี้เป็นวิธีที่ดีที่สุดที่จะเติบโตและเพิ่มคุณสมบัติอย่างรวดเร็ว ด้วยเหตุนี้ เราจึงมี SwarmKit และโหมด Swarm ซึ่งสร้างไว้ใน Docker โดยตรง

Docker Swarm เป็นเครื่องมือจัดการคอนเทนเนอร์ ในระดับสูง ต้องใช้ Docker Engine หลายตัวที่ทำงานบนโฮสต์ที่ต่างกัน และให้คุณใช้ร่วมกันได้ การใช้งานนั้นง่าย: ประกาศแอปพลิเคชันของคุณเป็นกองบริการ และปล่อยให้ Docker จัดการส่วนที่เหลือ บริการสามารถเป็นอะไรก็ได้ตั้งแต่อินสแตนซ์ของแอปพลิเคชันไปจนถึงฐานข้อมูล หรือยูทิลิตี้ เช่น Redis หรือ RabbitMQ สิ่งนี้น่าจะฟังดูคุ้นเคยหากคุณเคยทำงานกับ docker-compose ในการพัฒนา เนื่องจากเป็นแนวคิดเดียวกันทุกประการ อันที่จริง การประกาศสแต็กเป็นเพียงไฟล์ docker-compose.yml ที่มีไวยากรณ์เวอร์ชัน 3.1 ซึ่งหมายความว่าคุณสามารถใช้การกำหนดค่าที่คล้ายคลึงกัน (และในหลายกรณีเหมือนกัน) สำหรับการพัฒนาและการปรับใช้เป็นกลุ่ม แต่ฉันกำลังก้าวไปข้างหน้าเล็กน้อยที่นี่ จะเกิดอะไรขึ้นเมื่อคุณมีอินสแตนซ์ของ Docker ในโหมด Swarm

โหมด Docker Swarm จะจัดกลุ่มบริการต่างๆ ออกเป็นกอง

อย่าตกจากแพ

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

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

ความงามของสิ่งนี้คือโหนดผู้จัดการสามารถหลุดออกมาได้เป็นระยะ ๆ โดยไม่กระทบต่อฉันทามติของฝูง หากการเปลี่ยนแปลงสถานะบรรลุถึงฉันทามติ เราทราบดีว่าการเปลี่ยนแปลงดังกล่าวมีอยู่ในโหนดผู้จัดการส่วนใหญ่ และจะคงอยู่ต่อไปแม้ว่าผู้นำปัจจุบันจะล้มเหลว

สมมติว่าเรามีโหนดผู้จัดการสามโหนดชื่อ A B และ C แน่นอนว่า A คือผู้นำที่กล้าหาญของเรา อยู่มาวันหนึ่งข้อผิดพลาดเครือข่ายชั่วคราวทำให้ A ออฟไลน์โดยปล่อยให้ B และ C อยู่คนเดียว ไม่ได้ยินจาก A มาเป็นเวลานาน (สองสามร้อยมิลลิวินาที) B และ C รอช่วงเวลาที่สร้างขึ้นแบบสุ่มก่อนที่จะเลือกตัวเองเพื่อเลือกตั้งและแจ้งให้อีกฝ่ายทราบ แน่นอน คนแรกที่ลงสมัครรับเลือกตั้ง ในกรณีนี้ ย่อมได้รับเลือก ในตัวอย่างนี้ B กลายเป็นผู้นำคนใหม่ และโควรัมได้รับการฟื้นฟู แต่แล้ว พล็อตเรื่องบิดเบี้ยว: จะเกิดอะไรขึ้นเมื่อ A กลับมาออนไลน์อีกครั้ง มันจะคิดว่ายังเป็นผู้นำอยู่ใช่หรือไม่? การเลือกตั้งแต่ละครั้งมีคำศัพท์ที่เกี่ยวข้องกัน ดังนั้น A ได้รับการเลือกตั้งในเทอมที่ 1 ทันทีที่ A กลับมาออนไลน์และเริ่มสั่ง B และ C ไปรอบๆ พวกเขาจะกรุณาแจ้งให้ทราบว่า B เป็นผู้นำของภาคเรียนที่ 2 และ เอจะก้าวลงจากตำแหน่ง

กระบวนการเดียวกันนี้ใช้งานได้ในระดับที่ใหญ่กว่ามากแน่นอน คุณสามารถมีโหนดตัวจัดการได้มากกว่าสามโหนด ฉันจะเพิ่มบันทึกย่ออีกฉบับหนึ่ง Swarm แต่ละตัวสามารถรับการสูญเสียของผู้จัดการได้ตามจำนวนที่กำหนดเท่านั้น โหนดผู้จัดการจำนวนมากสามารถสูญเสียผู้จัดการ (n-1)/2 โดยไม่สูญเสียองค์ประชุม นั่นหมายความว่าสำหรับกลุ่มผู้จัดการสามคน คุณอาจสูญเสียหนึ่งคน สำหรับห้าคน คุณอาจสูญเสียสองคน เป็นต้น เหตุผลเบื้องหลังของเรื่องนี้กลับมาที่แนวคิดเกี่ยวกับฉันทามติส่วนใหญ่ และเป็นสิ่งที่ควรคำนึงถึงเมื่อคุณเข้าสู่การผลิต

การจัดตารางงานและการกระทบยอด

จนถึงตอนนี้ เราได้พิสูจน์แล้วว่าผู้จัดการของเรามีปฏิสัมพันธ์ที่ดี ยอดเยี่ยม! แต่พวกเขากำลังทำอะไรอยู่? จำที่ฉันบอกว่าคุณปรับใช้กองบริการกับ Swarm ได้อย่างไร เมื่อคุณประกาศบริการของคุณ คุณจะให้ข้อมูลสำคัญแก่ Swarm ว่าคุณต้องการให้บริการของคุณทำงานอย่างไร ซึ่งรวมถึงพารามิเตอร์ต่างๆ เช่น จำนวนแบบจำลองที่คุณต้องการสำหรับแต่ละบริการ วิธีการแจกจ่ายแบบจำลอง การเรียกใช้แบบจำลองเหล่านี้บนบางโหนดเท่านั้น และอื่นๆ

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

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

การค้นหาบริการและการทำโหลดบาลานซ์

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

ดำเนินการต่อในตัวอย่าง Nginx เดียวกัน สมมติว่าเราบอก Docker ว่าคอนเทนเนอร์เหล่านั้นควรเปิดเผยพอร์ต 80 หากคุณชี้เบราว์เซอร์ของคุณไปที่โหนดที่รันคอนเทนเนอร์นั้นบนพอร์ต 80 คุณจะเห็นเนื้อหาของคอนเทนเนอร์นั้น ไม่แปลกใจเลย สิ่งที่น่าประหลาดใจก็คือ หากคุณส่งคำขอของคุณไปยังโหนดที่ไม่ได้ใช้งานคอนเทนเนอร์นั้น คุณจะยังคงเห็นเนื้อหาเดิมอยู่! เกิดอะไรขึ้นที่นี่?

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

ไม่หยุดที่การเชื่อมต่อภายนอก บริการที่ทำงานบนสแต็กเดียวกันมีเครือข่ายโอเวอร์เลย์ที่ช่วยให้สามารถสื่อสารกันได้ แทนที่จะใช้ที่อยู่ IP แบบฮาร์ดโค้ดในโค้ดของคุณ คุณสามารถใช้ชื่อของบริการเป็นชื่อโฮสต์ที่คุณต้องการเชื่อมต่อได้ ตัวอย่างเช่น หากแอปของคุณต้องการสื่อสารกับบริการ Redis ชื่อ "redis" ก็สามารถใช้ "redis" เป็นชื่อโฮสต์และ Swarm จะกำหนดเส้นทางคำขอไปยังคอนเทนเนอร์ที่เหมาะสม และเนื่องจากการทำงานนี้ทำงานได้อย่างราบรื่นในการพัฒนาด้วย docker-compose และในการผลิตด้วย Docker Swarm คุณจึงไม่ต้องกังวลเมื่อปรับใช้แอปของคุณ

ตาข่ายการกำหนดเส้นทางของโหมด Docker Swarm ร้องขอไปยังคอนเทนเนอร์ที่เหมาะสม แม้ว่าจะกำลังทำงานอยู่บนโหนดต่างๆ

การอัปเดตโรลลิ่งส

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

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

ความปลอดภัย

สุดท้าย แต่ไม่มีที่ไหนเลยแม้แต่น้อย Docker Swarm มาพร้อมกับคุณสมบัติด้านความปลอดภัยที่ยอดเยี่ยมตั้งแต่แกะกล่อง เมื่อโหนดเข้าร่วมกลุ่ม จะใช้โทเค็นที่ไม่เพียงแต่ยืนยันตัวเอง แต่ยังยืนยันว่ากำลังเข้าร่วมกลุ่มที่คุณคิดว่าใช่ นับจากนั้นเป็นต้นมา การสื่อสารระหว่างโหนดทั้งหมดจะเกิดขึ้นโดยใช้การเข้ารหัส TLS ร่วมกัน การเข้ารหัสนี้ได้รับการจัดเตรียมและจัดการโดยอัตโนมัติโดย Swarm คุณจึงไม่ต้องกังวลกับการต่ออายุใบรับรองและปัญหาด้านความปลอดภัยทั่วไปอื่นๆ และแน่นอน หากคุณต้องการบังคับการหมุนแป้น ก็มีคำสั่งสำหรับสิ่งนั้น

Docker Swarm ปลอดภัยตามค่าเริ่มต้น

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

ดำดิ่งสู่ฝูง

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

แอพตัวอย่าง Docker Swarm

ฉันได้สร้างแอพ Flask พื้นฐานมากเพื่อแสดงพลังและความสะดวกในการใช้ Docker Swarm เว็บแอปจะแสดงหน้าที่บอกคุณว่าคอนเทนเนอร์ใดให้บริการตามคำขอของคุณ จำนวนคำขอทั้งหมดที่ได้รับ และรหัสผ่านฐานข้อมูล "ความลับ" คืออะไร

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

ซอร์สโค้ดทั้งหมดมีอยู่ใน GitHub หากคุณต้องการ "ตรวจสอบ" ว่าเกิดอะไรขึ้น

เล่นกับนักเทียบท่า!

อย่าลังเลที่จะใช้เซิร์ฟเวอร์ของคุณเองในขณะที่คุณอ่านบทช่วยสอนนี้ แต่ฉันขอแนะนำให้ใช้ play-with-docker.com หากคุณต้องการเข้าร่วม เว็บไซต์นี้เป็นไซต์ที่ดำเนินการโดยนักพัฒนา Docker สองสามรายที่ให้คุณสร้างเครือข่ายได้หลายเครือข่าย โหนดที่ติดตั้ง Docker ไว้ล่วงหน้า พวกเขาจะปิดตัวลงหลังจากสี่ชั่วโมง แต่นั่นก็เพียงพอแล้วสำหรับตัวอย่างนี้!

การสร้างฝูง

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

ยังคงหมุนขึ้น? ไม่ต้องห่วง ฉันจะรอ ตกลง ตอนนี้เรากำลังจะสร้างโหนดผู้จัดการและผู้นำแรกของเรา ในอินสแตนซ์แรกของคุณ ให้เริ่มต้นกลุ่ม:

 docker swarm init --advertise-addr <node ip here>

แทนที่ <node_ip_here> ด้วยที่อยู่ IP ของโหนดของคุณ บน PWD ที่อยู่ IP จะแสดงที่ด้านบนสุด และหากคุณใช้ VPS ของคุณเอง คุณสามารถใช้ที่อยู่ IP ส่วนตัวของเซิร์ฟเวอร์ของคุณได้ตราบเท่าที่สามารถเข้าถึงได้จากโหนดอื่นๆ ในเครือข่ายของคุณ

ตอนนี้คุณมีฝูง! เป็นกลุ่มที่ค่อนข้างน่าเบื่อ เนื่องจากมีโหนดเพียงโหนดเดียว ไปข้างหน้าและเพิ่มโหนดอื่น ๆ คุณจะสังเกตเห็นว่าเมื่อคุณเรียกใช้ init จะแสดงข้อความยาวอธิบายวิธีใช้โทเค็นการเข้าร่วม เราจะไม่ใช้อันนั้นเพราะมันจะทำให้ผู้ปฏิบัติงานโหนดอื่น ๆ และเราต้องการให้พวกเขาเป็นผู้จัดการ มารับโทเค็นการเข้าร่วมสำหรับผู้จัดการโดยเรียกใช้สิ่งนี้บนโหนดแรก:

 docker swarm join-token manager

คัดลอกคำสั่งผลลัพธ์และรันบนโหนดที่สองและสามของคุณ ดูเถิด ฝูงสามโหนด! มาตรวจสอบว่าโหนดทั้งหมดของเรามีอยู่จริง คำสั่ง docker node ls จะแสดงรายการโหนดทั้งหมดในกลุ่มของเรา คุณควรเห็นสิ่งนี้:

 $ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS su1bgh1uxqsikf1129tjhg5r8 * node1 Ready Active Leader t1tgnq38wb0cehsry2pdku10h node3 Ready Active Reachable wxie5wf65akdug7sfr9uuleui node2 Ready Active Reachable

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

ใช้เวลาสักครู่เพื่อชื่นชมว่ามันง่ายเพียงใด แล้วมาปรับใช้แอปแรกของเรากัน!

จัดส่ง!

ทีมพัฒนาธุรกิจได้สัญญากับลูกค้าว่าแอปใหม่ของพวกเขาจะพร้อมใช้งานและพร้อมใช้งานภายในหนึ่งชั่วโมง! โดยทั่วไปฉันรู้ แต่ไม่ต้องกลัว เราไม่ต้องการเวลาเกือบขนาดนั้น เพราะมันถูกสร้างขึ้นโดยใช้ Docker! นักพัฒนาใจดีพอที่จะให้ยืมไฟล์ docker-compose :

 version: '3.1' services: web: image: lsapan/docker-swarm-demo-web command: gunicorn --bind 0.0.0.0:5000 wsgi:app deploy: replicas: 2 secrets: - db_password nginx: image: lsapan/docker-swarm-demo-nginx ports: - 8000:80 deploy: mode: global redis: image: redis deploy: replicas: 1 secrets: db_password: external: true

เราจะทำลายมันลงในช่วงเวลาหนึ่ง แต่ยังไม่มีเวลาสำหรับเรื่องนั้น มาปรับใช้กันเถอะ! ไปข้างหน้าและสร้างไฟล์บนโหนดแรกของคุณชื่อ docker docker-compose.yml compose.yml และเติมข้อมูลด้วยการกำหนดค่าด้านบน คุณสามารถทำได้อย่างง่ายดายด้วย echo "<pasted contents here>" > docker-compose.yml

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

 echo "supersecretpassword" | docker secret create db_password -

ยอดเยี่ยม! ตอนนี้ สิ่งที่เราต้องทำคือบอกให้ Docker ใช้การกำหนดค่าของเรา:

 docker stack deploy -c docker-compose.yml demo

เมื่อคุณเรียกใช้คำสั่งนี้ คุณจะเห็น Docker สร้างบริการสามอย่างที่เรากำหนด: web , nginx และ redis อย่างไรก็ตาม เนื่องจากเราตั้งชื่อว่า stack demo ของเรา บริการของเราจึงถูกตั้งชื่อว่า demo_web , demo_nginx และ demo_redis เราสามารถดูบริการที่ทำงานอยู่ของเราได้โดยใช้คำสั่ง docker service ls ซึ่งควรแสดงดังนี้:

 $ docker service ls ID NAME MODE REPLICAS IMAGE PORTS cih6u1t88vx7 demo_web replicated 2/2 lsapan/docker-swarm-demo-web:latest u0p1gd6tykvu demo_nginx global 3/3 lsapan/docker-swarm-demo-nginx:latest *:8000->80/ tcp wa1gz80ker2g demo_redis replicated 1/1 redis:latest

โว้ว! นักเทียบท่าได้ดาวน์โหลดอิมเมจของเราไปยังโหนดที่เหมาะสมและสร้างคอนเทนเนอร์สำหรับบริการของเรา หากแบบจำลองของคุณยังไม่เต็มความจุ โปรดรอสักครู่แล้วตรวจสอบอีกครั้ง นักเทียบท่ายังคงดาวน์โหลดภาพอยู่

การเห็นคือความเชื่อ

อย่าเชื่อคำพูดของฉัน (หรือคำพูดของ Docker) เลย มาลองเชื่อมต่อกับแอพของเรากัน การกำหนดค่าบริการของเราบอกให้ Docker แสดง NGINX บนพอร์ต 8000 หากคุณใช้ PWD ควรมีลิงก์สีน้ำเงินที่ด้านบนของหน้าที่ระบุว่า "8000" PWD ตรวจพบโดยอัตโนมัติจริง ๆ ว่าเรามีบริการที่ทำงานอยู่บนพอร์ตนั้น! คลิกแล้วระบบจะนำคุณไปยังโหนดที่เลือกบนพอร์ต 8000 หากคุณเปิดเซิร์ฟเวอร์ของคุณเอง ให้ไปที่ IP ของเซิร์ฟเวอร์ของคุณที่พอร์ต 8000

คุณจะได้รับการต้อนรับด้วยหน้าจอที่มีสไตล์สวยงามซึ่งให้ข้อมูลพื้นฐานแก่คุณ:

เนื้อหาที่แสดงโดย stack . ที่สร้างขึ้น

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

อย่าลังเลที่จะลองกดพอร์ต 8000 จากโหนดใด ๆ คุณจะยังคงถูกส่งไปยังแอปอย่างถูกต้อง

ไขปริศนาเวทย์มนต์

ณ จุดนี้ ทุกอย่างทำงานได้ และหวังว่าคุณจะพบว่ากระบวนการนี้ไม่เจ็บปวด! ลองมาดูไฟล์ docker-compose.yml นั้นให้ละเอียดยิ่งขึ้น และดูสิ่งที่เราบอกกับ Docker จริงๆ ในระดับสูง เราเห็นว่าเราได้กำหนดบริการสามอย่าง: web , nginx และ redis เช่นเดียวกับไฟล์เขียนทั่วไป เราได้จัดเตรียมอิมเมจให้ Docker ใช้สำหรับแต่ละบริการ รวมทั้งคำสั่งที่จะเรียกใช้ ในกรณีของ nginx เราได้ระบุด้วยว่าพอร์ต 8000 บนโฮสต์ควรแมปกับพอร์ต 80 ในคอนเทนเนอร์ ทั้งหมดนี้เป็นไวยากรณ์การเขียนมาตรฐานจนถึงตอนนี้

มีอะไรใหม่บ้างที่นี่คือคีย์การปรับใช้และความลับ คีย์เหล่านี้ถูกละเว้นโดย docker-compose ดังนั้นจะไม่ส่งผลต่อสภาพแวดล้อมการพัฒนาของคุณ แต่ถูกใช้โดย docker stack มาดูเว็บเซอร์วิสกัน ง่ายพอ เรากำลังบอก Docker ว่าเราต้องการเรียกใช้แอป Flask ของเราจำลองสองแบบจำลอง เรายังแจ้งให้ Docker ทราบว่าบริการบนเว็บต้องการรหัสลับ db_password นี่คือสิ่งที่ทำให้แน่ใจว่าคอนเทนเนอร์จะมีไฟล์ชื่อ /run/secrets/db_password ที่มีค่าของความลับ

เมื่อเลื่อนลงมาที่ Nginx เราจะเห็นว่าโหมดการปรับใช้ถูกตั้งค่าเป็น global ค่าเริ่มต้น (ซึ่งใช้โดยปริยายในเว็บ) ถูก replicated ซึ่งหมายความว่าเราจะระบุจำนวนแบบจำลองที่เราต้องการ เมื่อเราระบุ global มันจะบอก Docker ว่าทุกโหนดในกลุ่มควรเรียกใช้บริการเพียงหนึ่งอินสแตนซ์ เรียกใช้ docker service ls อีกครั้ง คุณจะสังเกตเห็นว่า nginx มีแบบจำลองสามแบบ หนึ่งชุดสำหรับแต่ละโหนดในกลุ่มของเรา

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

ใช้ Swarm วันต่อวัน

ขอแสดงความยินดีกับการปรับใช้แอปแรกของคุณกับ Docker Swarm! มาทบทวนคำสั่งทั่วไปสองสามคำสั่งที่คุณจะใช้กัน

ตรวจสอบฝูงของคุณ

ต้องการตรวจสอบบริการของคุณหรือไม่? ลอง docker service ls และ docker service ps <service name> แบบแรกจะแสดงภาพรวมระดับสูงของแต่ละบริการ และส่วนหลังจะให้ข้อมูลเกี่ยวกับคอนเทนเนอร์แต่ละอันที่รันสำหรับบริการที่ระบุ อันนั้นมีประโยชน์อย่างยิ่งเมื่อคุณต้องการดูว่าโหนดใดที่ใช้บริการอยู่

การอัปเดตโรลลิ่งส

แล้วเมื่อคุณพร้อมที่จะอัปเดตแอปล่ะ สิ่งที่ยอดเยี่ยมเกี่ยวกับการ docker stack deploy ก็คือมันจะนำการอัปเดตไปใช้กับสแต็กที่มีอยู่ด้วยเช่นกัน สมมติว่าคุณได้พุชอิมเมจ Docker ใหม่ไปยังที่เก็บของคุณ จริงๆ แล้ว คุณสามารถเรียกใช้คำสั่งปรับใช้เดียวกันกับที่คุณใช้ในครั้งแรก และฝูงของคุณจะดาวน์โหลดและปรับใช้อิมเมจใหม่

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

 docker service update \ --image lsapan/docker-swarm-demo-web:latest \ demo_web

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

 docker service update \ --image lsapan/docker-swarm-demo-web:latest \ --update-parallelism 1 --update-delay 30s \ demo_web

ซึ่งจะอัปเดตทีละคอนเทนเนอร์ โดยรอ 30 วินาทีระหว่างการอัปเดต

บริการปรับขนาดขึ้นหรือลง

การมีเว็บคอนเทนเนอร์สองอันนั้นยอดเยี่ยม แต่คุณรู้อะไรดีกว่ากัน? มีสิบ! บริการปรับขนาดขึ้นและลงในกลุ่มเป็นเรื่องง่ายเหมือน:

 docker service scale demo_web=10

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

การลบกองและบริการ

สแต็คและบริการของคุณได้รับการปรับใช้และปรับขนาด ยอดเยี่ยม! แต่ตอนนี้คุณต้องการทำให้ออฟไลน์ สามารถทำได้ด้วยคำสั่ง rm ที่เกี่ยวข้อง หากต้องการลบ demo stack ให้รันคำสั่ง:

 docker stack rm demo

หรือหากคุณต้องการเพียงแค่ลบบริการเดียว ให้ใช้:

 docker service rm demo_web

โหนดระบายน้ำ

จำได้ไหมว่าเมื่อเรารัน docker node ls ก่อนหน้านี้เพื่อตรวจสอบโหนดในกลุ่มของเรา? มันให้ข้อมูลมากมายเกี่ยวกับแต่ละโหนด รวมถึงความ พร้อมใช้งาน โดยค่าเริ่มต้น โหนดจะ ทำงาน ซึ่งหมายความว่าเป็นเกมที่ยุติธรรมในการรันคอนเทนเนอร์ อย่างไรก็ตาม มีบางครั้งที่คุณอาจต้องทำให้โหนดออฟไลน์ชั่วคราวเพื่อดำเนินการบำรุงรักษา แน่นอนว่าคุณสามารถปิดมันลงและฝูงสัตว์จะฟื้นตัว แต่เป็นการดีที่จะแจ้งให้ทราบเล็กน้อยแก่ Moby (ปลาวาฬ Docker)

นี่คือที่ที่โหนดระบายน้ำเข้ามา เมื่อคุณทำเครื่องหมายโหนดเป็น Drain แล้ว Docker Swarm จะมอบหมายคอนเทนเนอร์ที่ทำงานอยู่บนโหนดนั้นไปยังโหนดอื่น และจะไม่เริ่มคอนเทนเนอร์ใดๆ บนโหนดจนกว่าคุณจะเปลี่ยนความพร้อมใช้งานกลับเป็น Active

สมมติว่าเราต้องการระบาย node1 เราสามารถเรียกใช้:

 docker node update --availability drain node1

ง่าย! เมื่อคุณพร้อมที่จะกลับไปทำงาน:

 docker node update --availability active node1

ห่อ

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