ปัญหาการทำความสะอาดอิมเมจคอนเทนเนอร์แบบ "อัจฉริยะ" และวิธีแก้ปัญหาใน WRF

ปัญหาการทำความสะอาดอิมเมจคอนเทนเนอร์แบบ "อัจฉริยะ" และวิธีแก้ปัญหาใน WRF

บทความนี้กล่าวถึงปัญหาการทำความสะอาดอิมเมจที่สะสมอยู่ในรีจิสทรีคอนเทนเนอร์ (Docker Registry และแอนะล็อก) ในความเป็นจริงของไปป์ไลน์ CI/CD สมัยใหม่สำหรับแอปพลิเคชันเนทิฟบนคลาวด์ที่ส่งไปยัง Kubernetes เกณฑ์หลักสำหรับความเกี่ยวข้องของรูปภาพและปัญหาที่เกิดขึ้นในการทำความสะอาดอัตโนมัติ ประหยัดพื้นที่ และตอบสนองความต้องการของทีม สุดท้ายนี้ เราจะบอกคุณว่าจะสามารถเอาชนะความยากลำบากเหล่านี้ได้อย่างไรโดยใช้ตัวอย่างของโครงการโอเพ่นซอร์สที่เฉพาะเจาะจง

การแนะนำ

จำนวนอิมเมจในคอนเทนเนอร์รีจีสทรีอาจเพิ่มขึ้นอย่างรวดเร็ว ใช้พื้นที่จัดเก็บมากขึ้น และทำให้ต้นทุนเพิ่มขึ้นอย่างมาก เพื่อควบคุม จำกัด หรือรักษาการเติบโตของพื้นที่ที่ยอมรับได้ในรีจิสทรี จะต้องยอมรับ:

  1. ใช้แท็กจำนวนคงที่สำหรับรูปภาพ
  2. ทำความสะอาดภาพในทางใดทางหนึ่ง


ข้อจำกัดแรกบางครั้งอาจยอมรับได้สำหรับทีมขนาดเล็ก หากนักพัฒนาซอฟต์แวร์มีแท็กถาวรเพียงพอ (latest, main, test, boris ฯลฯ ) รีจิสทรีจะไม่ขยายขนาดและคุณไม่ต้องคิดเรื่องการทำความสะอาดเลยเป็นเวลานาน ท้ายที่สุดแล้ว รูปภาพที่ไม่เกี่ยวข้องทั้งหมดจะถูกลบ และไม่มีงานเหลือสำหรับการทำความสะอาด (ทุกอย่างทำโดยคนเก็บขยะทั่วไป)

อย่างไรก็ตาม วิธีการนี้จำกัดการพัฒนาอย่างมาก และไม่ค่อยนำไปใช้กับโครงการ CI/CD สมัยใหม่ ส่วนสำคัญของการพัฒนาก็คือ อัตโนมัติซึ่งช่วยให้คุณทดสอบ ปรับใช้ และส่งมอบฟังก์ชันการทำงานใหม่ๆ ให้กับผู้ใช้ได้รวดเร็วยิ่งขึ้น ตัวอย่างเช่น ในทุกโปรเจ็กต์ของเรา ไปป์ไลน์ CI จะถูกสร้างขึ้นโดยอัตโนมัติพร้อมกับคอมมิตแต่ละรายการ ในนั้น รูปภาพจะถูกประกอบ ทดสอบ และเผยแพร่ไปยังวงจร Kubernetes ต่างๆ เพื่อการดีบักและการตรวจสอบที่เหลือ และหากทุกอย่างเรียบร้อยดี การเปลี่ยนแปลงจะไปถึงผู้ใช้ปลายทาง และนี่ไม่ใช่วิทยาศาสตร์จรวดอีกต่อไป แต่เกิดขึ้นทุกวันสำหรับหลายๆ คน ซึ่งน่าจะเป็นไปได้มากที่สุดสำหรับคุณ เนื่องจากคุณกำลังอ่านบทความนี้

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

แต่คุณจะทราบได้อย่างไรว่ารูปภาพนั้นมีความเกี่ยวข้องหรือไม่

เกณฑ์สำหรับความเกี่ยวข้องของภาพ

ในกรณีส่วนใหญ่ เกณฑ์หลักจะเป็นดังนี้:

