หลักการทำงานของ Container Registry: Push/Pull อิมเมจโดยตรง
(labs.iximiuz.com)- 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 ก็เพียงพอ
- สำหรับไฟล์ขนาดใหญ่ วิธีอัปโหลดแบบ chunk ด้วย
- เมื่ออัปโหลดสำเร็จ จะได้รับการตอบกลับ
HTTP/2 201 Createdพร้อมLocationheader ที่ชี้ไปยังตำแหน่งของ 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 - ความสามารถนี้ไม่ได้ถูกเปิดให้ใช้ผ่าน
dockerCLI แต่เข้าถึงได้ผ่าน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>
- (1) ลบแท็กด้วย
- เนื่องจากรีจิสทรีเป็นที่เก็บแบบ 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 เท่านั้น
ยังไม่มีความคิดเห็น