พ็อด Kubernetes รับที่อยู่ IP ได้อย่างไร

บันทึก. แปล: บทความนี้เขียนโดยวิศวกร SRE จาก LinkedIn ลงรายละเอียดเกี่ยวกับความมหัศจรรย์ภายในใน Kubernetes - ที่แม่นยำยิ่งขึ้นคือการทำงานร่วมกันของ CRI, CNI และ kube-apiserver - ซึ่งเกิดขึ้นเมื่อพ็อดถัดไปจำเป็นต้องกำหนดที่อยู่ IP

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

เมื่อฉันเริ่มทำงานกับ Kubernetes ครั้งแรก ฉันยังไม่ชัดเจนว่าพ็อดรับที่อยู่ IP ของตนได้อย่างไร แม้จะเข้าใจว่าส่วนประกอบแต่ละชิ้นทำงานอย่างไร แต่ก็ยังยากที่จะจินตนาการว่าส่วนประกอบต่างๆ ทำงานร่วมกันได้ ตัวอย่างเช่น ฉันรู้ว่าปลั๊กอิน CNI มีไว้เพื่ออะไร แต่ฉันไม่รู้ว่ามันเรียกว่าอะไรกันแน่ ดังนั้นฉันจึงตัดสินใจเขียนบทความนี้เพื่อแบ่งปันความรู้เกี่ยวกับส่วนประกอบเครือข่ายต่างๆ และวิธีการทำงานร่วมกันในคลัสเตอร์ Kubernetes ซึ่งช่วยให้แต่ละพ็อดได้รับที่อยู่ IP ที่เป็นเอกลักษณ์ของตัวเอง

มีหลายวิธีในการจัดระเบียบเครือข่ายใน Kubernetes เช่นเดียวกับที่มีตัวเลือกรันไทม์ที่แตกต่างกันสำหรับคอนเทนเนอร์ สิ่งพิมพ์นี้จะใช้ สักหลาด เพื่อจัดระเบียบเครือข่ายในคลัสเตอร์และเป็นสภาพแวดล้อมที่ปฏิบัติการได้ - ตู้คอนเทนเนอร์. ฉันยังตั้งสมมติฐานด้วยว่าคุณรู้ว่าการเชื่อมต่อเครือข่ายระหว่างคอนเทนเนอร์ทำงานอย่างไร ดังนั้นฉันจะพูดถึงมันสั้น ๆ เพื่อบริบทเท่านั้น

แนวคิดพื้นฐานบางประการ

คอนเทนเนอร์และเครือข่าย: ภาพรวมโดยย่อ

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

คอนเทนเนอร์บนโฮสต์เดียว

วิธีหนึ่งในการจัดการการสื่อสารผ่านที่อยู่ IP ระหว่างคอนเทนเนอร์ที่ทำงานบนโฮสต์เดียวกันคือการสร้างบริดจ์ Linux เพื่อจุดประสงค์นี้ อุปกรณ์เสมือนจะถูกสร้างขึ้นใน Kubernetes (และ Docker) veth (อีเธอร์เน็ตเสมือน). ปลายด้านหนึ่งของอุปกรณ์ veth เชื่อมต่อกับเนมสเปซเครือข่ายของคอนเทนเนอร์ โดยอีกด้านหนึ่งเชื่อมต่อกับ สะพานลินุกซ์ บนเครือข่ายโฮสต์

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

พ็อด Kubernetes รับที่อยู่ IP ได้อย่างไร

คอนเทนเนอร์บนโฮสต์ที่แตกต่างกัน

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

ในคลัสเตอร์ Kubernetes นั้น Flannel จะสร้างอุปกรณ์ vxlan และอัปเดตตารางเส้นทางบนแต่ละโหนดตามลำดับ แต่ละแพ็กเก็ตที่กำหนดไว้สำหรับคอนเทนเนอร์บนโฮสต์ที่แตกต่างกันจะผ่านอุปกรณ์ vxlan และถูกห่อหุ้มไว้ในแพ็กเก็ต UDP ที่ปลายทาง แพ็กเก็ตที่ซ้อนกันจะถูกแยกและส่งต่อไปยังพ็อดที่ต้องการ

พ็อด Kubernetes รับที่อยู่ IP ได้อย่างไร
หมายเหตุ: นี่เป็นเพียงวิธีหนึ่งในการจัดการการสื่อสารเครือข่ายระหว่างคอนเทนเนอร์

CRI คืออะไร?

CRI (อินเทอร์เฟซรันไทม์คอนเทนเนอร์) เป็นปลั๊กอินที่อนุญาตให้ kubelet ใช้สภาพแวดล้อมรันไทม์ของคอนเทนเนอร์ที่แตกต่างกัน CRI API ถูกสร้างขึ้นในรันไทม์ที่หลากหลาย ดังนั้นผู้ใช้สามารถเลือกรันไทม์ที่ต้องการได้

CNI คืออะไร?

โครงการซีเอ็นไอ คือ a ข้อกำหนด เพื่อจัดระเบียบโซลูชันเครือข่ายสากลสำหรับคอนเทนเนอร์ Linux นอกจากนี้ยังรวมถึง ปลั๊กอินรับผิดชอบฟังก์ชั่นต่างๆเมื่อตั้งค่าเครือข่ายพ็อด ปลั๊กอิน CNI เป็นไฟล์ปฏิบัติการที่เป็นไปตามข้อกำหนด (เราจะพูดถึงปลั๊กอินบางตัวด้านล่าง)

