นี่เป็นเพียงการสาธิตง่ายๆ เพื่อทำความเข้าใจพื้นฐานว่า Docker ทำงานอย่างไรขณะทำงานทีละขั้นตอน ฉันเรียนรู้ Docker แบบนี้และทำ Repo นี้เพื่อแก้ไขปัญหาบางอย่างที่ฉันเผชิญระหว่างประสบการณ์การเรียนรู้ เพื่อที่จะได้ช่วยเหลือผู้เริ่มต้นคนอื่นๆ ได้ หวังว่าคุณจะสนุกกับการเรียนรู้ ถ้าคุณชอบก็ให้ไปที่ GitHub และสนับสนุนงานของฉัน
สิ่งสำคัญ:- เมื่อเห็นขนาดของ readme คุณอาจมีความคิดที่สอง แต่พูดตามตรง หากคุณทำงานตั้งแต่เริ่มต้น คุณจะไม่มีปัญหาใดๆ และเรียนรู้ไปพร้อมกัน
Wikipedia กำหนด Docker เป็น
คือชุดของแพลตฟอร์มที่เป็นผลิตภัณฑ์บริการ (PaaS) ที่ใช้การจำลองเสมือนระดับ OS เพื่อส่งมอบซอฟต์แวร์ในแพ็คเกจที่เรียกว่าคอนเทนเนอร์ คอนเทนเนอร์จะถูกแยกออกจากกันและรวมซอฟต์แวร์ ไลบรารี และไฟล์การกำหนดค่าเข้าด้วยกัน สามารถสื่อสารกันผ่านช่องทางที่ชัดเจน คอนเทนเนอร์ทั้งหมดทำงานโดยเคอร์เนลระบบปฏิบัติการเดียว ดังนั้นจึงใช้ทรัพยากรน้อยกว่าเครื่องเสมือน
Docker ช่วยคุณในการปรับใช้แอปพลิเคชันของคุณอย่างมีประสิทธิภาพมากขึ้นในแซนด์บ็อกซ์ (เรียกว่าคอนเทนเนอร์) เพื่อทำงานบนระบบปฏิบัติการโฮสต์ เช่น Mac ข้อได้เปรียบหลักของนักเทียบท่าคือช่วยให้คุณสามารถรวมซอฟต์แวร์ที่มีการขึ้นต่อกันทั้งหมดไว้ในหน่วยมาตรฐานเดียว
คอนเทนเนอร์คือโซลูชันสำหรับวิธีทำให้ซอฟต์แวร์ทำงานโดยไม่มีปัญหาใดๆ เมื่อย้ายจากสภาพแวดล้อมการประมวลผลหนึ่งไปยังอีกสภาพแวดล้อมหนึ่ง ซึ่งอาจมาจากสภาพแวดล้อมชั่วคราวไปจนถึงการใช้งานจริง หรืออาจจากแล็ปท็อปไปยังแล็ปท็อปเครื่องอื่นที่มีระบบปฏิบัติการอื่น
คอนเทนเนอร์จัดเตรียมกลไกการบรรจุแบบลอจิคัลซึ่งทำให้แอปพลิเคชันของคุณถูกแยกออกจากสภาพแวดล้อมที่แอปพลิเคชันทำงานอยู่ ข้อแตกต่างที่สำคัญคือทุกคอนเทนเนอร์ไม่จำเป็นต้องใช้ระบบปฏิบัติการเต็มรูปแบบ คอนเทนเนอร์ทั้งหมดบนโฮสต์เดียวที่แชร์ระบบปฏิบัติการเดียว ซึ่งจะช่วยเพิ่มพื้นที่ว่างทรัพยากรระบบจำนวนมหาศาล เช่น CPU, RAM
เมื่อคุณติดตั้ง Docker เสร็จแล้ว ให้ทดสอบการติดตั้ง Docker ของคุณโดยดำเนินการดังต่อไปนี้:
docker run hello-world
Hello from Docker.
This message shows that your installation appears to be working correctly.
...
Dockerfile
คือเอกสารข้อความที่มีคำสั่งทั้งหมดที่คุณสามารถเรียกใช้บนบรรทัดคำสั่งเพื่อสร้างรูปภาพได้ สร้างไฟล์ hello.js
และคัดลอกโค้ดนี้ลงไป ที่นี่เราเขียนโค้ด JS ง่ายๆ เพื่อแสดง Hello World บน localhost:8888
var http = require( " http " ) ;
http.createServer(function (request, response) {
response.writeHead(200, { ' Content-Type ' : ' text/plain ' }) ;
response.end( ' Hello Worldn ' ) ;
}).listen(8888) ;
// Console will print the message
console.log( ' Server running at http://127.0.0.1:8888/ ' ) ;
Dockerfile
และคัดลอกโค้ดนี้ลงไป FROM node:8
LABEL maintainer= " [email protected] "
RUN npm install
ADD hello.js /hello.js
EXPOSE 8888
ENTRYPOINT [ " node " , " hello.js " ]
แม้ว่านี่จะเป็น Dockerfile แรกที่คุณเคยเห็น แต่ฉันว่าคุณสามารถเดาได้ดีว่าเกิดอะไรขึ้นที่นี่ คำแนะนำ Dockerfile คือ FROM, ENV, LABEL, RUN , ADD , EXPOSE และ ENTRYPOINT พวกเขาอยู่ในเมืองหลวง แต่นั่นเป็นเพียงแบบแผน ไม่ใช่ข้อกำหนด
ในระดับสูง Dockerfile นี้ให้คำแนะนำเช่นเริ่มต้นด้วยอิมเมจโหนด, เพิ่ม “[email protected]”
เป็นผู้ดูแล, เรียกใช้ npm install
เพื่อติดตั้งการอ้างอิง, คัดลอกไฟล์ในโค้ดแอปพลิเคชัน, บันทึกพอร์ตเครือข่ายของแอป และตั้งค่า hello.js เป็นแอปพลิเคชันเริ่มต้นที่จะรัน
ตอนนี้เราจะสร้างอิมเมจนักเทียบท่าในเครื่องของเรา เปิดเทอร์มินัลของคุณในโฟลเดอร์ของโปรเจ็กต์ปัจจุบันแล้วรัน
docker build -t helloworld .
ที่นี่คุณกำลังบอกให้ Docker สร้างอิมเมจที่เรียกว่า helloworld
ตามเนื้อหาของไดเร็กทอรีปัจจุบัน (สังเกต จุด (.) ที่ส่วนท้ายของคำสั่ง build) นักเทียบท่าจะค้นหา Dockerfile ในไดเร็กทอรีและสร้างอิมเมจตามคำแนะนำในไฟล์
หลังจากสร้างอิมเมจนักเทียบท่าแล้ว ขั้นตอนต่อไปคือการเรียกใช้อิมเมจและดูว่าใช้งานได้หรือไม่:
docker run -p 8888:8888 helloworld
คำสั่งที่เราเพิ่งรันใช้พอร์ต 8888 สำหรับเซิร์ฟเวอร์ภายในคอนเทนเนอร์และเปิดเผยสิ่งนี้ภายนอกบนพอร์ต 8888 ตรงไปที่ URL ที่มีพอร์ต 8888:
ยินดีด้วย! คุณสร้างอิมเมจนักเทียบท่าแรกสำเร็จแล้ว
อิมเมจนักเทียบท่าเป็นเหมือนเทมเพลตเครื่องเสมือนและใช้เพื่อเริ่มคอนเทนเนอร์ ภายใต้ประทุน พวกมันประกอบด้วยเลเยอร์อ่านอย่างเดียวตั้งแต่หนึ่งเลเยอร์ขึ้นไป ซึ่งเมื่อวางซ้อนกันจะทำให้เกิดเป็นภาพโดยรวม นักเทียบท่าจะดูแลการซ้อนเลเยอร์เหล่านี้และแสดงให้เป็นวัตถุที่รวมเป็นหนึ่งเดียว หมายเหตุ: รูปภาพ Docker ไม่เปลี่ยนรูป หมายความว่ารูปภาพ Docker ไม่สามารถเปลี่ยนแปลงได้ เมื่อคุณสร้างแล้ว คุณสามารถลบออกได้ แต่จะไม่สามารถแก้ไขได้
อิมเมจ Docker มีไฟล์ทั้งหมดที่คุณจัดแพ็กเกจ ซึ่งกลายเป็นระบบไฟล์ของคอนเทนเนอร์ และยังมีข้อมูลเมตามากมายเกี่ยวกับอิมเมจนั้นด้วย รวมถึงประวัติโดยย่อเกี่ยวกับวิธีการสร้างภาพดังกล่าว คุณสามารถใช้สิ่งนั้นเพื่อดูแต่ละเลเยอร์ของรูปภาพและคำสั่งที่สร้างเลเยอร์ได้ คุณสามารถตรวจสอบประวัติของภาพ helloworld
ได้โดยใช้:
docker image history helloworld
IMAGE CREATED CREATED BY COMMENT
cb84eb33ca20 58 seconds ago /bin/sh -c # (nop) ENTRYPOINT ["node" "hello…
7d652a817a9f 58 seconds ago /bin/sh -c # (nop) EXPOSE 8888
334575e947c9 59 seconds ago /bin/sh -c # (nop) ADD file:b9606ef53b832e66e…
คำสั่ง CREATED BY
คือคำสั่ง Dockerfile ซึ่งมีความสัมพันธ์แบบหนึ่งต่อหนึ่ง ดังนั้นแต่ละบรรทัดใน Dockerfile จึงสร้างเลเยอร์รูปภาพขึ้นมา
ขั้นแรก คุณต้องเข้าสู่ระบบด้วยบัญชี dockerhub ของคุณก่อน
docker login --username $dockerId
เมื่อคุณเข้าสู่ระบบแล้ว คุณสามารถส่งรูปภาพไปยังบัญชีของคุณหรือองค์กรใดๆ ที่คุณสามารถเข้าถึงได้ หากคุณไม่ได้เป็นสมาชิกขององค์กรใดๆ คุณสามารถพุชรูปภาพไปยังที่เก็บข้อมูลในบัญชีของคุณเท่านั้น
เราสร้างอิมเมจ Docker ที่เรียกว่า helloworld
การอ้างอิงรูปภาพนั้นไม่มีชื่อบัญชี ดังนั้นเราจึงไม่สามารถส่งไปยังรีจิสทรีใดๆ ได้ เราไม่จำเป็นต้องสร้างรูปภาพใหม่เพื่อใช้อ้างอิงใหม่ แต่รูปภาพสามารถมีข้อมูลอ้างอิงได้หลายรายการ แท็กรูปภาพของคุณดังนี้:
docker image tag helloworld $dockerId /helloworld:v1
ตอนนี้เรามีข้อมูลอ้างอิงรูปภาพพร้อม Docker ID ของเราในชื่อบัญชี และเราลงชื่อเข้าใช้ Docker Hub ดังนั้นเราจึงพร้อมที่จะแชร์รูปภาพของเรา! คำสั่ง docker image push เป็นคำสั่งที่เทียบเท่ากับคำสั่ง pull โดยจะอัปโหลดเลเยอร์รูปภาพในเครื่องของเราไปยังรีจิสทรี:
docker image push championshuttler/helloworld:v1
The push refers to a repository [docker.io/championshuttler/helloworld]
9519a21ac374: Pushed
เราสามารถใส่สตริงใดๆ ลงในแท็กรูปภาพ Docker ได้ และดังที่เราได้เห็นแล้วว่าคุณสามารถมีหลายแท็กสำหรับรูปภาพเดียวกันได้ เราจะใช้สิ่งนั้นเพื่อกำหนดเวอร์ชันของซอฟต์แวร์ในรูปภาพของเรา และให้ผู้ใช้ตัดสินใจโดยมีข้อมูลประกอบในสิ่งที่พวกเขาจะไม่ใช้ และเพื่อตัดสินใจด้วยข้อมูลของเราเองเมื่อเราใช้รูปภาพของผู้อื่น
โปรเจ็กต์ซอฟต์แวร์จำนวนมากใช้รูปแบบการกำหนดเวอร์ชันตัวเลขที่มีจุดทศนิยมเพื่อระบุว่ามีการเปลี่ยนแปลงมากน้อยเพียงใดระหว่างเวอร์ชันต่างๆ และคุณสามารถติดตามการเปลี่ยนแปลงนั้นด้วยแท็กรูปภาพของคุณ แนวคิดพื้นฐานคือ [major].[minor].[patch] ซึ่งมีการรับประกันโดยนัยบางประการ การเปิดตัวที่เพิ่มหมายเลขแพทช์เท่านั้นอาจมีการแก้ไขข้อบกพร่อง แต่ควรมีคุณสมบัติเหมือนกับเวอร์ชันล่าสุด การเปิดตัวที่เพิ่มเวอร์ชันรองอาจเพิ่มคุณสมบัติ แต่ไม่ควรลบออก การเปิดตัวครั้งใหญ่อาจมีฟีเจอร์ที่แตกต่างไปจากเดิมอย่างสิ้นเชิง
แอปพลิเคชันส่วนใหญ่ไม่ได้ทำงานในองค์ประกอบเดียว แม้แต่แอปเก่าๆ ขนาดใหญ่ก็มักจะสร้างเป็นส่วนประกอบส่วนหน้าและส่วนหลัง ซึ่งเป็นเลเยอร์ลอจิคัลที่แยกจากกันที่ทำงานในส่วนประกอบที่กระจายทางกายภาพ Docker เหมาะอย่างยิ่งสำหรับการใช้งานแอปพลิเคชันแบบกระจาย ตั้งแต่โมโนลิธระดับ n ไปจนถึงไมโครเซอร์วิสสมัยใหม่ แต่ละส่วนประกอบทำงานในคอนเทนเนอร์น้ำหนักเบา และ Docker จะเชื่อมต่อส่วนประกอบเหล่านั้นเข้าด้วยกันโดยใช้โปรโตคอลเครือข่ายมาตรฐาน คุณกำหนดและจัดการแอพหลายคอนเทนเนอร์เช่นนี้ได้โดยใช้ Docker Compose Docker Compose เป็นเครื่องมือสำหรับกำหนดและเรียกใช้แอปพลิเคชัน Docker แบบหลายคอนเทนเนอร์ เมื่อใช้ Compose คุณจะใช้ไฟล์ YAML
เพื่อกำหนดค่าบริการของแอปพลิเคชันของคุณ จากนั้นด้วยคำสั่งเดียว เราจะสร้างและเริ่มบริการทั้งหมดจากการกำหนดค่าของคุณ
ไฟล์ Docker Compose อธิบายสถานะที่ต้องการของแอปของคุณ - ควรมีลักษณะอย่างไรเมื่อทุกอย่างทำงาน เป็นรูปแบบไฟล์ธรรมดาที่คุณบันทึกตัวเลือกทั้งหมดที่คุณใส่ไว้ในคำสั่งเรียกใช้คอนเทนเนอร์นักเทียบท่าลงในไฟล์เขียน จากนั้นคุณใช้เครื่องมือ Docker Compose เพื่อเรียกใช้แอพ โดยจะพิจารณาว่าทรัพยากร Docker ใดที่ต้องการ ซึ่งอาจเป็นคอนเทนเนอร์ เครือข่าย หรือวอลุ่ม และส่งคำขอไปยัง Docker API เพื่อสร้างคำขอเหล่านั้น ชื่อเริ่มต้นสำหรับไฟล์ Compose YAML คือ docker-compose.yml
อย่างไรก็ตาม เราสามารถใช้แฟล็ก -f เพื่อระบุชื่อไฟล์ที่กำหนดเองได้
มาเริ่มกันเลย
ด้านล่างโค้ดแสดงไฟล์ Docker Compose
ที่เรียบง่ายซึ่งกำหนดแอป Flask ขนาดเล็กที่มีสองบริการ (ส่วนหน้าของเว็บและ Redis) แอปนี้เป็นเว็บเซิร์ฟเวอร์ธรรมดาที่นับจำนวนการเข้าชมและจัดเก็บมูลค่าไว้ใน Redis
version: " 3.5 "
services:
web-frontend:
build: .
command: python app.py
ports:
- target: 8888
published: 8888
networks:
- counter-net
volumes:
- type: volume
source: counter-vol
target: /code
redis:
image: " redis:alpine "
networks:
counter-net:
networks:
counter-net:
volumes:
counter-vol:
จำเป็นต้องมีคีย์ version
และควรอยู่ที่บรรทัดแรกของไฟล์เสมอ ซึ่งจะอธิบายเวอร์ชันของรูปแบบ Compose file
(โดยทั่วไปคือ API)
คีย์ services
ระดับบนสุดคือที่ที่เรากำหนดบริการแอปพลิเคชันต่างๆ ตัวอย่างที่เราใช้กำหนดสองบริการ ส่วนหน้าของเว็บเรียกว่า web-frontend
และฐานข้อมูลในหน่วยความจำที่เรียกว่า Redis Compose จะปรับใช้แต่ละบริการเหล่านี้เป็นคอนเทนเนอร์
คีย์ networks
ระดับบนสุดจะบอก Docker ให้สร้างเครือข่ายใหม่ ตามค่าเริ่มต้น Compose จะสร้างเครือข่ายบริดจ์ เหล่านี้เป็นเครือข่ายโฮสต์เดียวที่สามารถเชื่อมต่อคอนเทนเนอร์บนโฮสต์เดียวกันเท่านั้น
ภายในคำจำกัดความของบริการส่วนหน้าของเว็บ เราให้คำแนะนำแก่ Docker ดังต่อไปนี้:
เราจะปรับใช้แอปที่กำหนดไว้ในไฟล์เขียนจากส่วนก่อนหน้า หากต้องการทำสิ่งนี้ คุณจะต้องมี 4 ไฟล์ต่อไปนี้จาก https://github.com/championshuttler/counter-app:
โคลน repo Git ในเครื่อง
git clone https://github.com/championshuttler/counter-app.git
มาอธิบายแต่ละไฟล์อย่างรวดเร็ว:
app.py
คือโค้ดแอปพลิเคชัน (แอป Python Flask)docker-compose.yml
เป็นไฟล์ Docker Compose ที่อธิบายว่า Docker ควรปรับใช้แอปอย่างไรDockerfile
อธิบายวิธีสร้างอิมเมจสำหรับบริการส่วนหน้าของเว็บrequirements.txt
แสดงรายการแพ็คเกจ Python ที่จำเป็นสำหรับแอป ลองใช้ Compose เพื่อเปิดแอปขึ้นมา คุณต้องรันคำสั่งต่อไปนี้ทั้งหมดจากภายในไดเร็กทอรี counter-app
:
docker-compose up &
จะใช้เวลาไม่กี่วินาทีก่อนที่แอปจะปรากฏขึ้น และผลลัพธ์ที่ได้ก็ค่อนข้างละเอียด
เมื่อปรับใช้แอปพลิเคชันเรียบร้อยแล้ว คุณสามารถชี้เว็บเบราว์เซอร์ไปที่โฮสต์ Docker ของคุณบน port 5000
และดูแอปพลิเคชันได้อย่างเต็มประสิทธิภาพ
คุณพบว่าบทช่วยสอนนี้เลอะเทอะไปหมดหรือคุณสนุกและเรียนรู้อะไรบางอย่างหรือไม่? ส่งความคิดของคุณมาให้ฉันโดยตรงหรือเพียงแค่สร้างปัญหา ค้นหาฉันบน Twitter ด้วยเช่นกัน อย่าลังเลที่จะถามคำถามที่คุณมีข้อสงสัย
ฉันชอบที่จะได้ยินเกี่ยวกับประสบการณ์ของคุณกับบทช่วยสอนนี้ หวังว่าคุณจะสนุกกับการเรียนรู้ หากคุณชอบโปรดไปที่ GitHub และสนับสนุนงานของฉัน