สวัสดีทุกคน! ในตัวเขา
การเริ่มต้น
ทุกอย่างเริ่มต้นในเย็นวันที่ฝนตกของเดือนกันยายน ตอนที่ฉันทำความสะอาดเครื่องที่ฉันเช่าในราคา 5 ดอลลาร์บน Digital Ocean ซึ่งถูกแช่แข็งเนื่องจาก Docker ได้เติมพื้นที่ว่างในดิสก์ทั้งหมด 24 กิกะไบต์ด้วยอิมเมจและคอนเทนเนอร์ สิ่งที่น่าขันคืออิมเมจและคอนเทนเนอร์ทั้งหมดนี้เป็นแบบชั่วคราวและจำเป็นสำหรับการทดสอบประสิทธิภาพของแอปพลิเคชันของฉันทุกครั้งที่มีการเปิดตัวไลบรารีหรือเฟรมเวิร์กเวอร์ชันใหม่เท่านั้น ฉันพยายามเขียนเชลล์สคริปต์และตั้งค่าตารางเวลา cron เพื่อล้างขยะ แต่มันก็ไม่ได้ช่วยอะไร: ทุกครั้งที่มันจบลงด้วยการที่พื้นที่ดิสก์ของเซิร์ฟเวอร์ของฉันถูกกินและเซิร์ฟเวอร์หยุดทำงานอย่างหลีกเลี่ยงไม่ได้ (อย่างดีที่สุด) เมื่อถึงจุดหนึ่ง ฉันเจอบทความเกี่ยวกับวิธีรัน Jenkins ในคอนเทนเนอร์ และวิธีสร้างและลบ build ไปป์ไลน์ผ่านซ็อกเก็ต docker daemon ที่ส่งต่อเข้าไป ฉันชอบแนวคิดนี้ แต่ฉันตัดสินใจไปไกลกว่านี้และลองทดลองใช้งาน Docker โดยตรงใน Docker ในเวลานั้น สำหรับฉันแล้วดูเหมือนว่าโซลูชันที่สมเหตุสมผลในการดาวน์โหลดอิมเมจ Docker และสร้างคอนเทนเนอร์สำหรับแอปพลิเคชันทั้งหมดที่ฉันต้องการสำหรับการทดสอบภายในคอนเทนเนอร์อื่น (ขอเรียกว่าคอนเทนเนอร์ชั่วคราว) แนวคิดก็คือการเริ่มต้นคอนเทนเนอร์การแสดงละครด้วยแฟล็ก -rm ซึ่งจะลบคอนเทนเนอร์ทั้งหมดและเนื้อหาทั้งหมดโดยอัตโนมัติเมื่อหยุดทำงาน ฉันปรับแต่งอิมเมจ Docker จาก Docker เอง (
ฝึกฝน. โคน
ฉันตั้งใจที่จะทำให้คอนเทนเนอร์ทำงานตามที่ฉันต้องการและทำการทดลองต่อ ซึ่งส่งผลให้มีตามากมาย ผลลัพธ์ของการทรมานตัวเองของฉันคืออัลกอริทึมต่อไปนี้:
-
เราเปิดตัวคอนเทนเนอร์ Docker ในโหมดโต้ตอบ
docker run --privileged -it docker:18.09.6
ให้ความสนใจกับเวอร์ชันของคอนเทนเนอร์ ไปทางขวาหรือซ้าย จากนั้น DinD ของคุณจะกลายเป็นฟักทอง ในความเป็นจริง สิ่งต่างๆ มักจะพังบ่อยครั้งเมื่อมีการเปิดตัวเวอร์ชันใหม่
เราต้องเข้าไปในเปลือกทันที -
เรากำลังพยายามค้นหาว่าคอนเทนเนอร์ใดกำลังทำงานอยู่ (คำตอบ: ไม่มี) แต่ให้เรารันคำสั่งต่อไป:
docker ps
คุณจะประหลาดใจเล็กน้อย แต่ปรากฎว่า Docker daemon ไม่ทำงานด้วยซ้ำ:
error during connect: Get http://docker:2375/v1.40/containers/json: dial tcp: lookup docker on 192.168.65.1:53: no such host
-
เรามาดำเนินการกันเอง:
dockerd &
ความประหลาดใจอันไม่พึงประสงค์อีกอย่าง:
failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: Iptables not found
-
ติดตั้งแพ็คเกจ iptables และ bash (ทุกอย่างน่าทำงานมากกว่าใน bash มากกว่าใน sh):
apk add --no-cache iptables bash
-
มาเปิดตัวทุบตีกันเถอะ ในที่สุดเราก็กลับมาอยู่ในเปลือกปกติ
-
ลองเปิด Docker อีกครั้ง:
dockerd &
เราควรเห็นบันทึกแผ่นยาวที่ลงท้ายด้วย:
INFO[2019-11-25T19:51:19.448080400Z] Daemon has completed initialization INFO[2019-11-25T19:51:19.474439300Z] API listen on /var/run/docker.sock
-
กดปุ่มตกลง. เรากลับมาทุบตีแล้ว
จากนี้ไป เราสามารถลองเปิดตัวคอนเทนเนอร์อื่นๆ ภายในคอนเทนเนอร์ Docker ของเราได้ แต่จะเป็นอย่างไรหากเราต้องการเปิดตัวคอนเทนเนอร์ Docker อื่นภายในคอนเทนเนอร์ Docker ของเรา หรือมีบางอย่างผิดพลาดและคอนเทนเนอร์ขัดข้อง เริ่มต้นใหม่ทั้งหมดอีกครั้ง
เป็นเจ้าของคอนเทนเนอร์ DinD และการทดลองใหม่
เพื่อหลีกเลี่ยงการทำซ้ำขั้นตอนข้างต้นซ้ำแล้วซ้ำอีก ฉันจึงสร้างคอนเทนเนอร์ DinD ของตัวเองขึ้นมา:
โซลูชัน DinD ที่ใช้งานได้ทำให้ฉันสามารถเรียกใช้ Docker ภายใน Docker แบบวนซ้ำและทำการทดลองที่ท้าทายมากขึ้น
ฉันจะอธิบายการทดลองหนึ่ง (ที่ประสบความสำเร็จ) กับการรัน MySQL และ Nodejs ทันที
คนที่ใจร้อนที่สุดก็สามารถมองเห็นได้ว่าที่นี่เป็นอย่างไร
ดังนั้นมาเริ่มกันเลย:
-
เราเปิดตัว DinD ในโหมดโต้ตอบ ใน DinD เวอร์ชันนี้ เราจำเป็นต้องแมปพอร์ตทั้งหมดที่คอนเทนเนอร์ย่อยของเราสามารถใช้ได้ด้วยตนเอง (ฉันกำลังดำเนินการในส่วนนี้อยู่แล้ว)
docker run --privileged -it -p 80:8080 -p 3306:3306 alekslitvinenk/dind
เราเข้าสู่การทุบตีซึ่งเราสามารถเริ่มเปิดตัวคอนเทนเนอร์ย่อยได้ทันที
-
เปิดตัว MySQL:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=strongpassword -d -p 3306:3306 mysql
-
เราเชื่อมต่อกับฐานข้อมูลในลักษณะเดียวกับที่เราเชื่อมต่อกับฐานข้อมูลภายในเครื่อง ตรวจสอบให้แน่ใจว่าทุกอย่างทำงานได้
-
เปิดตัวคอนเทนเนอร์ที่สอง:
docker run -d --rm -p 8080:8080 alekslitvinenk/hello-world-nodejs-server
โปรดทราบว่าการแมปพอร์ตจะเป็นเช่นนั้นทุกประการ 8080:8080เนื่องจากเราได้แมปพอร์ต 80 จากโฮสต์ไปยังคอนเทนเนอร์หลักกับพอร์ต 8080 แล้ว
-
เราไปที่ localhost ในเบราว์เซอร์ ตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ตอบสนอง "Hello World!"
ในกรณีของฉัน การทดลองกับคอนเทนเนอร์ Docker ที่ซ้อนกันกลับกลายเป็นผลดีทีเดียว และฉันจะพัฒนาโปรเจ็กต์ต่อไปและใช้สำหรับการแสดงละคร สำหรับฉันดูเหมือนว่านี่เป็นโซลูชันที่เบากว่า Kubernetes และ Jenkins X มาก แต่นี่คือความเห็นส่วนตัวของฉัน
ฉันคิดว่านั่นคือทั้งหมดสำหรับบทความของวันนี้ ในบทความถัดไป ผมจะอธิบายการทดลองโดยละเอียดเพิ่มเติมด้วยการรัน Docker แบบวนซ้ำใน Docker และการติดตั้งไดเรกทอรีลึกลงในคอนเทนเนอร์ที่ซ้อนกัน
PS หากคุณพบว่าโปรเจ็กต์นี้มีประโยชน์ โปรดติดดาวบน GitHub และแยกมันออกและบอกต่อเพื่อนของคุณ
Edit1 แก้ไขข้อผิดพลาดโดยเน้นที่วิดีโอ 2 รายการ
ที่มา: will.com