Skip to main content

ครั้งแรกกับการใช้งาน Docker บน Apple Silicon M1 และสิ่งที่คุณควรรู้

Kongvut Sangkla

Intro

สวัสดีครับ บทความนี้จะเล่าถึง Docker กับ Chip M1 โดย Docker เป็น Develop tools ที่ผมใช้งานประจำ และเมื่อได้รับเครื่องที่ใช้ Apple silicon ก็ตื่นเต้นมากที่จะได้ลองใช้กับ Docker

แนะนำให้อ่านบทความนี้ร่วม ว่าทำไมได้เครื่องใหม่มาทำไมถึงดูวุ่นวายกว่าเดิมกับ M1 "วิธีติดตั้ง Node.js บนเครื่องที่ใช้ CPU Apple Silicon M1" ที่มีการเปลี่ยนไปใช้สถาปัตยกรรมที่เป็น ARM ทำให้พบการใช้ Docker ที่ต่างจากเดิมที่เคยใช้งาน ดังนั้นจึงขอมาเขียนบันทึกไว้สักหน่อยครับ 😊

img

พูดถึง 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 binary
    • docker-credential-ecr-login ที่เป็น Credential helper
  • ต้องเข้าใจว่าไม่ใช่ 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

Imgur

ตามปกติ 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

ตัวอย่างบน Dockerfile
FROM --platform=linux/amd64 php:8.1.0-fpm-buster
ตัวอย่างบน docker-compose.yml
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 เพื่อแก้ปัญหาเองให้รองรับได้ในอนาคต

References

Loading...