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

โหนดคอนโทรลเพลนสามโหนด โดเมนความล้มเหลวเดียว

คุณรัน kubectl get nodes เห็นรายการคอนโทรลเพลนสามรายการ และบันทึกคลัสเตอร์ว่ามีความพร้อมใช้งานสูง จำนวนนั้นอธิบายความจุที่จัดสรรได้ ไม่ใช่การอยู่รอด ใน kubeadm ที่ไม่มี etcd ภายนอก ทุกโหนดคอนโทรลเพลนยังโฮสต์สมาชิกด้วย ดังนั้นสามโหนดจึงให้ผู้ลงคะแนนสามคนจริง ๆ การที่ผู้ลงคะแนนเหล่านั้นล้มเหลวอย่างอิสระหรือไม่เป็นคำถามแยกที่รายการโหนดตอบไม่ได้

VM สองเครื่องบนไฮเปอร์ไวเซอร์เดียว แร็คสองอันบนแหล่งจ่ายไฟเดียว ลิงก์อัปสองเส้นจาก ISP เดียว: แต่ละคู่เป็นโดเมนเดียวที่สวมชื่อโฮสต์สองชื่อ เขียนตำแหน่งติดตั้งและทำเครื่องหมายว่าผู้ลงคะแนนแต่ละคนใช้ร่วมกันอะไร — ไฮเปอร์ไวเซอร์ PDU สวิตช์บนสุดของแร็ค อาร์เรย์เก็บข้อมูล อุปกรณ์ NAT คอนเซนเทรเตอร์ VPN จากนั้นนำวัตถุที่ใช้ร่วมกันแต่ละชิ้นออกบนกระดาษและนับคะแนนที่เหลือใหม่ คลัสเตอร์ที่สูญเสียผู้ลงคะแนนสองคนเพราะโฮสต์เดียวล้มเหลวเป็นคลัสเตอร์ผู้ลงคะแนนคนเดียวมาตลอด ไม่มีใครเคยถามคำถามนั้นกับมัน

อะไรที่การแยกสองไซต์ทนได้และทนไม่ได้

เมื่อผู้ลงคะแนนสามคนถูกวางแบบสองและหนึ่งในสองไซต์ ฝ่ายที่ใหญ่กว่ายังคงรักษาควอรัมเมื่ออีกไซต์หายไป และฝ่ายผู้ลงคะแนนคนเดียวไม่เคย ความไม่สมดุลนั้นคือเลขคณิต ไม่ใช่การปรับแต่ง คลัสเตอร์ etcd ที่อิงเสียงข้างมากซึ่งกระจายพอดีบนสองไซต์อิสระจะล้มเหลวในการทดสอบ "สูญเสียไซต์ใดก็ได้และยังคงยืนยัน" เพราะทั้งสองฝ่ายต้องถือคะแนนเกินครึ่งในเวลาเดียวกัน

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

What disappearsVoters leftWrites still commit
Site B, holding voter 32 of 3Yes
Site A, holding voters 1 and 21 of 3No
One hypervisor carrying any two voters1 of 3No
The inter-site VPN only2 of 3 on one sideOnly on the majority side

ทำไมอุโมงค์จึงไม่เคยเพิ่มคะแนนเสียง

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

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

ตัดสินใจว่าคุณซื้อการหยุดชะงักแบบไหน

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

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

ควอรัมไม่เหมือนกับบริการ

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

จากนั้นยืนยันสมาชิกภาพที่คุณคิดว่าคุณมี เพราะไดอะแกรมคลาดเคลื่อน:

kubectl -n kube-system get pods -l component=etcd -o wide
kubectl get endpoints kube-apiserver -n default
etcdctl member list -w table

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

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

บทความที่เกี่ยวข้อง