1. ภาพแรก (ที่ชัดเจนที่สุดและสำคัญที่สุด) คือภาพนั้น ที่ใช้ใน Kubernetes ในปัจจุบัน. การลบอิมเมจเหล่านี้ออกอาจส่งผลให้เกิดต้นทุนการหยุดทำงานของการผลิตอย่างมีนัยสำคัญ (เช่น รูปภาพอาจจำเป็นสำหรับการจำลอง) หรือลบล้างความพยายามของทีมในการแก้ไขข้อบกพร่องในลูปใดๆ (ด้วยเหตุนี้เราจึงได้จัดทำรายการพิเศษขึ้นมาด้วย ผู้ส่งออกโพรมีธีอุสซึ่งติดตามการไม่มีอิมเมจดังกล่าวในคลัสเตอร์ Kubernetes ใดๆ)

2. ประการที่สอง (ไม่ชัดเจนแต่มีความสำคัญมากและเกี่ยวข้องกับการแสวงหาผลประโยชน์อีกครั้ง) - รูปภาพนั้น จำเป็นสำหรับการย้อนกลับในกรณีที่ตรวจพบปัญหาร้ายแรง ในเวอร์ชันปัจจุบัน ตัวอย่างเช่น ในกรณีของ Helm รูปภาพเหล่านี้คือรูปภาพที่ใช้ในเวอร์ชันที่บันทึกไว้ของการเผยแพร่ (อย่างไรก็ตาม ตามค่าเริ่มต้นใน Helm ขีดจำกัดอยู่ที่ 256 การแก้ไข แต่ก็ไม่น่าจะมีใครต้องการบันทึกจริงๆ เช่น เป็นจำนวนมาก?..) โดยเฉพาะอย่างยิ่งเราเก็บเวอร์ชันต่างๆ ไว้ เพื่อที่เราจะได้ใช้ในภายหลัง กล่าวคือ “ย้อนกลับ” ให้พวกเขาหากจำเป็น

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

4. ประการที่สี่ - รูปภาพนั้น สอดคล้องกับเวอร์ชันของแอปพลิเคชันของเรา, เช่น. เป็นผลิตภัณฑ์ขั้นสุดท้าย: v1.0.0, 20.04.01/XNUMX/XNUMX, เซียร่า ฯลฯ

หมายเหตุ: เกณฑ์ที่กำหนดไว้ในที่นี้จัดทำขึ้นจากประสบการณ์ในการโต้ตอบกับทีมพัฒนาหลายสิบทีมจากบริษัทต่างๆ อย่างไรก็ตาม แน่นอนว่า ขึ้นอยู่กับข้อมูลเฉพาะในกระบวนการพัฒนาและโครงสร้างพื้นฐานที่ใช้ (เช่น ไม่ได้ใช้ Kubernetes) เกณฑ์เหล่านี้อาจแตกต่างกัน

คุณสมบัติและโซลูชั่นที่มีอยู่

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

* ขึ้นอยู่กับการใช้งานรีจิสตรีคอนเทนเนอร์เฉพาะ เราพิจารณาความเป็นไปได้ของโซลูชันต่อไปนี้: Azure CR, Docker Hub, ECR, GCR, แพ็คเกจ GitHub, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io - ณ เดือนกันยายน 2020

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

ตัวอย่างเช่น เกณฑ์ที่สามที่เกี่ยวข้องกับความต้องการของนักพัฒนา สามารถแก้ไขได้โดยการจัดระเบียบกระบวนการภายในทีม: การตั้งชื่อรูปภาพเฉพาะ การรักษารายการอนุญาตพิเศษ และข้อตกลงภายใน แต่ท้ายที่สุดแล้ว มันยังต้องเป็นไปโดยอัตโนมัติ และหากความสามารถของโซลูชันสำเร็จรูปยังไม่เพียงพอ คุณต้องทำอะไรด้วยตนเอง

สถานการณ์ที่มีเกณฑ์สองข้อแรกนั้นคล้ายคลึงกัน: ไม่สามารถพอใจได้หากไม่ได้รับข้อมูลจากระบบภายนอก - ซึ่งเป็นที่ที่มีการปรับใช้แอปพลิเคชัน (ในกรณีของเราคือ Kubernetes)

ภาพประกอบของเวิร์กโฟลว์ใน Git

สมมติว่าคุณกำลังทำงานแบบนี้ใน Git:

ปัญหาการทำความสะอาดอิมเมจคอนเทนเนอร์แบบ "อัจฉริยะ" และวิธีแก้ปัญหาใน WRF

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

จะเกิดอะไรขึ้นหากนโยบายการล้างข้อมูลอนุญาตให้เก็บเฉพาะรูปภาพเท่านั้น (ไม่ถูกลบ) โดยระบุชื่อแท็ก?

ปัญหาการทำความสะอาดอิมเมจคอนเทนเนอร์แบบ "อัจฉริยะ" และวิธีแก้ปัญหาใน WRF

แน่นอนว่าสถานการณ์เช่นนี้จะไม่ทำให้ใครมีความสุข

จะเกิดอะไรขึ้นหากนโยบายไม่อนุญาตให้ลบรูปภาพ ตามช่วงเวลาที่กำหนด / จำนวนการคอมมิตครั้งล่าสุด?

ปัญหาการทำความสะอาดอิมเมจคอนเทนเนอร์แบบ "อัจฉริยะ" และวิธีแก้ปัญหาใน WRF

ผลลัพธ์ดีขึ้นมาก แต่ก็ยังห่างไกลจากอุดมคติ ท้ายที่สุดแล้ว เรายังมีนักพัฒนาที่ต้องการอิมเมจในรีจิสทรี (หรือแม้แต่ปรับใช้ใน K8) เพื่อแก้ไขจุดบกพร่อง...

เพื่อสรุปสถานการณ์ตลาดในปัจจุบัน: ฟังก์ชันที่มีอยู่ในการลงทะเบียนคอนเทนเนอร์ไม่มีความยืดหยุ่นเพียงพอในการทำความสะอาด และเหตุผลหลักก็คือ ไม่มีทางที่จะโต้ตอบกับโลกภายนอกได้. ปรากฎว่าทีมที่ต้องการความยืดหยุ่นดังกล่าวถูกบังคับให้ดำเนินการลบรูปภาพ "จากภายนอก" อย่างอิสระโดยใช้ Docker Registry API (หรือ API ดั้งเดิมของการใช้งานที่เกี่ยวข้อง)

อย่างไรก็ตาม เรากำลังมองหาโซลูชันสากลที่จะทำการล้างข้อมูลรูปภาพโดยอัตโนมัติสำหรับทีมต่างๆ โดยใช้รีจิสทรีที่แตกต่างกัน...

เส้นทางสู่การทำความสะอาดภาพแบบสากลของเรา

ความต้องการนี้มาจากไหน? ความจริงก็คือเราไม่ใช่กลุ่มนักพัฒนาที่แยกจากกัน แต่เป็นทีมที่ทำหน้าที่นักพัฒนาหลายคนในคราวเดียว ซึ่งช่วยแก้ไขปัญหา CI/CD อย่างครอบคลุม และเครื่องมือทางเทคนิคหลักสำหรับสิ่งนี้คือยูทิลิตี้ Open Source เวร. ลักษณะเฉพาะของมันคือไม่ได้ทำหน้าที่เดียว แต่มาพร้อมกับกระบวนการส่งมอบอย่างต่อเนื่องในทุกขั้นตอนตั้งแต่การประกอบไปจนถึงการใช้งาน

การเผยแพร่รูปภาพไปยังรีจิสทรี* (ทันทีหลังจากสร้างขึ้น) เป็นฟังก์ชันที่ชัดเจนของยูทิลิตี้ดังกล่าว และเนื่องจากรูปภาพถูกวางไว้ที่นั่นเพื่อจัดเก็บ ดังนั้น หากพื้นที่เก็บข้อมูลของคุณไม่จำกัด คุณจะต้องรับผิดชอบในการทำความสะอาดในภายหลัง เราจะหารือเพิ่มเติมเกี่ยวกับวิธีที่เราประสบความสำเร็จในเรื่องนี้และเป็นไปตามเกณฑ์ที่ระบุทั้งหมด

* แม้ว่ารีจิสทรีอาจแตกต่างกัน (Docker Registry, GitLab Container Registry, Harbor ฯลฯ) ผู้ใช้ก็ประสบปัญหาเดียวกัน โซลูชันสากลในกรณีของเราไม่ได้ขึ้นอยู่กับการใช้งานรีจิสทรีเพราะ ทำงานนอกรีจิสทรีและเสนอพฤติกรรมแบบเดียวกันสำหรับทุกคน