การจัดสรรเครือข่ายย่อยให้กับโหนดเพื่อกำหนดที่อยู่ IP ให้กับพ็อด

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

ตัวควบคุมโหนด IPAM

เมื่อ nodeipam ส่งผ่านเป็นพารามิเตอร์แฟล็ก --controllers kube-คอนโทรลเลอร์-ผู้จัดการโดยจะจัดสรรซับเน็ตแยกต่างหาก (podCIDR) ให้กับแต่ละโหนดจาก CIDR ของคลัสเตอร์ (เช่น ช่วงของที่อยู่ IP สำหรับเครือข่ายคลัสเตอร์) เนื่องจาก podCIDR เหล่านี้ไม่ทับซ้อนกัน จึงเป็นไปได้ที่แต่ละพ็อดจะได้รับการจัดสรรที่อยู่ IP ที่ไม่ซ้ำกัน

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

$ kubectl get no <nodeName> -o json | jq '.spec.podCIDR'
10.244.0.0/24

Kubelet, คอนเทนเนอร์รันไทม์ และปลั๊กอิน CNI: ทั้งหมดทำงานอย่างไร

การกำหนดเวลาพ็อดต่อโหนดเกี่ยวข้องกับขั้นตอนการเตรียมการมากมาย ในส่วนนี้ ผมจะเน้นเฉพาะสิ่งที่เกี่ยวข้องโดยตรงกับการตั้งค่าเครือข่ายพ็อดเท่านั้น

การกำหนดเวลาพ็อดให้กับโหนดใดโหนดหนึ่งจะทำให้เกิดห่วงโซ่ของเหตุการณ์ต่อไปนี้:

พ็อด Kubernetes รับที่อยู่ IP ได้อย่างไร

ข้อมูล: สถาปัตยกรรมของปลั๊กอิน Containerd CRI.

การโต้ตอบระหว่างคอนเทนเนอร์รันไทม์และปลั๊กอิน CNI

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

นอกจากนี้ผู้ให้บริการแต่ละรายยังมีตัวแทนของตนเอง มีการติดตั้งบนโหนด 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:

พ็อด Kubernetes รับที่อยู่ IP ได้อย่างไร

ดังที่คุณเห็นด้านบน kubelet เรียกปลั๊กอิน Containerd CRI เพื่อสร้างพ็อด ซึ่งจะเรียกปลั๊กอิน CNI เพื่อกำหนดค่าเครือข่ายของพ็อด ในการทำเช่นนั้น ปลั๊กอิน CNI ของผู้ให้บริการเครือข่ายจะเรียกปลั๊กอิน CNI หลักอื่นๆ เพื่อกำหนดค่าด้านต่างๆ ของเครือข่าย

ปฏิสัมพันธ์ระหว่างปลั๊กอิน CNI

มีปลั๊กอิน CNI มากมายที่มีหน้าที่ช่วยตั้งค่าการสื่อสารเครือข่ายระหว่างคอนเทนเนอร์บนโฮสต์ บทความนี้จะกล่าวถึงสามเรื่องต่อไปนี้

ปลั๊กอิน CNI สักหลาด

เมื่อใช้ Flannel เป็นผู้ให้บริการเครือข่าย คอมโพเนนต์ Containerd CRI จะเรียกใช้ ปลั๊กอิน CNI สักหลาดโดยใช้ไฟล์กำหนดค่า CNI /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 บนเครือข่ายโฮสต์ สะพานปลั๊กอิน CNI เชื่อมต่อคอนเทนเนอร์โฮสต์ทั้งหมดเข้ากับบริดจ์ Linux บนเครือข่ายโฮสต์

หลังจากตั้งค่าคู่ veth เสร็จแล้ว ปลั๊กอิน Bridge จะเรียกปลั๊กอิน IPAM CNI ของโฮสต์ภายในเครื่อง ประเภทปลั๊กอิน IPAM สามารถกำหนดค่าได้ในการกำหนดค่า CNI ที่ปลั๊กอิน CRI ใช้เพื่อเรียกปลั๊กอิน Flannel CNI

ปลั๊กอิน IPAM CNI ของโฮสต์ภายใน

เชื่อมโยงการโทร CNI ปลั๊กอิน IPAM โฮสต์ท้องถิ่น 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 ได้ดีขึ้น หากฉันผิดพลาดประการใดโปรดติดต่อฉันได้ที่ Twitter หรือตามที่อยู่ [ป้องกันอีเมล]. โปรดติดต่อเราหากคุณต้องการหารือเกี่ยวกับแง่มุมต่างๆ ของบทความนี้หรือสิ่งอื่นใด ฉันอยากจะคุยกับคุณ!

การอ้างอิง

ตู้คอนเทนเนอร์และเครือข่าย

แฟลนเนลทำงานอย่างไร?

CRI และ CNI

ปล.จากผู้แปล

อ่านเพิ่มเติมในบล็อกของเรา:

ที่มา: will.com

เพิ่มความคิดเห็น