บันทึก. แปล: บทความนี้เขียนโดยวิศวกร SRE จาก LinkedIn ลงรายละเอียดเกี่ยวกับความมหัศจรรย์ภายในใน Kubernetes - ที่แม่นยำยิ่งขึ้นคือการทำงานร่วมกันของ CRI, CNI และ kube-apiserver - ซึ่งเกิดขึ้นเมื่อพ็อดถัดไปจำเป็นต้องกำหนดที่อยู่ IP
หนึ่งในข้อกำหนดพื้นฐาน
เมื่อฉันเริ่มทำงานกับ Kubernetes ครั้งแรก ฉันยังไม่ชัดเจนว่าพ็อดรับที่อยู่ IP ของตนได้อย่างไร แม้จะเข้าใจว่าส่วนประกอบแต่ละชิ้นทำงานอย่างไร แต่ก็ยังยากที่จะจินตนาการว่าส่วนประกอบต่างๆ ทำงานร่วมกันได้ ตัวอย่างเช่น ฉันรู้ว่าปลั๊กอิน CNI มีไว้เพื่ออะไร แต่ฉันไม่รู้ว่ามันเรียกว่าอะไรกันแน่ ดังนั้นฉันจึงตัดสินใจเขียนบทความนี้เพื่อแบ่งปันความรู้เกี่ยวกับส่วนประกอบเครือข่ายต่างๆ และวิธีการทำงานร่วมกันในคลัสเตอร์ Kubernetes ซึ่งช่วยให้แต่ละพ็อดได้รับที่อยู่ IP ที่เป็นเอกลักษณ์ของตัวเอง
มีหลายวิธีในการจัดระเบียบเครือข่ายใน Kubernetes เช่นเดียวกับที่มีตัวเลือกรันไทม์ที่แตกต่างกันสำหรับคอนเทนเนอร์ สิ่งพิมพ์นี้จะใช้
แนวคิดพื้นฐานบางประการ
คอนเทนเนอร์และเครือข่าย: ภาพรวมโดยย่อ
มีสิ่งพิมพ์ดีๆ มากมายบนอินเทอร์เน็ตที่อธิบายว่าคอนเทนเนอร์สื่อสารกันอย่างไรผ่านเครือข่าย ดังนั้น ฉันจะให้ภาพรวมทั่วไปของแนวคิดพื้นฐานเท่านั้น และจำกัดตัวเองอยู่เพียงแนวทางเดียว ซึ่งเกี่ยวข้องกับการสร้างบริดจ์ Linux และแพ็คเกจห่อหุ้ม รายละเอียดจะถูกละเว้น เนื่องจากหัวข้อของเครือข่ายคอนเทนเนอร์สมควรได้รับบทความแยกต่างหาก ลิงก์ไปยังสิ่งพิมพ์ที่ให้ความรู้และเจาะลึกเป็นพิเศษจะมีระบุไว้ด้านล่าง
คอนเทนเนอร์บนโฮสต์เดียว
วิธีหนึ่งในการจัดการการสื่อสารผ่านที่อยู่ IP ระหว่างคอนเทนเนอร์ที่ทำงานบนโฮสต์เดียวกันคือการสร้างบริดจ์ Linux เพื่อจุดประสงค์นี้ อุปกรณ์เสมือนจะถูกสร้างขึ้นใน Kubernetes (และ Docker)
คอนเทนเนอร์ทั้งหมดบนโฮสต์เดียวกันมีปลายด้านหนึ่งเชื่อมต่อกับบริดจ์ซึ่งสามารถสื่อสารระหว่างกันผ่านที่อยู่ IP บริดจ์ Linux ยังมีที่อยู่ IP และทำหน้าที่เป็นเกตเวย์สำหรับการรับส่งข้อมูลขาออกจากพ็อดที่กำหนดให้กับโหนดอื่น
คอนเทนเนอร์บนโฮสต์ที่แตกต่างกัน
การห่อหุ้มแพ็กเก็ตเป็นวิธีการหนึ่งที่ช่วยให้คอนเทนเนอร์บนโหนดที่แตกต่างกันสามารถสื่อสารระหว่างกันได้โดยใช้ที่อยู่ IP ที่ Flannel เทคโนโลยีเป็นผู้รับผิดชอบต่อโอกาสนี้
ในคลัสเตอร์ Kubernetes นั้น Flannel จะสร้างอุปกรณ์ vxlan และอัปเดตตารางเส้นทางบนแต่ละโหนดตามลำดับ แต่ละแพ็กเก็ตที่กำหนดไว้สำหรับคอนเทนเนอร์บนโฮสต์ที่แตกต่างกันจะผ่านอุปกรณ์ vxlan และถูกห่อหุ้มไว้ในแพ็กเก็ต UDP ที่ปลายทาง แพ็กเก็ตที่ซ้อนกันจะถูกแยกและส่งต่อไปยังพ็อดที่ต้องการ
หมายเหตุ: นี่เป็นเพียงวิธีหนึ่งในการจัดการการสื่อสารเครือข่ายระหว่างคอนเทนเนอร์
CRI คืออะไร?
CNI คืออะไร?
การจัดสรรเครือข่ายย่อยให้กับโหนดเพื่อกำหนดที่อยู่ IP ให้กับพ็อด
เนื่องจากแต่ละพ็อดในคลัสเตอร์จะต้องมีที่อยู่ IP จึงเป็นสิ่งสำคัญที่จะต้องตรวจสอบให้แน่ใจว่าที่อยู่นี้ไม่ซ้ำกัน สิ่งนี้สามารถทำได้โดยการกำหนดเครือข่ายย่อยที่ไม่ซ้ำกันให้แต่ละโหนด จากนั้นพ็อดบนโหนดนั้นจะถูกกำหนดที่อยู่ IP
ตัวควบคุมโหนด IPAM
เมื่อ nodeipam
ส่งผ่านเป็นพารามิเตอร์แฟล็ก --controllers
โหนด Kubernetes ได้รับการกำหนด podCIDR เมื่อลงทะเบียนครั้งแรกกับคลัสเตอร์ หากต้องการเปลี่ยน podCIDR ของโหนด คุณต้องยกเลิกการลงทะเบียนโหนดเหล่านั้นแล้วลงทะเบียนใหม่อีกครั้ง โดยทำการเปลี่ยนแปลงการกำหนดค่าเลเยอร์ควบคุม Kubernetes อย่างเหมาะสมในระหว่างนั้น คุณสามารถแสดง podCIDR ของโหนดได้โดยใช้คำสั่งต่อไปนี้:
$ kubectl get no <nodeName> -o json | jq '.spec.podCIDR'
10.244.0.0/24
Kubelet, คอนเทนเนอร์รันไทม์ และปลั๊กอิน CNI: ทั้งหมดทำงานอย่างไร
การกำหนดเวลาพ็อดต่อโหนดเกี่ยวข้องกับขั้นตอนการเตรียมการมากมาย ในส่วนนี้ ผมจะเน้นเฉพาะสิ่งที่เกี่ยวข้องโดยตรงกับการตั้งค่าเครือข่ายพ็อดเท่านั้น
การกำหนดเวลาพ็อดให้กับโหนดใดโหนดหนึ่งจะทำให้เกิดห่วงโซ่ของเหตุการณ์ต่อไปนี้:
ข้อมูล:
การโต้ตอบระหว่างคอนเทนเนอร์รันไทม์และปลั๊กอิน CNI
ผู้ให้บริการเครือข่ายแต่ละรายมีปลั๊กอิน CNI ของตัวเอง รันไทม์ของคอนเทนเนอร์จะเรียกใช้เพื่อกำหนดค่าเครือข่ายสำหรับพ็อดเมื่อเริ่มต้นระบบ ในกรณีของคอนเทนเนอร์ ปลั๊กอิน CNI จะถูกเปิดใช้งานโดยปลั๊กอิน
นอกจากนี้ผู้ให้บริการแต่ละรายยังมีตัวแทนของตนเอง มีการติดตั้งบนโหนด Kubernetes ทั้งหมด และรับผิดชอบการกำหนดค่าเครือข่ายของพ็อด เอเจนต์นี้จะรวมอยู่ในการกำหนดค่า CNI หรือสร้างอย่างอิสระบนโหนด การกำหนดค่าช่วยให้ปลั๊กอิน CRI ตั้งค่าปลั๊กอิน CNI ที่จะเรียกใช้
ตำแหน่งของการกำหนดค่า CNI สามารถปรับแต่งได้ โดยค่าเริ่มต้นจะอยู่ใน /etc/cni/net.d/<config-file>
. ผู้ดูแลระบบคลัสเตอร์ยังรับผิดชอบในการติดตั้งปลั๊กอิน CNI บนแต่ละโหนดคลัสเตอร์ ตำแหน่งของพวกเขายังสามารถปรับแต่งได้ ไดเรกทอรีเริ่มต้น - /opt/cni/bin
.
เมื่อใช้คอนเทนเนอร์ คุณสามารถตั้งค่าเส้นทางสำหรับการกำหนดค่าปลั๊กอินและไบนารีได้ในส่วนนี้ [plugins.«io.containerd.grpc.v1.cri».cni]
в
เนื่องจากเราใช้ Flannel เป็นผู้ให้บริการเครือข่าย เรามาพูดคุยกันเล็กน้อยเกี่ยวกับการตั้งค่า:
- โดยปกติแล้ว Flanneld (Flannel's daemon) จะถูกติดตั้งในคลัสเตอร์เหมือนกับ DaemonSet ด้วย
install-cni
ในขณะที่คอนเทนเนอร์เริ่มต้น . Install-cni
สร้างไฟล์การกำหนดค่า CNI (/etc/cni/net.d/10-flannel.conflist
) ในแต่ละโหนด- Flanneld สร้างอุปกรณ์ vxlan ดึงข้อมูลเมตาของเครือข่ายจากเซิร์ฟเวอร์ API และตรวจสอบการอัปเดตพ็อด เมื่อสร้างขึ้น มันจะกระจายเส้นทางไปยังพ็อดทั้งหมดทั่วทั้งคลัสเตอร์
- เส้นทางเหล่านี้ช่วยให้พ็อดสามารถสื่อสารกันผ่านที่อยู่ IP
หากต้องการข้อมูลโดยละเอียดเพิ่มเติมเกี่ยวกับงานของ Flannel ฉันขอแนะนำให้ใช้ลิงก์ท้ายบทความ
นี่คือแผนภาพของการโต้ตอบระหว่างปลั๊กอิน Containerd CRI และปลั๊กอิน CNI:
ดังที่คุณเห็นด้านบน kubelet เรียกปลั๊กอิน Containerd CRI เพื่อสร้างพ็อด ซึ่งจะเรียกปลั๊กอิน CNI เพื่อกำหนดค่าเครือข่ายของพ็อด ในการทำเช่นนั้น ปลั๊กอิน CNI ของผู้ให้บริการเครือข่ายจะเรียกปลั๊กอิน CNI หลักอื่นๆ เพื่อกำหนดค่าด้านต่างๆ ของเครือข่าย
ปฏิสัมพันธ์ระหว่างปลั๊กอิน CNI
มีปลั๊กอิน CNI มากมายที่มีหน้าที่ช่วยตั้งค่าการสื่อสารเครือข่ายระหว่างคอนเทนเนอร์บนโฮสต์ บทความนี้จะกล่าวถึงสามเรื่องต่อไปนี้
ปลั๊กอิน CNI สักหลาด
เมื่อใช้ Flannel เป็นผู้ให้บริการเครือข่าย คอมโพเนนต์ Containerd CRI จะเรียกใช้ /etc/cni/net.d/10-flannel.conflist
.
$ cat /etc/cni/net.d/10-flannel.conflist
{
"name": "cni0",
"plugins": [
{
"type": "flannel",
"delegate": {
"ipMasq": false,
"hairpinMode": true,
"isDefaultGateway": true
}
}
]
}
ปลั๊กอิน Flannel CNI ทำงานร่วมกับ Flanneld ในระหว่างการเริ่มต้น Flanneld จะดึงข้อมูล podCIDR และรายละเอียดที่เกี่ยวข้องกับเครือข่ายอื่นๆ จากเซิร์ฟเวอร์ API และบันทึกลงในไฟล์ /run/flannel/subnet.env
.
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false
ปลั๊กอิน Flannel CNI ใช้ข้อมูลจาก /run/flannel/subnet.env
เพื่อกำหนดค่าและเรียกใช้ปลั๊กอินบริดจ์ CNI
สะพานปลั๊กอิน CNI
ปลั๊กอินนี้ถูกเรียกโดยมีการกำหนดค่าต่อไปนี้:
{
"name": "cni0",
"type": "bridge",
"mtu": 1450,
"ipMasq": false,
"isGateway": true,
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24"
}
}
เมื่อเรียกครั้งแรกจะสร้างบริดจ์ลินุกซ์ด้วย «name»: «cni0»
ซึ่งระบุไว้ในการกำหนดค่า จากนั้นจะมีการสร้างคู่ veth สำหรับแต่ละพ็อด ปลายด้านหนึ่งเชื่อมต่อกับเนมสเปซเครือข่ายของคอนเทนเนอร์ ส่วนอีกด้านหนึ่งจะรวมอยู่ในบริดจ์ Linux บนเครือข่ายโฮสต์
หลังจากตั้งค่าคู่ veth เสร็จแล้ว ปลั๊กอิน Bridge จะเรียกปลั๊กอิน IPAM CNI ของโฮสต์ภายในเครื่อง ประเภทปลั๊กอิน IPAM สามารถกำหนดค่าได้ในการกำหนดค่า CNI ที่ปลั๊กอิน CRI ใช้เพื่อเรียกปลั๊กอิน Flannel CNI
ปลั๊กอิน IPAM CNI ของโฮสต์ภายใน
เชื่อมโยงการโทร CNI
{
"name": "cni0",
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24",
"dataDir": "/var/lib/cni/networks"
}
}
ปลั๊กอิน IPAM ภายในโฮสต์ (IP Address Mการจัดการ - การจัดการที่อยู่ IP) ส่งคืนที่อยู่ IP สำหรับคอนเทนเนอร์จากซับเน็ตและจัดเก็บ IP ที่จัดสรรไว้บนโฮสต์ในไดเร็กทอรีที่ระบุในส่วน dataDir
- /var/lib/cni/networks/<network-name=cni0>/<ip>
. ไฟล์นี้มี ID ของคอนเทนเนอร์ที่กำหนดที่อยู่ IP นี้
เมื่อเรียกปลั๊กอิน IPAM ภายในโฮสต์ จะส่งกลับข้อมูลต่อไปนี้:
{
"ip4": {
"ip": "10.244.4.2",
"gateway": "10.244.4.3"
},
"dns": {}
}
สรุป
Kube-controller-manager กำหนด podCIDR ให้กับแต่ละโหนด พ็อดของแต่ละโหนดได้รับที่อยู่ IP จากพื้นที่ที่อยู่ในช่วง podCIDR ที่จัดสรร เนื่องจาก podCIDR ของโหนดไม่ทับซ้อนกัน พ็อดทั้งหมดจึงได้รับที่อยู่ IP ที่ไม่ซ้ำกัน
ผู้ดูแลระบบคลัสเตอร์ Kubernetes กำหนดค่าและติดตั้ง kubelet, รันไทม์คอนเทนเนอร์, เอเจนต์ผู้ให้บริการเครือข่าย และคัดลอกปลั๊กอิน CNI ไปยังแต่ละโหนด ในระหว่างการเริ่มต้น ตัวแทนผู้ให้บริการเครือข่ายจะสร้างการกำหนดค่า CNI เมื่อมีการกำหนดเวลาพ็อดให้กับโหนด kubelet จะเรียกปลั๊กอิน CRI เพื่อสร้างโหนด ถัดไป หากใช้คอนเทนเนอร์ ปลั๊กอิน Containerd CRI จะเรียกปลั๊กอิน CNI ที่ระบุในการกำหนดค่า CNI เพื่อกำหนดค่าเครือข่ายของพ็อด เป็นผลให้พ็อดได้รับที่อยู่ IP
ฉันใช้เวลาพอสมควรในการทำความเข้าใจรายละเอียดปลีกย่อยและความแตกต่างของปฏิสัมพันธ์เหล่านี้ทั้งหมด ฉันหวังว่าประสบการณ์นี้จะช่วยให้คุณเข้าใจวิธีการทำงานของ Kubernetes ได้ดีขึ้น หากฉันผิดพลาดประการใดโปรดติดต่อฉันได้ที่
การอ้างอิง
ตู้คอนเทนเนอร์และเครือข่าย
แฟลนเนลทำงานอย่างไร?
CRI และ CNI
ปล.จากผู้แปล
อ่านเพิ่มเติมในบล็อกของเรา:
- «
Calico สำหรับการสร้างเครือข่ายใน Kubernetes: บทนำและประสบการณ์เล็กน้อย "; - "ภาพประกอบคู่มือการสร้างเครือข่ายใน Kubernetes":
ส่วนที่ 1 และ 2 (โมเดลเครือข่าย, เครือข่ายโอเวอร์เลย์) ,ส่วนที่ 3 (บริการและการประมวลผลการรับส่งข้อมูล) ; - «
Container Networking Interface (CNI) - อินเทอร์เฟซเครือข่ายและมาตรฐานสำหรับคอนเทนเนอร์ Linux '
ที่มา: will.com