แม้ว่าเราจะใช้ werf เป็นตัวอย่างในการใช้งาน แต่เราหวังว่าแนวทางที่ใช้จะเป็นประโยชน์กับทีมอื่น ๆ ที่เผชิญกับปัญหาที่คล้ายกัน

ดังนั้นเราจึงยุ่ง ภายนอก การใช้กลไกในการทำความสะอาดอิมเมจ - แทนความสามารถที่มีอยู่แล้วในการลงทะเบียนสำหรับคอนเทนเนอร์ ขั้นตอนแรกคือการใช้ Docker Registry API เพื่อสร้างนโยบายดั้งเดิมที่เหมือนกันสำหรับจำนวนแท็กและเวลาที่สร้าง (ดังที่กล่าวไว้ข้างต้น) เพิ่มให้กับพวกเขา รายการที่อนุญาตตามรูปภาพที่ใช้ในโครงสร้างพื้นฐานที่ปรับใช้, เช่น. คูเบอร์เนเตส ประการหลัง การใช้ Kubernetes API เพื่อวนซ้ำทรัพยากรที่ปรับใช้ทั้งหมดและรับรายการค่าก็เพียงพอแล้ว image.

วิธีแก้ปัญหาเล็กๆ น้อยๆ นี้ช่วยแก้ปัญหาที่สำคัญที่สุดได้ (เกณฑ์ข้อ 1) แต่เป็นเพียงจุดเริ่มต้นของการเดินทางของเราเพื่อปรับปรุงกลไกการทำความสะอาด ขั้นตอนถัดไปและน่าสนใจกว่ามากคือการตัดสินใจ เชื่อมโยงภาพที่เผยแพร่กับประวัติ Git.

รูปแบบการแท็ก

ขั้นแรก เราเลือกวิธีการที่รูปภาพสุดท้ายควรจัดเก็บข้อมูลที่จำเป็นสำหรับการทำความสะอาด และสร้างกระบวนการในการแท็กแผนการ เมื่อเผยแพร่รูปภาพ ผู้ใช้เลือกตัวเลือกการแท็กเฉพาะ (git-branch, git-commit หรือ git-tag) และใช้ค่าที่สอดคล้องกัน ในระบบ CI ค่าเหล่านี้จะถูกตั้งค่าโดยอัตโนมัติตามตัวแปรสภาพแวดล้อม ในความเป็นจริง ภาพสุดท้ายเชื่อมโยงกับ Git ดั้งเดิมเฉพาะจัดเก็บข้อมูลที่จำเป็นสำหรับการทำความสะอาดไว้ในฉลาก

แนวทางนี้ส่งผลให้มีชุดนโยบายที่อนุญาตให้ใช้ Git เป็นแหล่งความจริงแหล่งเดียว:

  • เมื่อลบสาขา/แท็กใน Git รูปภาพที่เกี่ยวข้องในรีจิสทรีจะถูกลบโดยอัตโนมัติ
  • จำนวนรูปภาพที่เกี่ยวข้องกับแท็ก Git และคอมมิตสามารถควบคุมได้โดยจำนวนแท็กที่ใช้ในสคีมาที่เลือกและเวลาที่สร้างคอมมิตที่เกี่ยวข้อง

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

อัลกอริธึมใหม่

ทำไม ด้วยการแท็กตามเนื้อหา แต่ละแท็กสามารถตอบสนองคอมมิตหลายรายการใน Git เมื่อทำความสะอาดภาพ คุณจะไม่สามารถคาดเดาได้อีกต่อไป เท่านั้น จากการกระทำที่มีการเพิ่มแท็กใหม่ลงในรีจิสทรี

สำหรับอัลกอริธึมการทำความสะอาดใหม่ มีการตัดสินใจที่จะย้ายออกจากรูปแบบการแท็กและการสร้าง กระบวนการเมตาอิมเมจซึ่งแต่ละแห่งจะเก็บกลุ่มของ:

  • การกระทำที่ดำเนินการเผยแพร่ (ไม่สำคัญว่ารูปภาพจะถูกเพิ่ม เปลี่ยนแปลง หรือคงเหมือนเดิมในรีจิสตรีคอนเทนเนอร์)
  • และตัวระบุภายในของเราที่สอดคล้องกับภาพที่ประกอบ

กล่าวอีกนัยหนึ่งก็มีให้ การเชื่อมโยงแท็กที่เผยแพร่กับการคอมมิตใน Git.

