Lima
Lima 是一個 MacOS 上的 Docker Desktop 開源解決方案。
環境安裝
使用 Homebrew 安裝:
brew install lima
接著使用 limactl
指令啟動預配置好的 Linux 虛擬機:
$ limactl start
? Creating an instance "default" [Use arrows to move, type to filter]
> Proceed with the default configuration
Open an editor to override the configuration
Exit
這裡會詢問是否要調整設定,可以直接使用預設配置懶人包即可。接著 lima 會下載虛擬機的映像檔並啟動,會花點時間,等完成後,即可使用 lima
指令對虛擬機操作。
lima
指令是別名,它等同於 limactl shell default
。預設的懶人包是使用 containerd + nerdctl
來管理容器,指令是使用 nerdctl
,完整的指令如下:
$ lima nerdctl ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
nerdctl
指令官方說明是 Docker-compatible CLI
,包括 Docker Compose 也有實作,理想上,可以設定下面這兩個別名:
alias docker="lima nerdctl"
alias docker-compose="lima nerdctl compose"
以下為了區分與 Docker 指令的不同,會採用原始指令。
啟動服務
來啟動 Hello world container 和起 Nginx 服務試試:
# Hello World,可以看到下載的進度表完全不一樣,這是 nerdctl 的介面
lima nerdctl run --rm -it hello-world
# 啟動 Nginx 服務並開 8080 port
lima nerdctl run -d -p 8080:80 nginx:alpine
# 測試是否可從 localhost 存取到 Nginx
curl http://localhost:8080
替換設定檔
官方有提供幾個預設設定範例檔可以直接套用,包含 Linux 發行版和 container engine 都可以更換。
目前使用經驗上,nerdctl
在 Docker Compose 的相容度還是有待改善,因此直接使用 Docker 作為 container engine 踩的雷會比較少一點:
# 下載官方的範例檔
curl -o docker.yaml https://raw.githubusercontent.com/lima-vm/lima/master/examples/docker.yaml
# 依 yaml 檔啟動虛擬機,並取名為 docker
limactl start docker.yaml
預設虛擬機已裝好 Docker,但沒有裝 Docker Compose,參考官方文件,使用下面指令安裝:
注意:官方提供的 artifacts 環境與版本,如果沒有找到的話會下載失敗,這時就會需要自行 compile。
# 進入虛擬機
limactl shell docker
# 執行安裝指令
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Version 2.0
# sudo curl -L "https://github.com/docker/compose/releases/download/v2.0.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
上面有提到,因為 lima
= limactl shell default
,因此它會使用 default 這個虛擬機,但上面建立好的會叫 docker,如果有需要用別名的話,要改成下面這樣:
alias docker="limactl shell docker docker"
alias docker-compose="limactl shell docker docker-compose"
已知問題
Mount host 檔案無法寫入
這是預設配置,主要是安全性考量。
如果想調整的話,修改 ~/.lima/default/lima.yaml
設定如下:
mounts:
- location: "~"
# CAUTION: `writable` SHOULD be false for the home directory.
# Setting `writable` to true is possible, but untested and dangerous.
writable: true
- location: "/tmp/lima"
writable: true
這裡是設定本機的哪些目錄可以寫入。把想要寫入的目錄設定好後,重新啟動 Linux VM 即可:
limactl stop default
limactl start default
Makefile 不吃 alias
參考 Stackoverflow,因此不能使用,直接一點的做法是寫個 script:
#!/usr/bin/env bash
# file: docker
limactl shell docker docker $@
#!/usr/bin/env bash
# file: docker-compose
limactl shell docker docker-compose $@
然後把這個檔案放在 /path/to/your/bin
,然後在啟動 shell 的時候加入 PATH 環境變數即可:
# ~/.bash_profile
PATH=/path/to/your/bin:$PATH
最後用 which
指令或 version
的子指令,確認有接到正確的指令即可:
# 查詢指令位置
$ witch docker
/path/to/your/bin/docker
$ witch docker-compose
/path/to/your/bin/docker-compose
# 直接查看版本
$ docker version
$ docker-compose version
Lima VM 出現 Broken 的狀態
出現的原因目前不明,在這個狀態下,使用 limactl ls
的範例如下:
$ limactl ls
WARN[0000] instance "docker" has errors errors="[failed to connect to \"/Users/miles/.lima/docker/ha.sock\": stat /Users/miles/.lima/docker/ha.sock: no such file or directory]"
NAME STATUS SSH ARCH DIR
docker Broken 127.0.0.1:60006 x86_64 /Users/miles/.lima/docker
從 log 來看,
ha.sock
應該是指的是hostagent
,類似地,ga.sock
指的是guestagent
以筆者遇到的狀況來說,會看到裡面有提到 ha.sock
找不到,但是 limacrl shell
卻又能正常進入 VM 執行 Docker 指令,甚至 Container 都能互相連結,這表示 VM 運作正常,但與 Host 的連結出現了問題。筆者在這個狀態下還有發現另一個現象是,port forwarding 運作有問題。
後來使用 limactl
都無法正常對 VM 做任何操作,最後只能使用 htop 或 ps 找到 QEMU 執行緒:
$ ps -aA | grep qemu
67116 ttys000 2:19.15 /usr/local/bin/qemu-system-x86_64 ...
終止程序(kill -9)後,它的狀態就會變 Stopped:
$ limactl ls
NAME STATUS SSH ARCH DIR
docker Stopped 127.0.0.1:60006 x86_64 /Users/miles/.lima/docker
重新 start 後就沒有出現錯誤訊息了:
$ limactl ls
NAME STATUS SSH ARCH DIR
docker Running 127.0.0.1:60006 x86_64 /Users/miles/.lima/docker
Lima Mount sshfs 出現錯誤訊息
在啟動 VM 的時候,看到錯誤訊息如下:
INFO[0034] [hostagent] Mounting "/Users/miles"
INFO[0034] [hostagent] fuse: mountpoint is not empty
INFO[0034] [hostagent] fuse: if you are sure this is safe, use the 'nonempty' mount option
INFO[0066] [hostagent] time="2021-10-19T16:40:55+08:00" level=warning msg="failed to confirm whether /Users/miles [remote] is successfully mounted" error="failed to execute script \"wait-for-remote-ready\": stdout=\"\", stderr=\"sshfs does not seem to be mounted on /Users/miles\\n\": exit status 1"
影響是啟動完 VM 後,裡面會沒有 host 的任何檔案,這會無法 Docker build 或 volume mount 等。
這個問題重啟也無效,最後只能砍掉重練解決:
limactl stop docker
limactl rm docker