告別 Docker Desktop 束縛!macOS 容器實戰:colima + k8s + containerd 踩坑遷移全記錄

告別 Docker Desktop 束縛!macOS 容器實戰:colima + k8s + containerd 踩坑遷移全記錄

前言 身為一個開發者,特別是在 macOS 環境下,Docker Desktop 幾乎是容器化開發的標配。然而,自從 Docker Desktop 開始針對大型企業調整其授權模式後,許多開發者開始尋找替代方案。 市面上確實出現了一些選擇,例如閉源但功能強大的 OrbStack。但對於熱愛開源的我來說,目光自然投向了社群。這時,colima 這個開源專案進入了我的視野。它不僅提供了一個在 macOS 上運行 Linux 容器的輕量級方式,還內建了 Kubernetes 支援,引起了我極大的興趣。 這篇文章,想記錄一下我從 Docker Desktop 轉換到 colima,並且在 colima 的 Kubernetes 環境中,從原本依賴 Docker Engine 逐步遷移到使用 containerd 作為容器執行時(Container Runtime)的心路歷程與踩坑經驗。 lima 與 colima 簡介 在深入 colima 之前,得先提一下 lima (Linux virtual machines on macOS)。lima 是一個旨在於 macOS 上輕鬆運行 Linux 虛擬機的開源專案。它底層利用了 macOS 的虛擬化框架(如 QEMU 或更高效的 vz),提供了一個相對輕量的 Linux VM 環境。 而 colima 則可以看作是建立在 lima 之上的「使用者友善層」。它簡化了 lima 的配置,並專注於提供容器執行時環境。colima 可以讓你輕鬆地啟動一個配置好 Docker 或 containerd 的 Linux VM,並且可以選擇性地啟用 Kubernetes (K3s) 支援。簡單來說,colima 幫你處理了建立 VM、安裝 Runtime 等繁瑣步驟,讓你專注在容器本身。...

2025-04-19 · 6 min · 1096 words
建構多平台的 container image

建構多平台的 container image

前言 最近在搞 side project 時,常常需要在不同的 CPU 架構上跑我的應用程式。例如,開發用的 MacBook 是 ARM 架構 (Apple Silicon),開發用的 Desktop 是 x86 架構(Ryzen 5900X),而部署的伺服器可能是 x86 (AMD64),有時候甚至想在 Raspberry Pi (ARM) 上跑些小東西。每次都要為不同平台分別建構 image 實在有點麻煩,而且 Registry 上一堆 xxxapp-amd64, xxxapp-arm64 的 tag 看了也很礙眼。經過一番研究與嘗試,是時候接觸 Docker Buildx 了。 為什麼需要多平台映像檔 在 wintel 的商業策略下,以及大家對高性能伺服器的普遍認知,主要用 x86/amd64,但現在 ARM 架構越來越普及,從 Apple Silicon 的 Mac、AWS Graviton 處理器、各種 IoT 設備到你的 Raspberry Pi,ARM 無所不在。如果你的 container image 只支援 amd64,那它就無法在這些 ARM 設備上原生運行 (需要模擬,效能差)。為了Build Once, Run Anywhere,多平台映像檔 (Multi-platform images) 就是 meta。 OCI 多平台映像檔架構簡述 其實不複雜。傳統的單一平台 image,它的 manifest 指向一組設定檔和一堆 layer。而多平台 image 則是透過一個 manifest list (索引) 指向多個特定平台的 manifest。每個特定平台的 manifest 才各自指向該平台的設定檔和 layer。...

2025-03-30 · 12 min · 2404 words
Never Install Locally?試試 Dev Container

Never Install Locally?試試 Dev Container

最近換了新工作,到了一間資訊安全公司,讓我更加重視開發環境的安全。 還記得之前分享過透過 Distrobox 解決 Linux 環境依賴問題,用他來解決不同 Linux distribution 的依賴關係,背後即是讓程式跑在 container 內。 既然能夠將應用程式一來透過 container,與 Host OS 本身做出區隔,那麼我們也能透過 container 來對開發的依賴做出隔離。於是,開始擁抱 Dev Container,一個能讓我更安心、更有效率(?)的開發環境。 什麼是 Dev Container? 簡單來說,Dev Container 就是把開發環境「容器化」。我們可以把所有需要的工具、函式庫、設定檔都放在一個 Docker Image 裡,然後用這個 Image 啟動一個 Container 作為你的開發環境。 Consistency (一致性): 不管是在哪台機器上開發,只要有 Docker,就能保證開發環境完全一致。再也不用擔心「在我這台電腦上可以跑啊!」這種崩潰的狀況發生。 Isolation (隔離性): Dev Container 與本機系統完全隔離,可以避免各種依賴衝突,也能保護系統安全。 Reproducibility (可重現性): 透過 Dockerfile,你可以完整記錄你的開發環境設定,方便團隊協作和版本控制。 為什麼需要 Dev Container? 身為一個資安從業人員,Dev Container 解決了以下痛點: 不同版本的 Node 環境,告別 nvm!需要 node14, node16, node18 或是 stable 版本,隨時產生開發環境。 需要下載 malware 到本地進行 e2e 測試,透過 container 進行蛤蜊(🦪意象),盡可能避免破壞系統安全性。 在 macOS 上解決一些只支援 linux 的 binary,或是在 arm64 host 上透過 rosetta2 模擬 x86_64 環境,進而執行 amd64 執行檔。 使用 rootless 模式,在危機四伏的 npm 環境中,確保開發環境的安全性。 我的 Dev Container 工作流 我將 dev-container 放在 github omegaatt36/lab/dev-container 中,以下 demo 僅「目前版本」,會依據使用情境進行迭代。...

