• Container Registry ภายนอกดูเหมือนเรียบง่าย แต่หากต้องการดีบักปัญหาอย่างแท็กผิด, แพลตฟอร์มไม่ตรงกัน, เลเยอร์หาย, หรือการลบที่จริง ๆ ไม่สำเร็จ ก็จำเป็นต้องเข้าใจหลักการทำงานภายในอย่างแน่นอน
  • แกนหลักของรีจิสทรีคือ ที่เก็บ blob แบบ content-addressable ซึ่งเลเยอร์, ไฟล์คอนฟิก, และอาร์ติแฟกต์ทั้งหมดจะถูกเก็บโดยใช้ digest เป็นที่อยู่
  • การ push อิมเมจจะดำเนินตามลำดับ อัปโหลด blob ก่อนแล้วค่อยรวมด้วย manifest ส่วน pull จะเป็นโครงสร้างย้อนกลับ โดยดึง manifest ก่อนแล้วจึงดาวน์โหลด blob ตามลำดับ
  • การลบอิมเมจ ไม่สามารถลบออกได้หมดด้วยการ untag อย่างเดียว ต้องตรวจสอบก่อนว่าเลเยอร์นั้นถูกแชร์อยู่ใน manifest อื่นหรือไม่ แล้วจึงลบ blob โดยตรง
  • อิมเมจหลายแพลตฟอร์ม ถูกทำให้ใช้งานได้โดยคง API endpoint เดิมทั้งหมดไว้ และเพิ่มเพียงชั้นอ้อมหนึ่งชั้นในรูปของ image index (manifest list)

ภาพรวมของ Registry API

  • Container Registry สมัยใหม่ส่วนใหญ่รองรับ OCI Distribution Specification ซึ่งเป็นสเปกที่กำหนด API protocol มาตรฐานสำหรับการกระจายคอนเทนต์
  • Registry API นั้นกระชับและเข้าใจได้ไม่ยาก และสามารถจัดการได้โดยตรงด้วย curl เพียงอย่างเดียว

การอัปโหลดและดาวน์โหลด Blob

  • โดยเนื้อแท้แล้ว รีจิสทรีคือ ที่เก็บ blob แบบ content-addressable โดยจะ hash ไฟล์จากฝั่งโลคัลก่อน แล้วใช้งาน digest เป็นที่อยู่สำหรับอัปโหลด
  • วิธีอัปโหลดที่ง่ายที่สุดคือแบบ Monolithic PUT ซึ่งเป็นโครงสร้าง 2 ขั้นตอน: เริ่มเซสชันด้วย POST แล้วส่ง blob ด้วย PUT
    • สำหรับไฟล์ขนาดใหญ่ วิธีอัปโหลดแบบ chunk ด้วย POST + PATCH + PUT จะมีประสิทธิภาพมากกว่า แต่ถ้าเป็น blob ขนาดเล็ก Monolithic PUT ก็เพียงพอ
  • เมื่ออัปโหลดสำเร็จ จะได้รับการตอบกลับ HTTP/2 201 Created พร้อม Location header ที่ชี้ไปยังตำแหน่งของ blob ใหม่
  • การดาวน์โหลดสามารถทำได้โดยตรงทันทีหากรู้ digest ผ่าน GET /v2/<repo>/blobs/<digest>

การ Push อิมเมจ

  • ขั้นตอนการ push อิมเมจ: (1) อัปโหลด blob ของ rootfs layer แต่ละตัว → (2) อัปโหลด blob ของ image configuration → (3) push ไฟล์ manifest ที่รวม digest ทั้งหมดไว้ในเอกสาร JSON เดียว
  • manifest จะถูกอัปโหลดผ่าน endpoint PUT /v2/<repo>/manifests/<tag> และแท็กจะถูกสร้างขึ้นในขั้นตอนนี้
  • ไคลเอนต์จริง (เช่น docker push) มักอัปโหลด blob แบบขนาน แต่เพื่อทำความเข้าใจหลักการ ก็สามารถมองเป็นการประมวลผลแบบลำดับได้
  • ตัวอย่างโครงสร้างไดเรกทอรีของอิมเมจ: config.json, layer-1.tar.gz, layer-2.tar.gz, manifest.json

