Bocker: Docker ที่เขียนด้วย Bash ประมาณ 100 บรรทัด (2015)
(github.com/p8952)- Bocker เป็นโปรเจกต์ที่นำ Docker มาเขียนใหม่ด้วย Bash ประมาณ 100 บรรทัด โดยมี flow คล้าย Docker เช่น pull อิมเมจ, run คอนเทนเนอร์, ดู logs, commit และลบ
- การรันต้องใช้ btrfs-progs, curl, iproute2, iptables, libcgroup-tools, util-linux 2.25.2 ขึ้นไป และ coreutils 7.5 ขึ้นไป อีกทั้งต้องมีไฟล์ซิสเต็ม btrfs ใต้
/var/bockerและการตั้งค่าเครือข่ายbridge0 - ตัวอย่างใน README แสดง flow ตั้งแต่ pull อิมเมจ
centos:7แล้วรันคำสั่งในคอนเทนเนอร์ จากนั้น commit ผลของyum install -y wgetและตรวจสอบ/usr/bin/wgetในการรันครั้งถัดไป - Bocker รันด้วย root และเปลี่ยน network interface, routing table, firewall rules จึงแนะนำให้ รันใน virtual machine และไม่มีการรับประกันเกี่ยวกับความเสียหายที่อาจเกิดกับระบบ
- ปัจจุบัน implement
docker pull,images,ps,run,exec,logs,commit,rm/rmi, networking และ quota ที่อิงกับ CGroups แล้ว แต่ data volume, data volume container และ port forwarding ยังไม่ได้ implement
วัตถุประสงค์และขอบเขตของ Bocker
- Bocker เป็นโปรเจกต์ที่นำ Docker มา implement ด้วย Bash ประมาณ 100 บรรทัด
- README แสดง flow คำสั่งที่คล้าย Docker โดยอิงกับ Bash และครอบคลุมฟีเจอร์อย่างการจัดการอิมเมจ, การรันคอนเทนเนอร์, การดู logs, การ commit การเปลี่ยนแปลง และการจำกัดทรัพยากร
ข้อกำหนดในการรัน
- แพ็กเกจที่จำเป็นสำหรับการรันมีดังนี้
-
btrfs-progs
- curl
- iproute2
- iptables
- libcgroup-tools
- util-linux 2.25.2 ขึ้นไป
- coreutils 7.5 ขึ้นไป
- ดิสโทรส่วนใหญ่ไม่มี util-linux ที่ใหม่พอ ดังนั้นอาจต้องดาวน์โหลด ซอร์ส util-linux 2.25 แล้วคอมไพล์เอง
- ระบบต้องมีการตั้งค่าต่อไปนี้
- ไฟล์ซิสเต็ม btrfs ที่เมานต์อยู่ใต้
/var/bocker - network bridge ชื่อ
bridge0พร้อม IP10.0.0.1/24 - เปิดใช้งาน IP forwarding ที่
/proc/sys/net/ipv4/ip_forward - การตั้งค่า firewall เพื่อ route traffic จาก
bridge0ไปยัง physical interface - มี Vagrantfile รวมมาให้เพื่อสร้าง environment ที่จำเป็นได้ง่าย
-
ข้อควรระวังเมื่อรัน
- แม้จะมีข้อกำหนดครบถ้วน ก็ยังแนะนำให้รัน Bocker ใน virtual machine
- Bocker รันด้วย root และต้องเปลี่ยนรายการต่อไปนี้
- network interface
- routing table
- firewall rules
- README ระบุชัดว่าไม่สามารถรับประกันได้ว่า Bocker จะไม่ทำให้ระบบเสียหาย
ตัวอย่าง flow การใช้งาน
- เมื่อดึงอิมเมจ
centos:7ด้วยbocker pull centos 7จะได้ image ID เช่นimg_42150 bocker imagesแสดง image ID และ source- ตัวอย่าง output:
img_42150,centos:7
- ตัวอย่าง output:
bocker run img_42150 cat /etc/centos-releaseแสดงข้อมูล release ของ CentOS จากในคอนเทนเนอร์- ตัวอย่าง output:
CentOS Linux release 7.1.1503 (Core)
- ตัวอย่าง output:
bocker psแสดง container ID และคำสั่งที่รันbocker logs ps_42045แสดง output log ของคอนเทนเนอร์นั้นbocker rm ps_42045ลบคอนเทนเนอร์- เมื่อรัน
bocker run img_42150 which wgetในตอนแรก จะได้ผลว่าไม่มีwget - หลังติดตั้ง
wgetด้วยbocker run img_42150 yum install -y wgetแล้วใช้bocker commit ps_42018 img_42150เพื่อสะท้อนการเปลี่ยนแปลงกลับไปยังอิมเมจ - หลังจากนั้น
bocker run img_42150 which wgetจะแสดง/usr/bin/wget
การจำกัดทรัพยากรและ CGroups
- ตัวอย่างการรัน Bocker แสดงให้เห็นว่าคอนเทนเนอร์ถูกวางไว้ใต้ CGroups
- ใน
/proc/1/cgroupจะมีรายการอย่างmemory:/ps_42152,cpuacct,cpu:/ps_42152ปรากฏขึ้น
- ใน
- ตัวอย่างค่า CPU share และ memory limit เริ่มต้นมีดังนี้
/sys/fs/cgroup/cpu/ps_42152/cpu.shares:512/sys/fs/cgroup/memory/ps_42152/memory.limit_in_bytes:512000000
- สามารถเปลี่ยน resource limit ได้ด้วย environment variables
BOCKER_CPU_SHARE=1024BOCKER_MEM_LIMIT=1024
- ตัวอย่างหลังเปลี่ยนแสดงค่าดังนี้
- CPU shares:
1024 - memory limit:
1024000000
- CPU shares:
ฟีเจอร์ที่ implement แล้วและยังไม่ได้ implement
- ฟีเจอร์ที่ implement แล้วในปัจจุบันมีดังนี้
docker build†docker pulldocker imagesdocker psdocker rundocker execdocker logsdocker commitdocker rm/docker rmi-
Networking
- รองรับ Quota / CGroups
- †
bocker initให้การ implementdocker buildแบบจำกัดมาก - ฟีเจอร์ที่ยังไม่ได้ implement มีดังนี้
- Data Volume Containers
- Data Volumes
- Port Forwarding
ไลเซนส์
- Bocker เป็นซอฟต์แวร์เสรีที่สามารถแจกจ่ายซ้ำและแก้ไขได้ภายใต้เงื่อนไขของ GNU General Public License
- สามารถเลือกใช้ไลเซนส์เวอร์ชัน GPL v3 ที่เผยแพร่โดย Free Software Foundation หรือเวอร์ชันหลังจากนั้นได้
- โปรแกรมถูกแจกจ่ายโดยหวังว่าจะเป็นประโยชน์ แต่ไม่มีการรับประกันโดยนัยใด ๆ เรื่องความสามารถในการขายหรือความเหมาะสมกับวัตถุประสงค์เฉพาะ
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ผมเคยทำของคล้าย ๆ กันด้วย proot ชื่อว่า Bag [1] และคงไม่ได้อธิบายว่าเป็นทางเลือกแทน Docker
มันไม่เกี่ยวกับ cgroups และอินเทอร์เฟซบรรทัดคำสั่งก็แตกต่างจาก Docker ด้วย เบื้องหลังคือผมสร้าง proxy chain ที่ดูเหมือนทราฟฟิก HTML ปกติ เพื่อหลบเลี่ยงการเซ็นเซอร์อินเทอร์เน็ตและ การตรวจสอบแพ็กเก็ตเชิงลึก และต้องให้มันรันต่อเนื่องได้ทุกที่ แต่ไม่อยากพอร์ตเป็นแอปเนทีฟบน Android
ผมอยากรันบน Termux แต่ตอนนั้น Termux ไม่มี JDK/JRE และถ้าใช้ proot เปิดสภาพแวดล้อม Arch Linux ก็จะใช้ JDK ได้ สภาพแวดล้อม Arch ภายใน Termux โดยรวมมีประโยชน์กว่า และการสร้าง สภาพแวดล้อมแบบใช้ครั้งเดียว ที่ตั้งค่าต่างกัน ลบทิ้ง แล้วเข้าไปด้วย proot เพื่อรันเพียงคำสั่งเดียว ก็ทำให้เป็นอัตโนมัติด้วยสคริปต์ได้ง่าย ดังนั้นจึงตั้งชื่อว่า bag.sh เพราะหมายถึงรูปแบบที่เล็กกว่าตู้คอนเทนเนอร์ขนส่งมาก
น่าสนุกตรงที่ bag.sh ยังมีโรดแมป/TODO ที่ไม่ได้แตะมา 5 ปีเหลืออยู่ด้วย ส่วนใหญ่จัดบรรทัดไว้ที่ 40 คอลัมน์ เพราะเขียนบนหน้าจอมือถือและอยากดูโดยไม่ต้องเลื่อน
[1]: https://github.com/hkoosha/bag
ผมสร้าง Debian ขนาดเล็กไว้ใน /opt ที่ใส่ซอฟต์แวร์ที่จำเป็นและ dependency อย่าง MySQL ไว้ด้วย และมันทำงานได้ค่อนข้างดี ใช้กันจนบริษัทที่ผมทำให้ถูกซื้อกิจการราวปี 2016 พูดให้กว้างกว่านั้น ผมคิดว่าการลองทำเวอร์ชันหยาบ ๆ ของแอปพลิเคชันขนาดใหญ่ด้วยตัวเอง เป็นหนึ่งใน วิธีที่ดีที่สุด ในการเรียนรู้กลไกภายใน
mkdir -p $(dirname "$2")ถ้าจับคู่กับคีย์บอร์ด Bluetooth ราว 10 นิ้วที่ใส่กระเป๋าด้านในของแจ็กเก็ตหนังได้สบาย ๆ ต่อให้ออกจากบ้านโดยไม่มีกระเป๋า ก็ยังไปนั่งมุมหนึ่งในเบียร์การ์เดนใกล้ ๆ แล้วเขียนโค้ดได้ แถมยัง productive กว่าที่คิด อาจเพราะมันมีแรงเสียดทานมากกว่าโน้ตบุ๊กนิดหน่อยในการสลับไปหาสิ่งรบกวนตามปกติ เลยลงเอยด้วยการจิบเบียร์ไปพลาง จ้องโค้ดต่อไปพลาง
ผมชอบของแบบนี้ ชอบสิ่งที่ทำด้วย Bash แบบน้อยที่สุด มาตลอด
ยังมี proof of concept ของ load balancer ภายในคลัสเตอร์ที่เขียนด้วย Bash 40 บรรทัด ซึ่งทำขึ้นในแฮกกาธอนที่จัดเพื่อโปรโมตอินฟราสตรัคเจอร์แบบกระจายอย่าง Docker, Mesos เมื่อประมาณ 10 ปีก่อน: https://github.com/cell-os/metal-cell/blob/master/discovery/...
น่าจะหายไปแล้ว แต่เคยมีเครื่องมือส่งต่อจาก colo-to-cloud ที่ใช้ reverse SSH tunnel ซึ่งมี redundancy และความเป็นแบบกระจายด้วย ของแบบนี้มีการรวบรวมไว้ดีใน Shell Fu และที่อื่น ๆ: https://www.shell-fu.org/
ความจริงที่ว่าส่วนใหญ่ของ Docker สามารถนำมาทำใหม่ได้ง่าย ๆ แบบนี้ คือปัญหาใหญ่ที่สุดที่บริษัท Docker เผชิญมาและยังเผชิญอยู่ เพราะโดยพื้นฐานแล้วมันใกล้เคียงกับ โค้ดกาว ที่เอาฟีเจอร์ของเคอร์เนลมาต่อเข้าด้วยกัน
จุดที่ Docker เพิ่มคุณค่าจริง ๆ ไม่ใช่แค่ Docker Hub แต่คือ Docker for Windows และ Mac ประเด็นสำคัญคือประสบการณ์แบบบูรณาการนั้นดีกว่าการต้องไปจัดการ VirtualBox กับ Vagrant เองเพื่อรัน Docker บนเครื่องพัฒนามาก
ส่วนตัวผมคิดว่าเวทมนตร์ที่แท้จริงของ Docker คือ รูปแบบอิมเมจ Docker/OCI วิธีที่มันจัดการแคชและการกระจายอิมเมจคอนเทนเนอร์ได้ยอดเยี่ยม และยังคงเป็นแกนหลักที่ทำให้เวิร์กโฟลว์แตกต่างจาก VM “ทั้งก้อน”
บน Windows ใช้ Docker ใน WSL ได้ และทำงานได้ดีมาก ผมไม่ค่อยเข้าใจว่าทำไมต้องใช้ Docker Desktop
แต่กลับไปทำ Docker Swarm แบบครึ่ง ๆ กลาง ๆ ที่ทำงานได้ไม่น่าเชื่อถือจริง ๆ แล้วก็ถูก Kubernetes แซงอย่างรวดเร็ว
วิธีที่ผมใช้มีแค่เอาสภาพแวดล้อม build เสมือนของใครสักคนมาใช้เพื่อ build ซอฟต์แวร์เมื่อหลายปีก่อนเท่านั้น
มีข้อความอย่าง “ยังไม่ได้ทำ”, “TODO”, “กำลังทำอยู่” อยู่ในรีโพ แล้วพอเห็นว่าคอมมิตล่าสุดคือหลายปีก่อนก็รู้สึกดี
ทำให้สบายใจขึ้นนิดหน่อยกับการที่ไม่กลับไปดู TODO ที่โปรยไว้ทั่วโค้ดของตัวเอง ไม่ได้จะดูถูกผู้เขียนนะ แค่รู้สึกได้รับการปลอบใจ
ถ้ารู้สึกว่า ต้องทำ เพียงเพราะโค้ดที่ไม่ได้ค่าจ้าง เป็นอาสาสมัคร หรือทำเป็นงานอดิเรกถูกเผยแพร่อยู่ การเขียนโค้ดก็จะสนุกน้อยลง และอาจทำให้โค้ดที่เดิมทีจะเปิดเผยก็ไม่ถูกเผยแพร่ด้วย
ถ้ามีไอเดียถัดไปเสมอ ตามนิยามแล้วก็ย่อมมี TODO ที่ยังทำไม่เสร็จเหลืออยู่เสมอ จริง ๆ แล้ว สภาวะปกติ ของทุกโปรเจกต์ควรเป็นแบบนั้น
การกำหนดขอบเขตให้ชัดเจนเป็นเรื่องที่โอเคเต็มที่และมักช่วยได้ เพราะจะได้ไม่ไล่ตามทางแยกย่อยจนโปรเจกต์รู้สึกเหมือน “ยังไม่เสร็จ” ไปตลอดกาล
แปลกใจที่ยังไม่มีใครพูดถึง lazydocker ว่าเป็นทางเลือกที่ยอดเยี่ยมแทน Docker Desktop ใช้ได้บน Linux/macOS/Windows [1]
เป็น เทอร์มินัล UI ที่ฟีเจอร์ค่อนข้างครบ และยังมีข้อดีที่สามารถรันผ่าน SSH ได้ด้วย
[1] https://github.com/jesseduffield/lazydocker
อย่างน้อยผมก็เพิ่งเคยเห็นแบบนี้ครั้งแรก ยังสงสัยด้วยว่าโฆษณาแบบนี้ได้รับอนุญาตตามข้อกำหนดการให้บริการหรือแนวนโยบายการใช้งานที่ยอมรับได้ของ GitHub หรือไม่
สงสัยว่าทำไม Bocker ถึงขึ้นหน้าแรกบ่อยขนาดนี้ ในปี 2024 Docker ยังเป็นประเด็นถกเถียงกันมากขนาดนั้นอยู่หรือ?
ไม่เข้าใจว่าทำไมถึงไม่ยอมรับกันว่า Docker นำสิ่งที่มีประโยชน์จริง ๆ มาให้ โดยหลักคือ การเผยแพร่ซอฟต์แวร์ และการ “รันได้ง่ายทุกที่”
Docker เป็นการผสมผสานเทคโนโลยีเคอร์เนลที่มีอยู่แล้ว ได้แก่ namespace, cgroups, ระบบไฟล์แบบ union และอาจมีอย่างอื่นอีกสองสามอย่าง
เลยน่าสนใจ และแทบจะเป็นเรื่องสไตล์ HN ที่สมบูรณ์แบบ
หลังจากสาธิตให้หลายคนดู ผมถึงเพิ่งรู้ว่าพวกเขาอาจใช้
/ตรง ๆ ก็ได้ หรือไม่ก็ผมน่าจะเอา Docker ไปให้พวกเขาใช้ก็ได้เช่นกันมีสิ่งที่เหมือนพี่น้องต่างแม่อย่าง https://bastillebsd.org/
Bastille ใช้ shell จัดการ FreeBSD jail ด้วยโครงสร้างหลายอย่างที่น่าจะเห็นได้ใน Docker มี dependency น้อยมาก เลยถูกใจมากกว่าซอฟต์แวร์จัดการ jail อื่น ๆ บน BSD
แต่แม้จะเป็นเครื่องมือแบบ CLI/TUI ก็เป็นโซลูชันที่ใกล้เคียงกับ “เกินจำเป็นขั้นสุด” ช่วงนี้ผมกำลังผ่านขั้นตอนสร้างและจัดการ jail ด้วยของที่มากับ FreeBSD ล้วน ๆ อยู่ แต่นี่เป็นแค่ช่วงชั่วคราวเท่านั้น
ผมจะทำแบบนั้นจนกว่าภาพรวมว่าทุกอย่างประกอบกันอย่างไรจะฝังอยู่ในหัวมากพอจนมั่นใจในการดีบัก จากนั้นก็จะเลิกเอาหินมาเคาะกันเหมือนคนรู้ความ แล้วกลับไปใช้เครื่องมือระดับสูงกว่า
แต่ผมใช้เวลาสักพักกว่าจะเข้าใจว่าทำไมถึงชื่อ Bastille La Bastille เป็นป้อมปราการที่สร้างขึ้นเพื่อป้องกัน Paris จากการโจมตีของอังกฤษในช่วงสงครามร้อยปี และต่อมาก็ถูกเปลี่ยนเป็นคุก
ส่วนที่ว่า “ดิสโทรส่วนใหญ่ไม่ได้ให้ util-linux เวอร์ชันใหม่พอ ดังนั้นน่าจะต้องเอาซอร์สจากที่นี่ไปคอมไพล์เอง” ต้องระวัง
prefix ติดตั้งค่าเริ่มต้นคือ
/usr/binดังนั้นกระบวนการติดตั้งอาจเขียนทับ คำสั่ง mount เดิมด้วยเวอร์ชันที่ต้องการไลบรารีซึ่งไม่มีอยู่จริงได้ แล้วตอนบูตครั้งถัดไป เคอร์เนลจะเมานต์ระบบไฟล์เป็นแบบอ่านอย่างเดียว/usr/local/binไม่เหมาะสำหรับใช้ประจำวัน แต่ช่วยให้เห็นภาพว่า Docker คืออะไรและทำงานอย่างไร
บน Linux นั้น Docker โดยพื้นฐานแล้วคือ chroot ที่แต่งตัวหรู
เกร็ดน่าสนใจ: Docker เริ่มต้นด้วย Bash แล้วต่อมาย้ายไป Python ก่อนจะลงเอยที่ Go
อีกอย่าง ในงาน Docker meetup ปี 2013 ก็มีคนเขียน โคลน Docker ด้วย Bash ด้วย ผู้คนอยากเรียนรู้ และหวังว่าสิ่งเหล่านี้จะช่วยได้