2025-03-01 · 4 min · 674 words

如何不啟動 container 從 image 中提取可執行檔

::: info 雖然文章內大多指令都是使用 docker,但由於是標準的 OCI image,使用 Podman 也是一樣的效果。 ::: 某段時間內,我會將所有需要執行的 binary 使用 containerize 給打包起來執行,例如: 需要將前端環境給跑起來,我會啟動一個 node 環境的 container: docker run --rm -it --name f2e --net=host -v $(pwd):/app \ docker.io/library/node:20-bookworm \ bash 需要安裝某個基於 golang 的 cli 工具,會使用自己寫的腳本,在 container 內進行建構。 需要透過 Liquibase 來進行 db migration,並不會選擇在本地安裝 maven 環境,一樣是啟動一個 container 來執行。 這麼做的好處是,「目前」大多數的 server/cli tools 至少會編譯 x86 架構下的可執行檔,我只需要確保 container 環境內可以工作,就可以在不同硬體的開發環境下游走。極度偏激的來說,無法確保安裝的 binary 有沒有受過污染,無論開源或閉源與否,也可以透過 Podman 來啟動 rootless 的 container 確保本機的安全。 但有時候會遇到別人打包的 image 十分肥大,即便程式可執行檔只需要幾 MB,編譯後的 image 確有幾百 MB(大多數是腳本語言),蒙生了從 image 中提取 executable 的想法,藉此也學習 docker layer 間的關係。...

2024-04-14 · 4 min · 806 words

Logitech Media Server 遷移紀錄:從 Bare Metal 到 Docker 再到 Podman

2021 年公司開始實施 322 WFH,少了通勤的時間,在家的時間也多了,就想在上班時也能好好對待自己,雖然是木耳但始終會想知道,網路上說的獨立訊源減少雜訊是有多重要,亦或只是玄學?於是誕生了Raspberry pi 4 + piCorePlayer 7.0.0 折騰筆記這篇筆記,到現在這個部落格的累積曝光最高的也是因為這篇吧。 雖然說現在已經出到 8.2.0,但也已經是 2022 年六月的版本了,起初因為 raspberry pi 4b 便宜而使用 piCorePlayer,後來也因 raspberry pi 4b 漲價(漲幅超過 100%)進而不使用 piCorePlayer,不知道官方後來沒更新了是因為樹莓派太穩定,還是真的太貴了…。 從 Bare Metal 到 Docker 當時在學習 HomeLab,首先是從 portainer 開始玩,也因此誕生了 logitech media server 搭配 docker 實現雙機分離。後來也用著同樣的 image 將 lms 建在 k8s cluster 內,遇到的比較髒的問題是 nginx 的 port 用非正式的方式解決。 這時候其實已經不在乎 logitech media server 是否帶來更好的音質了,也沒有連動 NAS 的音樂,主要是使用 Youtube Plugin 播放 Youtube 上的內容(即便有訂閱 Youtube Premium)。以及使用 Podcast Plugin 收聽 podcast。 使用 docker 的好處不外乎一個字,省,於是我把 raspberry pi 4b 也給賣了。...

2023-02-24 · 2 min · 231 words

logitech media server 搭配 docker 實現雙機分離

前言 雖然官方 releases 頁面似乎還沒發布,不過前一陣子把 piCorePlayer 升級到 8.1.0,看起來似乎還是 unstable,懶得倒版回去 8.0.0,趁這個機會把一直想玩的雙機留兜起來。 雙機顧名思義為 client 與 server 分開在兩台機器上,piCorePlayer 的 client 為 Squeezelite,server 則為 Logitech Media Server,事實上在 windows 上也有 client Squeezelite-X可以玩,預期中的最終成品將會是「三機流」吧 XD LMS 解決方案 採用 lms community 的 docker image lmscommunity/logitechmediaserver 作為這次 server 端的 service。 安裝流程 此篇文章使用 portainer 作為 GUI 方便演示,若熟悉 docker 與 k8s 的可以自行下指令安裝。 首先我把我的音樂都存放在 NAS 上,先將 music 資料夾給共享出來 接著到 portainer 中建立三個 volume a. lms-music 輸入在 NAS 分享出來的目錄與使用者、密碼,建立一個 cifs mounted volume b. lms-config c. lms-playlist 接著到 stack 中,複製貼上官方的 docker-compose,若 portainer 已經佔用了 port 9000,則需要更改暴露的 port port:port/tcp 並追加環境變數 HTTP_PORT=port,我最終的 stack 設定為: lms: image: lmscommunity/logitechmediaserver volumes: - lms-config:/config:rw - lms-music:/music:ro - lms-playlist:/playlist:rw - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro ports: - 9002:9002/tcp - 9090:9090/tcp - 3483:3483/tcp - 3483:3483/udp environment: - HTTP_PORT=9002 restart: always 點下 Deploy the stack 後就完成了 可以到 container 下看是否已經啟動完成了,並稍微記一下 container 的 hash,在稍後 windows 的設定中會出現。 piCorePlayer 設定 進入到 piCorePlayer web 中的 Squeezelite Settings 設定頁面,並在 LMS IP 中輸入 portainer 的 ip 位置後點擊 Save,大功告成。 接著到 portainer_id:9002 中就可以看到 lms 的畫面了 Squeezelite-X 設定 windows 中的 Squeezelite 設定更為簡單,到 Microsoft Store 取得並安裝 Squeezelite-X後打開,整個 logitech media service 似乎已經整合好 service discovery 了,直接在設定頁中的 Host 中看到剛剛起好的 docker container name 結語 lms 社群看起來還是有很多人在維護,設定起來十分簡單,數位流追求的就是方便...

2021-12-04 · 1 min · 199 words