การกำหนดค่าขั้นสุดท้ายและอัลกอริธึมทั่วไป

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

  • มีการอ้างอิงมากมาย เช่น แท็ก Git หรือสาขา Git ที่ใช้ระหว่างการสแกน
  • และขีดจำกัดการค้นหารูปภาพสำหรับการอ้างอิงแต่ละรายการจากชุด

เพื่อแสดงให้เห็น นี่คือลักษณะที่การกำหนดค่านโยบายเริ่มต้นเริ่มมีลักษณะดังนี้:

cleanup:
  keepPolicies:
  - references:
      tag: /.*/
      limit:
        last: 10
  - references:
      branch: /.*/
      limit:
        last: 10
        in: 168h
        operator: And
    imagesPerReference:
      last: 2
      in: 168h
      operator: And
  - references:  
      branch: /^(main|staging|production)$/
    imagesPerReference:
      last: 10

การกำหนดค่านี้มีนโยบาย XNUMX รายการที่สอดคล้องกับกฎต่อไปนี้:

  1. บันทึกรูปภาพสำหรับแท็ก Git 10 รายการล่าสุด (ตามวันที่สร้างแท็ก)
  2. บันทึกไม่เกิน 2 ภาพที่เผยแพร่ในสัปดาห์ที่ผ่านมาสำหรับไม่เกิน 10 กระทู้ที่มีกิจกรรมในสัปดาห์ที่ผ่านมา
  3. บันทึก 10 ภาพสำหรับสาขา main, staging и production.

อัลกอริธึมสุดท้ายจะมีขั้นตอนต่อไปนี้:

  • กำลังดึงรายการจากรีจิสตรีคอนเทนเนอร์
  • ไม่รวมรูปภาพที่ใช้ใน Kubernetes เนื่องจาก เราได้เลือกไว้ล่วงหน้าแล้วโดยการสำรวจ K8s API
  • สแกนประวัติ Git และยกเว้นรูปภาพตามนโยบายที่ระบุ
  • การลบภาพที่เหลือ

กลับมาที่ภาพประกอบของเรา นี่คือสิ่งที่เกิดขึ้นกับ werf:

ปัญหาการทำความสะอาดอิมเมจคอนเทนเนอร์แบบ "อัจฉริยะ" และวิธีแก้ปัญหาใน WRF

อย่างไรก็ตาม แม้ว่าคุณจะไม่ได้ใช้ wef แต่แนวทางที่คล้ายกันในการทำความสะอาดรูปภาพขั้นสูง - ในการใช้งานอย่างใดอย่างหนึ่ง (ตามแนวทางที่ต้องการในการแท็กรูปภาพ) - สามารถนำไปใช้กับระบบ/ยูทิลิตี้อื่น ๆ ได้ ในการดำเนินการนี้ ก็เพียงพอแล้วที่จะจดจำปัญหาที่เกิดขึ้นและค้นหาโอกาสเหล่านั้นในสแต็กของคุณที่ช่วยให้คุณสามารถบูรณาการโซลูชันได้อย่างราบรื่นที่สุด เราหวังว่าเส้นทางที่เราได้เดินทางจะช่วยให้คุณพิจารณากรณีเฉพาะของคุณด้วยรายละเอียดและความคิดใหม่ ๆ

ข้อสรุป

  • ไม่ช้าก็เร็ว ทีมส่วนใหญ่ประสบปัญหารีจิสทรีล้น
  • เมื่อค้นหาวิธีแก้ไข ขั้นแรกจำเป็นต้องกำหนดเกณฑ์สำหรับความเกี่ยวข้องของรูปภาพ
  • เครื่องมือที่นำเสนอโดยบริการรีจีสทรีคอนเทนเนอร์ยอดนิยมช่วยให้คุณสามารถจัดระเบียบการล้างข้อมูลแบบง่ายๆ ที่ไม่คำนึงถึง "โลกภายนอก": รูปภาพที่ใช้ใน Kubernetes และลักษณะเฉพาะของเวิร์กโฟลว์ของทีม
  • อัลกอริธึมที่ยืดหยุ่นและมีประสิทธิภาพต้องมีความเข้าใจในกระบวนการ CI/CD และไม่เพียงดำเนินการกับข้อมูลอิมเมจ Docker เท่านั้น

PS

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

ที่มา: will.com

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