Mac上Docker的使用
至於圖形化的介面完全不需要, 我們並不指望圖形化介面能比敲 快到哪裡去, 也不指望圖形化介面變為主力; 所以本篇文章的核心目標:
- 在 Mac 上使用完整的 docker cli 命令, 包括對基本的 -v 掛載支援
- 可以支援 x86 的模擬, 可以為 x86 build 或者執行相關映象
- 在儘可能的情況下可以進行 CPU 架構切換, arm64 與 x86 最好都可以支援
首先是我們最熟悉的 Docker Desktop, 安裝包奇大無比, UI 卡成翔, 啟動速度更不用提而且還時不時的卡死, 所以 Docker Desktop 是完全不考慮的; 那麼剩下幾種方案型別如下:
- VM 虛擬機器方案
- Colima 方案
- Lima 方案
先說結論: Lima YES! VM 虛擬機器方案要花錢且難受, Colima 暫且不穩定. Lima 方案直接看第五節.
目前在 M1 上, 唯一可用或者說堪用的虛擬機器當屬 Parallels Desktop, 至於其他的 VBox、VMware 目前還不成熟; 如果純 qemu 有點過於硬核(願意自己封裝 的當我沒說); 對於 Parallels Desktop 來說, 我們需要購買開發版本的 License, 因為我們需要藉助 prlctl 來實現一些自動化 , 一年好幾百… 經過測試這種方案也有一定可行性:
- 1、首先透過 PD 建立 Ubuntu 之類的虛擬機器
- 2、在虛擬機器裡安裝好 Docker
- 3、透過 cli 程式啟動虛擬機器, 並且將 ~ rw 掛載到虛擬機器裡
基於這個方案我個人嘗試過, 曾經寫過一個 PD 的小工具來輔助完成掛載動作. 但是這種工具有一些明顯的缺點:
目前不支援 x86 的模擬, 可透過 binfmt 緩解, 但是不完善。虛擬機器要花錢且需要虛擬機器 cli 支援完善
Colima 號稱是專門為了解決 Mac 平臺容器化工具鏈的, 但是實際測試發現目前 Colima 還不算穩定, 有時可能會有一些小問題; 當然 Colima 最大的問題是: 可自定義化程度不高, 底層基於 Lima. Colima 具體的使用方式啥的這裡暫不詳細描述, 目前還不穩定不太推薦.
Lima 目前是基於 QEMU 的自動化 VM 方案, 當前由於其出色設計, 藉助 Cloud Init 可以在很多階段幫助我們完成 hook; 所以不論是裝個 Docker 還是 k8s, 亦或是弄個其他的東西都很方便; 而且很多方案比如 docker 官方都有相關樣例, 我們可以直接照抄外加做點自定義.
Lima 在 Mac 下安裝相對簡單, 以下命令將安裝 master 分支版本.
brew install lima --HEADCopy
在正常情況下, 安裝 Lima 會附帶安裝 QEMU, 如果本機已經安裝 QEMU, 可能需要執行以下命令將 QEMU 升級到 7.0:
brew upgrade qemuCopy
為了使用 docker, 還需要透過 brew 安裝一下 docker cli:
brew install dockerCopy
預設情況下 Lima 安裝完成後會生成一個 lima 的快捷命令, 目前不太推薦使用, 原因是看起來方便一點但是沒法控制太多引數, 所以仍然建議使用標準的 limactl 命令進行操作. limactl 使用方式如下:
Lima: Linux virtual machines Usage: limactl [command] Examples: Start the default instance: $ limactl start Open a shell: $ lima Run a container: $ lima nerdctl run -d --name nginx -p 8080:80 nginx:alpine Stop the default instance: $ limactl stop See also example YAMLs: /opt/homebrew/share/doc/lima/examples Available Commands: completion Generate the autocompletion script for the specified shell copy Copy files between host and guest delete Delete an instance of Lima. edit Edit an instance of Lima factory-reset Factory reset an instance of Lima help Help about any command info Show diagnostic information list List instances of Lima. prune Prune garbage objects shell Execute shell in Lima show-ssh Show the ssh command line start Start an instance of Lima stop Stop an instance sudoers Generate /etc/sudoers.d/lima file for enabling vmnet.framework support validate Validate YAML files Flags: --debug debug mode -h, --help help for limactl -v, --version version for limactl Use "limactl [command] --help" for more information about a command.Copy
Lima 透過讀取一個 yaml 配置描述檔案來決定如何建立一個虛擬機器, 該檔案基本結構如下:
# 定義每個平臺架構需要使用的啟動映象 images: - location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img" arch: "x86_64" - location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-arm64.img" arch: "aarch64" # 定義虛擬機器需要使用哪個架構啟動(對應上面的映象) arch: "x86_64" # CPU 數量 cpus: 4 # 記憶體大小 memory: "16G" # 磁碟大小 disk: "100G" # 虛擬機器與 macOS 宿主機掛載時使用的掛載技術 # 目前推薦 9p, 可換成 sshfs, 但是 sshfs 會有許可權問題 mountType: 9p # 定義虛擬機器和 macOS 宿主機有哪些目錄可以共享 mounts: - location: "~" # 定義虛擬機器對這個目錄是否可寫 writable: true 9p: # 對於可寫的共享目錄, cache 推薦型別為 mmap, 不寫好像預設 fscache cache: "mmap" - location: "/tmp/lima" writable: true 9p: cache: "mmap" # containerd is managed by Docker, not by Lima, so the values are set to false here. containerd: system: false user: false # cloud-init hook 定義 provision: # 定義以什麼許可權在虛擬機器內執行指令碼- mode: system # This script defines the host.docker.internal hostname when hostResolver is disabled. # It is also needed for lima 0.8.2 and earlier, which does not support hostResolver.hosts. # Names defined in /etc/hosts inside the VM are not resolved inside containers when # using the hostResolver; use hostResolver.hosts instead (requires lima 0.8.3 or later). script: | #!/bin/sh sed -i 's/host.lima.internal.*/host.lima.internal host.docker.internal/' /etc/hosts - mode: system script: | #!/bin/bash set -eux -o pipefail if command -v docker >/dev/null 2>&1; then docker run --platform=linux/amd64 --privileged --rm tonistiigi/binfmt --install all exit 0 else export DEBIAN_FRONTEND=noninteractive curl -fsSL | sh docker run --platform=linux/amd64 --privileged --rm tonistiigi/binfmt --install all # NOTE: you may remove the lines below, if you prefer to use rootful docker, not rootless systemctl disable --now docker apt-get install -y uidmap dbus-user-session fi - mode: user script: | #!/bin/bash set -eux -o pipefail systemctl --user start dbus dockerd-rootless-setuptool.sh install docker context use rootless probes: - script: | #!/bin/bash set -eux -o pipefail if ! timeout 30s bash -c "until command -v docker >/dev/null 2>&1; do sleep 3; done"; then echo >&2 "docker is not installed yet" exit 1 fi if ! timeout 30s bash -c "until pgrep rootlesskit; do sleep 3; done"; then echo >&2 "rootlesskit (used by rootless docker) is not running" exit 1 fi hint: See "/var/log/cloud-init-output.log". in the guest hostResolver: # hostResolver.hosts requires lima 0.8.3 or later. Names defined here will also # resolve inside containers, and not just inside the VM itself. hosts: host.docker.internal: host.lima.internal portForwards: - guestSocket: "/run/user/{{.UID}}/docker.sock" hostSocket: "{{.Dir}}/sock/docker.sock" # 自己定義的啟動後訊息輸出 message: | To run `docker` on the host (assumes docker-cli is installed), run the following commands: ------ docker context create amd64 --docker "host=unix://{{.Dir}}/sock/docker.sock" docker context use amd64 ------
limactl 命令提供了一個 start 子命令用於啟動一個虛擬機器, 子命令接受一個引數, 這個引數形式不同會產生不同的行為:
- 如果引數為一個檔案路徑, 則假定檔案為一個 lima 虛擬機器的 yaml 配置, 讀取並啟動
- 如果引數是單純字串, 首先嚐試從已存在的虛擬機器中查詢名字相同的, 找到則立即啟動
- 如果引數是單純字串, 且未找到已存在同名的虛擬機器, 則嘗試透過內建模版來建立一個新的虛擬機器
以上面我自己定義的 docker 配置檔案為例, 我們直接啟動這個配置既可以建立一個 docker 虛擬機器:
limactl start ./docker-amd64.yamlCopy
啟動後會提示是否編輯然後再啟動, 這是為了使用同一個配置來啟動多個 vm 使用的, 所以不編輯直接啟動即可:
稍等片刻後虛擬機器將啟動成功:
啟動完成後, 執行最下面列印出的兩條命令, 即可在宿主機上完整的使用 docker. 其本質上利用 docker context 功能, 然後透過將虛擬機器中的 sock 檔案掛載到宿主機, 並配置 docker context 來實現無縫使用 docker 命令.
某些情況下, 我們需要定製一些 VM 裡的配置, 在定製時主要需要調整配置檔案的 provision 部分; 在該部分中, 如果 mode 被定義為 system 則會以 root 使用者執行相關命令, 否則以普通使用者來執行命令. 需要注意的是, 我們定義的指令碼需要具有冪等性, 因為指令碼在每次都會執行一次, 所以一般對於可能造成資料擦除動作的命令都要寫好判斷邏輯, 避免重複執行.
關於檔案掛載, 這裡推薦使用 9p 型別, 未來 lima 將完全切換到該掛載方式; 同時經過測試目前僅有 9p 掛載模式下, 本地目錄 rw 對映到虛擬機器時不會出現許可權問題, sshfs 方式掛載如果遇到 chown 之類的命令會造成許可權錯誤, 可能導致容器啟動失敗(例如 mysql).
在測試虛擬機器配置過程中, 可以直接使用 limactl delete -f xxxx 來強制刪除目標虛擬機器, 然後重新啟動即可; 虛擬機器名稱預設與 yaml 檔名相同, 可使用 limactl ls 命令檢視.
在上面我的 docker 配置樣例中, 每次虛擬機器啟動完成後會自動安裝 binfmt:
docker run --platform=linux/amd64 --privileged --rm tonistiigi/binfmt --install allCopy
這樣能保證無論 Lima 虛擬機器原始架構是什麼, 都能執行其他平臺的 docker 映象; 典型的例如某些 openjdk8 映象只有 amd64 的版本, 但是在 lima 虛擬機器為 aarch64 的情況下仍然可以使用.
除了這種 “速度較快” 的跨架構執行方式, lima 還支援直接在 VM 中定義架構, 這樣在 qemu 啟動時則會直接從 VM 系統層模擬目標架構; 這種方式的好處是對目標架構相容性很好, 但是執行速度會更慢. 調整 VM 架構只需要修改 arch 配置即可(注意, 目標架構的映象一定要配置好):
# 定義每個平臺架構需要使用的啟動映象 images: - location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img" arch: "x86_64" - location: "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-arm64.img" arch: "aarch64" # 定義本虛擬機器需要使用哪個架構啟動(對應會使用上面目標架構的映象) arch: "aarch64"Copy
目前整體來看, Docker Desktop 在 mac 上基本上是很難用的, Colima 現在還不太成熟, 適合輕度使用 docker 的使用者; 而重度使用 docker 並且有定製化需求的使用者還是推薦 Lima 虛擬機器; 同時 Lima 也支援很多作業系統, 官方有大量的樣例模版(包括 k8s、k3s、podman 等), 非常適合重度容器使用者。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2902552/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何在Mac上使用DockerMacDocker
- 在mac上安裝DockerMacDocker
- mac上brew使用Mac
- 在FreeBSD上使用DockerDocker
- Mac上使用Docker Desktop啟動Kubernetes,踩坑後才搞定MacDocker
- 在 Mac 上使用 JavaMacJava
- 開始在 CentOS 上使用 dockerCentOSDocker
- 【Mac】Docker安裝及基礎使用MacDocker
- Docker 教程:在 Mac M2 上執行 PostgreSQLDockerMacSQL
- 使用Travis在Docker Hub上管理開源Docker映象Docker
- 在 Azure 上使用 Docker 執行 MonoDockerMono
- Mac下使用Docker開啟KubernetesMacDocker
- 「mac使用技巧」mac上修復丟失滑鼠?Mac
- 如何在Mac上使用“接力”功能?Mac
- 在Mac 上如何使用替代文字?Mac
- mac上SVN使用技巧和感受Mac
- 如何在 Ubuntu 上使用 Grafana 監控 DockerUbuntuGrafanaDocker
- CentOS7上安裝和使用DockerCentOSDocker
- 在 Linux 上安裝和使用 DockerLinuxDocker
- Laravel 如何使用 Docker 快速架起 Echo Server(上)LaravelDockerServer
- 不借助 Docker Desktop 在Mac上開發容器應用DockerMac
- Docker的使用Docker
- 什麼是Homebrew和在Mac上的怎麼使用?Mac
- mac系統上hdfs java api的簡單使用MacJavaAPI
- mac 上使用OpenSSL 生成RSA證書Mac
- 如何在Mac上使用表情符號Mac符號
- 如何在 Mac 上使用 Ctrl + Alt + Delete?Macdelete
- 如何在Mac上使用螢幕共享Mac
- MAC上iTerm 2安裝與使用Mac
- 在ubuntu上安裝docker, 使用國內的安裝源UbuntuDocker
- Mac 安裝執行 Docker for MacMacDocker
- mac基礎操作:在Mac上怎麼使用夜覽Mac
- Mac 使用 docker 搭建 kafka 叢集 + Zookeeper + kafka-managerMacDockerKafka
- Docker-OSX:在Docker中執行你的蘋果Mac!Docker蘋果Mac
- 使用 docker-sync 解決 docker for Mac 啟動的虛擬容器程式執行緩慢的問題DockerMac
- Mac使用技巧:怎樣在Mac電腦上更改密碼Mac密碼
- Docker Desktop 現在可以在 Linux 上使用DockerLinux
- 如何給Docker hub使用者上傳頭像Docker