ครั้งแรกกับการใช้งาน Docker บน Apple Silicon M1 และสิ่งที่คุณควรรู้
Table of contents
Intro
สวัสดีครับ บทความนี้จะเล่าถึง Docker กับ Chip M1 โดย Docker เป็น Develop tools ที่ผมใช้งานประจำ และเมื่อได้รับเครื่องที่ใช้ Apple silicon ก็ตื่นเต้นมากที่จะได้ลองใช้กับ Docker
แนะนำให้อ่านบทความนี้ร่วม ว่าทำไมได้เครื่องใหม่มาทำไมถึงดูวุ่นวายกว่าเดิมกับ M1 "วิธีติดตั้ง Node.js บนเครื่องที่ใช้ CPU Apple Silicon M1" ที่มีการเปลี่ยนไปใช้สถาปัตยกรรมที่เป็น ARM ทำให้พบการใช้ Docker ที่ต่างจากเดิมที่เคยใช้งาน ดังนั้นจึงขอมาเขียนบันทึกไว้สักหน่อยครับ 😊
พูดถึง Docker Desktop สำหรับ Apple silicon
Docker Desktop for Mac บน Apple silicon ตอนนี้ก็ได้ออกตัวจริงและพร้อมใช้งานแล้ว ทำให้สามารถใช้สำหรับการพัฒนา Applications ในตัวเลือกสภาพแวดล้อมที่เป็นแบบ Development หรือจะเป็นแบบ Development pipelines บนสถาปัตยกรรม ARM ได้
Docker Desktop สำหรับ Apple silicon นั้นได้รองรับการทำงานแบบ multi-platform images โดยที่อนุญาตให้ Build หรือ รัน Images ได้ทั้งสองแบบทั้ง x86
และ arm64
โดยไม่ต้องมีขั้นตอนการตั้งค่าที่ซับซ้อนของพวก Cross development environments อีกทั้งคุณสามารถใช้คำสั่ง docker buildx สำหรับการ Build แบบ multi-platform และใช้ Docker Hub เพื่อใช้ระบุ Platform และ แชร์ Repositories สำหรับ multi-platform ของ Docker images
ความต้องการของระบบ
ใน Docker Desktop 4.3.0 ไม่ได้บังคับให้ติดตั้ง Rosetta 2 โดยให้เป็นตัวเลือกคำสั่งติดตั้งเองถ้ามีการใช้พวก Darwin/AMD64
เดี๋ยวจะเล่าถึงปัญหาของการใช้งานในหัวข้อต่อไป
ถึงแม้ว่าจะได้รับประสบการ ณ์ใช้งานที่ดีที่สุดแล้ว แต่ทาง Docker ก็แนะนำให้ติดตั้ง Rosetta 2 โดยคำสั่งสำหรับวิธีการติดตั้งแบบ Manual บน Terminal คือ:
softwareupdate --install-rosetta
ปัญหาตอนนี้ที่พบบน Docker สำหรับ Apple silicon
-
บางคำสั่ง Command line tools จะไม่สาม ารถทำงานได้เมื่อไม่ได้ติดตั้ง Rosetta 2
- ใน Version 1.x (เก่า)
docker-compose
ทาง Docker แนะนำให้ใช้ Compose V2 แทน ด้วยการพิมพ์คำสั่งdocker compose
แทน หรือไปเปิดการใช้งานได้ที่เมนู General preferences tab docker scan
ของsnyk
binarydocker-credential-ecr-login
ที่เป็น Credential helper
- ใน Version 1.x (เก่า)
-
ต้องเข้าใจว่าไม่ใช่ Images ทั้งหมดที่จะสามารถใช้กับ
arm64
architecture ได้โดยที่คุณสามารถเพิ่มคำสั่ง--platform linux/amd64
(ดูในหัวข้อตัวอย่าง) สำหรับการรัน Intel image ที่เป็นx86
โดยเฉพาะอย่างยิ่งเช่น MySQL image นั้นตอนนี้ไม่รองรับarm64
แต่คุณก็สามารถแก้ปัญหานี้ด้วยการใช้ MariaDB image แทนแม้ว่าคุณจะพยายามรัน Containers ด้วย Intel-based บน Apple silicon แต่บางครั้งก็สามารถเกิดการ Crash หรือ Fails ได้ที่จะรัน Container อีกทั้งในส่วนของ Filesystem ได้เปลี่ยน Notifications APIs (inotify) ที่ทำให้ไม่สามารถใช้งานภายใต้ qemu emulation ได้ และแม้ว่าตอนที่สามารถรัน Containers ได้แล้วแบบที่ไม่ Fails แต่มันก็อาจจะช้าลง และมีการใช้หน่วยความจำเยอะมากกว่าที่เป็นแบบ Native
สรุปคือ ตอนที่รัน Containers ด้วย Intel-based คุณควรเข้าใจด้วยว่า Docker "ความพยายามอย่างดีที่สุด" แล้ว ดังนั้นแนะนำให้รัน Containers แบบ
arm64
ดีกว่าถ้าเป็นไปได้ และให้พยายามหา Image ที่รองรับarm64
หรือเป็นแบบ multi-arch โดยทาง Docker ก็คาดหวังว่าปัญหาเหล่านี้จะลดน้อยลงในอนาคต และจะมี Images ที่รองรับหลายสถาปัตยกรรมมากขึ้นในอนาคต (supporting multiple architectures) -
คำสั่ง
ping
ใน Container สำหรับติดต่อ Internet จะไม่สามารถทำงานได้ตามที่คาดหวัง สำหรับการทดสอบ Network ทาง Docker ได้แนะนำให้ใช้คำสั่งcurl
หรือwget
แทน ดูรายละเอียดที่นี่ docker/for-mac#5322 -
คุณอาจจะเจอปัญหาเป็นครั้งคราวเกี่ยวกับ data drop เมื่อ TCP stream เกิด half-closed
ตัวอย่างการใช้งาน
การใช้งาน Image แบบ arm64
ตามปกติ Docker บน Apple Silicon เวลาเราสั่ง pull image ซึ่ง Docker ก็จะ pull image ที่เป็นแบบ arm64
ให้แบบ Default เลย
โดยที่เมื่อเราจะใช้ Image ใด ๆ เราสามารถค้นหาก่อนว่า Image นั้นรองรับ arm64
หรือไม่บน Docker Hub ดังรูปภาพ
การใช้งาน Image แบบ x86
Images ส่วนใหญ่บน Docker Hub รองรับ x86
อยู่แล้วแต่ตามคำแนะนำสำหรับการใช้งานบน Apple silicon นั้นก็แนะนำให้ใช้ arm64
มากกว่า x86
เพื่อประสิทธิภาพที่ดีกว่า ดังนั้นการใช้ Image ที่เป็น x86
ควรใช้เท่าที่จำเป็นเท่านั้นถึงจะดีที่สุดด้วยการเพิ่มคำสั่งแบบตัวอย่างดังนี้
เพิ่มคำสั่ง --platform=linux/amd64
สำหรับ Image ของ PHP
FROM --platform=linux/amd64 php:8.1.0-fpm-buster
services:
frontend:
platform: linux/amd64
build: frontend
ports:
- 80:80
depends_on:
- backend
backend:
platform: linux/amd64
build: backend
สรุป
จากการทดลอง Build Dockerfile ของพวก Image ที่เป็นแบบ arm64
พบว่า Build เร็วมาก ๆ และ Images ชื่อดังส่วนใหญ่ที่อยู่บน Docker Hub นั้นก็รองรับ arm64
แทบทุกตัว แล้วตัวไหนที่ Build ด้วย arm64
ผ่านสำเร็จผมแทบร้องเย้ออกมาเลย 5555 😄 🎉 เพราะอยากให้เป็นการทำงานแบบ Native บน Apple silicon ที่ให้ประสิทภาพดีกว่าอยู่แล้ว
แต่จากประสบการณ์ส่วนตัวที่ได้ทดลองแล้วแม้ว่า Image ที่เราใช้เป็น arm64
แล้วก็ตาม และบางครั้งเราจำเป็นต้องเขียน Dockerfile เพิ่มทำให้บาง Packages ที่ต้อง Compile เองมีปัญหาไม่รองรับ arm64
ดังนั้นก็เลยทำให้ต้องมาเพิ่มคำสั่ง --platform linux/amd64
ที่ Image อยู่ดี ซึ่งทำให้ไม่ได้รับ Image แบบ arm64
ที่ทำงานเป็น Native สรุปก็แย่อยู่ดี เฮ้ออออ 😌
อาจจะเพราะตอนนี้ arm64
ยังใหม่ และรองรับได้เท่าที่มี ที่จริงตอนนี้ Images arm64
ก็มีเพียงพอสำหรับการใช้ทั่ว ๆ ไปแล้ว แต่ถ้าต้องการ Customize กั บ Dockerfile เองที่ต้องใช้ท่ายากเยอะ ๆ ต้องรออีกสักพัก (พักยาว ๆ) และเราเองต้องตามขยันอัปเดทการแก้ปัญหาพวก Issues บาง Packages (จากผู้พัฒนาโดยตรง หรือบน Github) ที่มีปัญหากับ arm64
เพื่อแก้ปัญหาเองให้รองรับได้ในอนาคต