เรียนรู้ว่า Solomon Hykes และ Docker ทำให้คอนเทนเนอร์เป็นมาตรฐานอย่างไร โดยใช้ image, Dockerfile และรีจิสทรีเป็นวิธีมาตรฐานในการแพ็กและปรับใช้แอปสมัยใหม่

Solomon Hykes เป็นวิศวกรที่ช่วยเปลี่ยนแนวคิดที่มีมานาน—การแยกสภาพแวดล้อมของซอฟต์แวร์เพื่อให้รันเหมือนกันทุกที่—ให้กลายเป็นสิ่งที่ทีมสามารถใช้งานได้จริงในแต่ละวัน ในปี 2013 โครงการที่เขานำเสนอแก่โลกถูกเปิดตัวในชื่อ Docker และมันเปลี่ยนวิธีที่บริษัทส่งมอบแอปอย่างรวดเร็ว
ในตอนนั้น ปัญหาช่างเรียบง่ายและคุ้นเคย: แอปรันได้บนแล็ปท็อปของนักพัฒนา แต่พฤติกรรมแตกต่างบนเครื่องของเพื่อนร่วมทีม แล้วก็พังอีกครั้งในสเตจหรือโปรดักชัน ปัญหา “สภาพแวดล้อมไม่สอดคล้องกัน” ไม่ได้เป็นแค่เรื่องน่ารำคาญ—มันชะลอการปล่อย, ทำให้การค้นหาข้อผิดพลาดทำได้ยาก, และก่อให้เกิดการส่งต่อความรับผิดชอบระหว่างทีมพัฒนาและปฏิบัติการอย่างไม่รู้จบ
Docker ให้วิธีที่ทำซ้ำได้แก่ทีมในการบรรจุแอปพร้อมกับไลบรารีที่มันคาดหวัง—เพื่อให้แอปรันแบบเดียวกันบนแล็ปท็อป เซิร์ฟเวอร์ทดสอบ หรือบนคลาวด์
นั่นคือเหตุผลที่ผู้คนพูดว่าคอนเทนเนอร์กลายเป็น “หน่วยการแพ็กเกจและปรับใช้เริ่มต้น” กล่าวแบบง่าย ๆ:
แทนที่จะปรับใช้ “ไฟล์ zip พร้อมเพจ wiki ของขั้นตอนการตั้งค่า” หลายทีมปรับใช้ image ที่รวมสิ่งที่แอปต้องการไว้แล้ว ผลคือความประหลาดใจน้อยลงและการปล่อยที่รวดเร็วขึ้นและคาดเดาได้มากขึ้น
บทความนี้ผสมผสาน ประวัติศาสตร์ กับ แนวคิดเชิงปฏิบัติ คุณจะได้รู้ว่า Solomon Hykes คือใครในบริบทนี้, Docker นำเสนออะไรในเวลาที่เหมาะสม, และกลไกพื้นฐาน—โดยไม่สมมติว่าคุณมีความรู้เชิงโครงสร้างพื้นฐานลึก
คุณจะเห็นด้วยว่าคอนเทนเนอร์ตั้งอยู่ตรงไหนในวันนี้: มันเชื่อมต่อกับเวิร์กโฟลว์ CI/CD และ DevOps อย่างไร, ทำไมเครื่องมือจัดการออร์เคสเตรชันเช่น Kubernetes จึงกลายเป็นสิ่งสำคัญทีหลัง, และสิ่งที่คอนเทนเนอร์ ไม่ได้ แก้ให้โดยอัตโนมัติ (โดยเฉพาะเรื่องความปลอดภัยและความน่าเชื่อถือ)
เมื่อจบคุณควรอธิบายได้—อย่างชัดเจนและมั่นใจ—ว่าทำไม “ส่งเป็นคอนเทนเนอร์” ถึงกลายเป็นสมมติฐานเริ่มต้นสำหรับการปรับใช้แอปสมัยใหม่
ก่อนที่คอนเทนเนอร์จะเป็นที่นิยม การย้ายแอปจากแล็ปท็อปของนักพัฒนาไปยังเซิร์ฟเวอร์มักเจ็บปวดกว่าการเขียนแอปเสียอีก ทีมไม่ได้ขาดความสามารถ—แต่ขาดวิธีที่เชื่อถือได้ในการย้าย “สิ่งที่ใช้งานได้” ข้ามสภาพแวดล้อม
นักพัฒนาอาจรันแอปได้สมบูรณ์บนคอมพิวเตอร์ของตัวเอง แล้วเห็นมันล้มเหลวในสเตจหรือโปรดักชัน ไม่ใช่เพราะโค้ดเปลี่ยน แต่เพราะสภาพแวดล้อมเปลี่ยน เวอร์ชันระบบปฏิบัติการที่ต่างกัน ไลบรารีที่หายไป ไฟล์คอนฟิกที่ต่างกันเล็กน้อย หรือฐานข้อมูลที่ตั้งค่าเริ่มต้นต่างกัน—all เหล่านี้ทำให้บิลด์เดียวกันพังได้
หลายโปรเจ็กต์พึ่งพาคำแนะนำการตั้งค่าที่ยาวและเปราะบาง:
ถึงจะเขียนอย่างรัดกุม คู่มือเหล่านี้ก็ล้าสมัยเร็ว เพื่อนร่วมทีมคนหนึ่งอัปเกรด dependency อาจทำให้การเริ่มต้นของคนอื่นพังได้
ยิ่งไปกว่านั้น สองแอปบนเซิร์ฟเวอร์เดียวกันอาจต้องการเวอร์ชัน runtime หรือไลบรารีที่ไม่เข้ากัน บังคับให้ทีมต้องหาทางแก้ชั่วคราวหรือใช้เครื่องแยกกัน
“การแพ็กเกจ” มักหมายถึงการผลิตไฟล์ ZIP, tarball, หรือโปรแกรมติดตั้ง ส่วน “การปรับใช้” หมายถึงสคริปต์และขั้นตอนบนเซิร์ฟเวอร์: จัดหาเครื่อง, ตั้งค่า, คัดลอกไฟล์, รีสตาร์ทบริการ, และหวังว่าไม่มีสิ่งอื่นในเซิร์ฟเวอร์ได้รับผลกระทบ
ทั้งสองเรื่องนี้ไม่ค่อยตรงกัน แพ็กเกจไม่ได้อธิบายสภาพแวดล้อมที่ต้องการทั้งหมด และกระบวนการปรับใช้พึ่งพาเซิร์ฟเวอร์เป้าหมายที่ถูกเตรียมไว้ "พอดี"
ที่ทีมต้องการคือหน่วยพกพาเดียวที่สามารถพาไปร่วมกับ dependency ของมันและรันได้สม่ำเสมอบนแล็ปท็อป เซิร์ฟเวอร์ทดสอบ และโปรดักชัน ความกดดันนี้—การตั้งค่าที่ทำซ้ำได้, ความขัดแย้งน้อยลง, และการปรับใช้ที่คาดเดาได้—วางพื้นให้คอนเทนเนอร์กลายเป็นวิธีเริ่มต้นในการส่งแอป
Docker ไม่ได้เริ่มจากแผนใหญ่เพื่อ “เปลี่ยนซอฟต์แวร์ไปตลอดกาล” มันเติบโตจากงานวิศวกรรมเชิงปฏิบัติที่ Solomon Hykes นำขณะสร้างแพลตฟอร์มเป็นบริการ ทีมต้องการวิธีที่ทำซ้ำได้ในการแพ็กและรันแอปข้ามเครื่องต่าง ๆ โดยไม่มีปัญหา "มันใช้ได้บนเครื่องฉัน" แบบเดิม ๆ
ก่อน Docker จะเป็นชื่อที่คุ้นเคย ความต้องการพื้นฐานนั้นชัดเจน: ส่งแอปพร้อม dependency, รันได้เชื่อถือได้, และทำซ้ำสำหรับลูกค้าจำนวนมากได้
โครงการที่กลายเป็น Docker เกิดขึ้นเป็นทางแก้ภายใน—สิ่งที่ทำให้การปรับใช้คาดเดาได้และสภาพแวดล้อมสอดคล้องกัน เมื่อตระหนักว่ากลไกการแพ็กและรันมีประโยชน์กว้างกว่าผลิตภัณฑ์ของตนเอง ทีมจึงปล่อยให้สาธารณะใช้งาน
การเปิดตัวนั้นสำคัญเพราะมันเปลี่ยนเทคนิคการปรับใช้ภายในให้เป็นชุดเครื่องมือที่อุตสาหกรรมสามารถนำไปใช้ ปรับปรุง และมาตรฐานร่วมกันได้
มักจะง่ายที่จะผสมสองสิ่งนี้เข้าด้วยกัน แต่จริง ๆ แล้วต่างกัน:
คอนเทนเนอร์มีอยู่ในรูปแบบต่าง ๆ ก่อน Docker สิ่งที่เปลี่ยนไปคือ Docker แพ็กเวิร์กโฟลว์ให้เป็นชุดคำสั่งและข้อปฏิบัติที่เป็นมิตรกับนักพัฒนา—สร้าง image, รัน container, แชร์ให้ผู้อื่น
ไม่กี่ก้าวที่เป็นที่รู้จักช่วยผลัก Docker จาก "น่าสนใจ" สู่ "เริ่มต้น":
ผลลัพธ์เชิงปฏิบัติ: นักพัฒนาหยุดถกเถียงกันว่าจะทำสภาพแวดล้อมให้เหมือนกันอย่างไร และเริ่มส่งหน่วยที่รันได้เหมือนกันทุกที่
คอนเทนเนอร์คือวิธีแพ็กและรันแอปเพื่อให้มันทำงานเหมือนกันบนแล็ปท็อปของคุณ บนเครื่องเพื่อนร่วมงาน และในโปรดักชัน แนวคิดหลักคือ การแยกโดยไม่ต้องมีคอมพิวเตอร์ทั้งเครื่องใหม่
เครื่องเสมือน (VM) เหมือนการเช่าอพาร์ตเมนต์ทั้งห้อง: คุณได้ประตู หน่วยสาธารณูปโภคของคุณเอง และสำเนาระบบปฏิบัติการของคุณ นั่นเป็นเหตุผลที่ VM สามารถรันระบบปฏิบัติการต่างกันข้างเคียงได้ แต่ก็หนักและมักใช้เวลานานกว่าจะบูต
คอนเทนเนอร์เหมือนการเช่าห้องล็อกในอาคารที่ใช้ร่วมกัน: คุณเอาเฟอร์นิเจอร์มาหรือไม่ (โค้ดแอป + ไลบรารี) แต่ยูทิลิตี้ของอาคาร (เคอร์เนลของโฮสต์) ถูกใช้ร่วมกัน คุณยังได้การแยกจากห้องอื่น ๆ แต่ไม่ต้องเริ่มระบบปฏิบัติการใหม่ทุกครั้ง
บน Linux คอนเทนเนอร์พึ่งพาฟีเจอร์การแยกที่ฝังอยู่ซึ่ง:
คุณไม่จำเป็นต้องรู้รายละเอียดเคอร์เนลเพื่อใช้คอนเทนเนอร์ แต่ดีที่จะรู้ว่ามันใช้ฟีเจอร์ของ OS—ไม่ใช่เวทมนตร์
คอนเทนเนอร์กลายเป็นที่นิยมเพราะมัน:
คอนเทนเนอร์ไม่ใช่เขตความปลอดภัยโดยค่าเริ่มต้น เพราะคอนเทนเนอร์ แชร์เคอร์เนลของโฮสต์ ช่องโหว่ระดับเคอร์เนลอาจส่งผลต่อหลายคอนเทนเนอร์ได้ นอกจากนี้ยังหมายความว่าไม่สามารถรัน Windows container บนเคอร์เนล Linux (และกลับกัน) ได้โดยไม่ใช้การจำลองเสมือนเพิ่มเติม
ดังนั้น: คอนเทนเนอร์ปรับปรุงการแพ็กและความสอดคล้อง—แต่คุณยังต้องมีแนวปฏิบัติด้านความปลอดภัย การแพตช์ และการตั้งค่าที่ฉลาด
Docker ประสบความสำเร็จบางส่วนเพราะมันให้ทีมแบบจำลองความคิดที่เรียบง่ายโดยแยกเป็น “ชิ้นส่วน” ชัดเจน: Dockerfile (คำสั่ง), image (อาร์ติแฟกต์ที่สร้าง), และ container (อินสแตนซ์ที่รัน) เมื่อคุณเข้าใจสายโซ่นี้ ระบบนิเวศ Docker อื่น ๆ จะเริ่มมีความหมาย
Dockerfile คือไฟล์ข้อความธรรมดาที่อธิบาย วิธีการสร้าง สภาพแวดล้อมแอปของคุณทีละขั้นตอน คิดเหมือนสูตรทำอาหาร: มันไม่ได้ให้อาหารใครโดยตัวมันเอง แต่บอกวิธีผลิตจานเดิมได้ทุกครั้ง
ขั้นตอนทั่วไปใน Dockerfile ประกอบด้วย: เลือกฐาน (เช่น runtime ของภาษา), คัดลอกโค้ดแอปเข้าไป, ติดตั้ง dependency, และประกาศคำสั่งที่จะรัน
Image คือผลลัพธ์จากการ build Dockerfile มันคือ snapshot ที่รวมทุกอย่างที่ต้องใช้ในการรัน: โค้ดของคุณ ไลบรารี และการตั้งค่าดีฟอลต์ มันไม่ “มีชีวิต”—เหมือนกล่องที่ปิดผนึกที่คุณส่งไปรอบ ๆ
Container คือสิ่งที่ได้เมื่อคุณ รัน image มันคือโปรเซสที่มีไฟล์ระบบแยกและการตั้งค่าของตัวเอง คุณสามารถเริ่ม หยุด รีสตาร์ท และสร้างหลายคอนเทนเนอร์จาก image เดียวกันได้
ภาพถูกสร้างเป็น เลเยอร์ คำสั่งแต่ละขั้นตอนใน Dockerfile มักสร้างเลเยอร์ใหม่ และ Docker พยายามนำเลเยอร์ที่ไม่เปลี่ยนกลับมาใช้ซ้ำ ("แคช")
แบบเข้าใจง่าย: ถ้าคุณเปลี่ยนแค่โค้ดแอป Docker มักจะสามารถนำเลเยอร์ที่ติดตั้งแพ็กเกจระบบและ dependency กลับมาใช้ได้ ทำให้การ build ใหม่เร็วขึ้น นี่ยังส่งเสริมการใช้ซ้ำข้ามโปรเจ็กต์—หลาย image แบ่งเลเยอร์ฐานร่วมกัน
นี่คือลำดับ “สูตร → อาร์ติแฟกต์ → อินสแตนซ์ที่รัน”:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["node", "server.js"]
docker build -t myapp:1.0 .docker run --rm -p 3000:3000 myapp:1.0นี่คือคำสัญญาหลักที่ Docker ทำให้เป็นที่นิยม: ถ้าคุณสร้าง image ได้ คุณจะรันสิ่งเดียวกันได้อย่างเชื่อถือได้—บนแล็ปท็อป ของ CI หรือบนเซิร์ฟเวอร์—โดยไม่ต้องเขียนขั้นตอนการติดตั้งซ้ำทุกครั้ง
การรันคอนเทนเนอร์บนแล็ปท็อปของคุณเองมีประโยชน์—แต่ไม่ใช่จุดเปลี่ยนที่แท้จริง การเปลี่ยนแปลงเกิดขึ้นเมื่อทีมสามารถ แชร์บิลด์เดียวกันเป๊ะ และรันมันทุกที่โดยไม่มีข้อโต้แย้ง “มันใช้ได้บนเครื่องฉัน”
Docker ทำให้การแชร์นั้นรู้สึกปกติเหมือนการแชร์โค้ด
รีจิสทรีคอนเทนเนอร์ คือที่เก็บสำหรับภาพคอนเทนเนอร์ หาก image คือแอปที่ถูกแพ็ก รีจิสทรีคือที่ที่คุณเก็บเวอร์ชันที่แพ็กแล้วเพื่อให้คนอื่นและระบบสามารถดึงไปใช้งานได้
รีจิสทรีรองรับเวิร์กโฟลว์ง่าย ๆ:
รีจิสทรีสาธารณะ (เช่น Docker Hub) ทำให้เริ่มง่าย แต่ทีมส่วนใหญ่ต้องการรีจิสทรีที่ตรงกับกฎการเข้าถึงและข้อกำหนดเชื่อมโยงของพวกเขาเร็ว ๆ นี้
ภาพมักถูกระบุเป็น name:tag—เช่น myapp:1.4.2 แท็กนั้นมากกว่าแค่ป้ายชื่อ: มันคือวิธีที่มนุษย์และระบบยอมรับกันว่า บิลด์ไหน จะรัน
ความผิดพลาดที่พบบ่อยคือพึ่งพา latest มันฟังดูสะดวก แต่กำกวม: "latest" เปลี่ยนได้โดยไม่แจ้ง ทำให้สภาพแวดล้อมเลื่อนไหล การปรับใช้หนึ่งอาจดึงบิลด์ใหม่ก่อนหน้าที่ไม่มีใครตั้งใจอัปเกรด
นิสัยที่ดีกว่า:
1.4.2) สำหรับปล่อยเมื่อคุณแชร์บริการภายใน ไลบรารีที่ต้องชำระเงิน หรือโค้ดของบริษัท คุณมักต้องการ รีจิสทรีส่วนตัว มันให้คุณควบคุมว่าใครดึงหรือพุชภาพได้, ผสานกับ single sign-on, และเก็บซอฟต์แวร์ที่เป็นกรรมสิทธิ์ให้ออกนอกดัชนีสาธารณะ
นี่คือการก้าวจาก "แล็ปท็อปสู่ทีม": เมื่оภาพอยู่ในรีจิสทรี ระบบ CI ของคุณ เพื่อนร่วมงาน และเซิร์ฟเวอร์โปรดักชันต่างดึงอาร์ติแฟกต์เดียวกัน—และการปรับใช้กลายเป็นสิ่งที่ทำซ้ำได้ ไม่ใช่การนำเสนอแบบฉุกเฉิน
CI/CD ทำงานได้ดีที่สุดเมื่อมันสามารถปฏิบัติต่อแอปของคุณเหมือน "สิ่งเดียวที่ทำซ้ำได้" ที่เคลื่อนผ่านขั้นตอนต่าง ๆ คอนเทนเนอร์ให้สิ่งนั้น: อาร์ติแฟกต์เดียว (image) ที่คุณสร้างครั้งเดียวและรันได้หลายครั้ง โดยมีปัญหา "ใช้ได้บนเครื่องฉัน" น้อยลง
ก่อนคอนเทนเนอร์ ทีมมักพยายามจับคู่สภาพแวดล้อมด้วยเอกสารตั้งค่าที่ยาวและสคริปต์ร่วม Docker เปลี่ยนเวิร์กโฟลว์เริ่มต้น: ดึง repo, สร้าง image, รันแอป คำสั่งเหล่านี้มักใช้งานได้บน macOS, Windows, และ Linux เพราะแอปรันในคอนเทนเนอร์
การมาตรฐานนี้ช่วยให้การเข้าใจงานเร็วขึ้น สมาชิกใหม่ใช้เวลาน้อยลงในการติดตั้ง dependency และมากขึ้นในการเข้าใจผลิตภัณฑ์
การตั้งค่า CI/CD ที่ดีมุ่งหวังให้ออกผลลัพธ์ของ pipeline เป็นหนึ่งเดียว กับคอนเทนเนอร์ ผลลัพธ์คือ image ที่ถูกแท็กด้วยเวอร์ชัน (มักเชื่อมกับ commit SHA) ภาพ เดียวกัน นั้นถูกโปรโมตจาก dev → test → staging → production
แทนที่จะสร้างแอปต่างกันในแต่ละสภาพแวดล้อม คุณเปลี่ยนการตั้งค่า (เช่น ตัวแปรสภาพแวดล้อม) ในขณะที่เก็บอาร์ติแฟกต์ให้เหมือนเดิม ซึ่งลดการเบี่ยงเบนของสภาพแวดล้อมและทำให้การปล่อยง่ายต่อการดีบัก
คอนเทนเนอร์แมปอย่างชัดเจนกับขั้นตอนของ pipeline:
เพราะแต่ละขั้นตอนทำงานกับแอปที่แพ็กไว้เหมือนกัน ความล้มเหลวจึงมีความหมายมากขึ้น: เทสที่ผ่านใน CI มีแนวโน้มจะทำงานเหมือนกันหลังการปรับใช้มากขึ้น
ถ้าคุณกำลังปรับกระบวนการ ควรกำหนดกฎง่าย ๆ (ข้อตกลงการแท็ก, การเซ็นภาพ, การสแกนพื้นฐาน) เพื่อให้ pipeline ยังคงคาดเดาได้ คุณสามารถขยายจากนั้นเมื่อตทีมโตขึ้น (ดู /blog/common-mistakes-and-how-to-avoid-them)
เชื่อมต่อกับเวิร์กโฟลว์การพัฒนาเร่งด้วย AI: แพลตฟอร์มเช่น Koder.ai สามารถสร้างและวนเวียนแอปแบบ full-stack (React บนเว็บ, Go + PostgreSQL เป็นแบ็กเอนด์, Flutter สำหรับมือถือ) ผ่านอินเทอร์เฟซแชท—แต่คุณยังต้องการหน่วยการแพ็กที่เชื่อถือได้เพื่อย้ายจาก “มันรันได้” ไปสู่ “มันพร้อมปล่อย” การปฏิบัติต่อทุกบิลด์เป็นภาพคอนเทนเนอร์ที่มีเวอร์ชันช่วยให้การพัฒนาโดย AI ยังคงสอดคล้องกับความคาดหวังของ CI/CD: การสร้างซ้ำได้, การปรับใช้ที่คาดเดาได้, และการย้อนกลับที่พร้อมใช้งาน
Solomon Hykes เป็นวิศวกรที่นำงานด้านการแยกกระบวนการในระดับระบบปฏิบัติการ (คอนเทนเนอร์) มารวมเป็นเวิร์กโฟลว์ที่ใช้งานง่ายสำหรับนักพัฒนา ในปี 2013 งานนี้ถูกเปิดตัวในชื่อ Docker ซึ่งทำให้ทีมทั่วไปสามารถบรรจุแอปพร้อมกับไลบรารีที่คาดหวังและรันได้อย่างสม่ำเสมอในสภาพแวดล้อมต่าง ๆ
คอนเทนเนอร์คือแนวคิดพื้นฐาน: กระบวนการที่แยกจากกันโดยใช้ฟีเจอร์ของระบบปฏิบัติการ (เช่น namespaces และ cgroups บน Linux) ขณะที่ Docker คือชุดเครื่องมือและข้อปฏิบัติที่ทำให้คอนเทนเนอร์สร้าง รัน และแชร์ได้ง่าย (เช่น Dockerfile → image → container) ปัจจุบันคุณยังสามารถใช้คอนเทนเนอร์โดยไม่ต้องใช้ Docker ได้ แต่ Docker เป็นผู้แพร่หลายรูปแบบการทำงานนี้
มันแก้ปัญหา “works on my machine” โดยการรวมโค้ดแอปกับไลบรารีที่ต้องการเป็นหน่วยพกพาที่ทำซ้ำได้ แทนที่จะปล่อย ZIP พร้อมเอกสารติดตั้ง ทีมใช้ภาพคอนเทนเนอร์ที่สามารถรันแบบเดียวกันได้บนแล็ปท็อป, CI, สเตจ และโปรดักชัน
A Dockerfile คือสูตรการสร้าง
An image คือผลลัพธ์ที่ถูกสร้าง (snapshot แบบไม่เปลี่ยนแปลงที่คุณเก็บและแชร์ได้)
A container คืออินสแตนซ์ที่รันจาก image นั้น (กระบวนการที่มีไฟล์ระบบและการตั้งค่าแยกกัน)
หลีกเลี่ยง latest เพราะมันกำกวมและอาจเปลี่ยนโดยไม่แจ้งให้ทราบ ทำให้สภาพแวดล้อมเบี่ยงเบนไป
ตัวเลือกที่ดีกว่า:
1.4.2sha-<hash>)รีจิสทรีคือที่เก็บภาพคอนเทนเนอร์เพื่อให้เครื่องและระบบอื่นดึงภาพเดียวกันมารันได้
ขั้นตอนทั่วไป:
ทีมมักต้องการรีจิสทรีส่วนตัวเมื่อมีการเข้าถึง, ความสอดคล้องตามข้อกำหนด หรือโค้ดภายในที่ไม่ควรอยู่ในพื้นที่สาธารณะ
คอนเทนเนอร์แชร์เคอร์เนลของโฮสต์ จึงเบากว่าและเริ่มต้นเร็วกว่าการรัน VM โดยรวม
ภาพง่าย ๆ:
ข้อจำกัดหนึ่งคือโดยปกติไม่สามารถรัน Windows container บนเคอร์เนล Linux (และกลับกัน) ได้โดยไม่ใช้การจำลองเสมือนเพิ่ม
เพราะคอนเทนเนอร์ให้ผลลัพธ์เดียวเป็นศูนย์กลางของ pipeline: image
รูปแบบ CI/CD ทั่วไป:
คุณเปลี่ยนการตั้งค่า (env vars/secret) ตามสภาพแวดล้อม ไม่ใช่ artifact ทำให้การย้อนกลับและการดีบักง่ายขึ้น
Docker ทำให้การรันคอนเทนเนอร์บนเครื่องเดียวเป็นเรื่องง่าย แต่เมื่อมีคอนเทนเนอร์จำนวนมากกระจายบนหลายเครื่อง คุณต้องการความสามารถด้าน:
Kubernetes ให้ความสามารถเหล่านี้เพื่อจัดการฟลีตคอนเทนเนอร์อย่างคาดเดาได้
คอนเทนเนอร์ทำให้การส่งมอบซอฟต์แวร์ง่ายขึ้น แต่ไม่ได้ทำให้ซอฟต์แวร์ปลอดภัยโดยอัตโนมัติ
แนวทางปฏิบัติพื้นฐาน:
privileged, ลด capabilities, ไม่รันเป็น root เมื่อเป็นไปได้)ข้อควรระวังอื่น ๆ: ระวังการ mount โวลุ่มที่กว้างเกินไป, การเปิด Docker socket ต่อคอนเทนเนอร์, และอย่าลืมแพตช์โฮสต์และเคอร์เนลเพราะคอนเทนเนอร์แชร์เคอร์เนล