การดูรายการแท็ก

  • สามารถเรียกดู รายการแท็กทั้งหมด ของรีโพซิทอรีหนึ่งได้ผ่าน endpoint GET /v2/<repo>/tags/list
  • ความสามารถนี้ไม่ได้ถูกเปิดให้ใช้ผ่าน docker CLI แต่เข้าถึงได้ผ่าน curl หรือเครื่องมืออย่าง crane, regctl เท่านั้น
    • crane, regctl เป็นเพียงการห่อ endpoint เดียวกันนี้ไว้ด้วยคำสั่ง ls

การ Pull อิมเมจ

  • ขั้นตอน pull เป็นลำดับย้อนกลับของ push: (1) เรียกดู manifest ด้วย GET /v2/<repo>/manifests/<tag> → (2) ดาวน์โหลด blob ทั้งหมด ด้วย digest ที่ระบุไว้ใน manifest
  • manifest สมัยใหม่ไม่ได้ใช้แค่กับ rootfs layer และการตั้งค่าอิมเมจเท่านั้น แต่ยังถูกใช้เป็นที่เก็บอเนกประสงค์ที่อ้างอิง blob ของอาร์ติแฟกต์ใดก็ได้ เช่น Helm chart, SBOM, provenance attestation, น้ำหนักของ LLM เป็นต้น

การลบอิมเมจ

  • การลบอิมเมจไม่ใช่เรื่องง่าย และ การลบแท็ก (untag) เพียงอย่างเดียวไม่ได้ลบ manifest ออกจริง
  • ขั้นตอนการลบแบบสมบูรณ์:
    • (1) ลบแท็กด้วย DELETE /v2/<repo>/manifests/<tag>
    • (2) เรียกดู manifest ด้วย digest เพื่อตรวจสอบ blob ทั้งหมดที่อ้างอิงอยู่
    • (3) เลือกลบเฉพาะ blob ที่ไม่ได้ถูกแชร์โดย manifest อื่น
    • (4) ลบ manifest blob ด้วย DELETE /v2/<repo>/blobs/<manifest-digest>
  • เนื่องจากรีจิสทรีเป็นที่เก็บแบบ content-addressable rootfs layer เดียวกันจึงอาจถูกแชร์โดยหลายอิมเมจ และการลบจะส่งผลต่อ ทุกอิมเมจ ที่อ้างอิงเลเยอร์นั้น
  • อีกทางเลือกหนึ่งคือ ลบทุกแท็กออกก่อน แล้วพึ่งพาการตั้งค่า garbage collection ของรีจิสทรี แต่ในรีจิสทรีสาธารณะ ฟังก์ชันนี้ไม่ได้เปิดใช้งานเสมอไป

อิมเมจหลายแพลตฟอร์ม

  • อิมเมจหลายแพลตฟอร์มถูกทำให้ใช้งานได้ โดยไม่ต้องเปลี่ยนโครงสร้างของ Registry API — ไม่มีการเพิ่มหรือแก้ไข endpoint ใด ๆ และใช้ API เดิมได้ทั้งหมด
  • วิธีการประกอบ:
    • push เวอร์ชันแพลตฟอร์มเดี่ยวแต่ละตัว (เช่น amd64, arm64) พร้อม manifest ของตัวเอง โดยอิง digest ก่อน
    • จากนั้น push manifest ระดับบนที่เรียกว่า image index (manifest list) พร้อมแท็ก
  • เมื่อเรียก GET /v2/<repo>/manifests/<tag> อาจได้คืนมาเป็น single-platform manifest หรือ image index อย่างใดอย่างหนึ่ง และผู้เรียกต้องแยกความแตกต่างจาก content type ของเอกสารที่ได้รับ
  • สรุปแล้ว การรองรับหลายแพลตฟอร์มเป็นเพียงการเพิ่ม ชั้นอ้อมอีกหนึ่งชั้น และอีกหนึ่งขั้นตอนอัปโหลด/ดาวน์โหลดเอกสาร index เข้าไปในโครงสร้างเดิม

การปกป้อง Registry API

  • OCI Distribution Spec ไม่ได้กำหนดวิธีการยืนยันตัวตนไว้อย่างเข้มงวด แต่รีจิสทรีส่วนใหญ่ในโลกจริงใช้ HTTP Basic authentication
  • เพื่อป้องกันไม่ให้ข้อมูลรับรองถูกส่งเป็นข้อความล้วน จึงต้องให้บริการอยู่บน HTTPS เท่านั้น

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น