自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何在 Mac 上愉快地使用 Docker

系統(tǒng) Linux
首先要明確的是, 作為一個每天在 Linux Server 上 rm -rf 的人來說, 如果想在 Mac 上使用 Docker, 最舒服的也是兼容所有 docker cli 命令行操作即可。

一、目標任務(wù)

至于圖形化的界面完全不需要, 我們并不指望圖形化界面能比敲命令快到哪里去, 也不指望圖形化界面變?yōu)橹髁? 所以本篇文章的核心目標:

  • 在 Mac 上使用完整的 docker cli 命令, 包括對基本的 -v 掛載支持
  • 可以支持 x86 的模擬, 可以為 x86 build 或者運行相關(guān)鏡像
  • 在盡可能的情況下可以進行 CPU 架構(gòu)切換, arm64 與 x86 最好都可以支持

二、工具選型

首先是我們最熟悉的 Docker Desktop, 安裝包奇大無比, UI 卡成翔, 啟動速度更不用提而且還時不時的卡死, 所以 Docker Desktop 是完全不考慮的; 那么剩下幾種方案類型如下:

  • VM 虛擬機方案
  • Colima 方案
  • Lima 方案

先說結(jié)論: Lima YES! VM 虛擬機方案要花錢且難受, Colima 暫且不穩(wěn)定. Lima 方案直接看第五節(jié).

三、虛擬機方案

目前在 M1 上, 唯一可用或者說堪用的虛擬機當屬 Parallels Desktop, 至于其他的 VBox、VMware 目前還不成熟; 如果純 qemu 有點過于硬核(愿意自己封裝腳本的當我沒說); 對于 Parallels Desktop 來說, 我們需要購買開發(fā)版本的 License, 因為我們需要借助 prlctl 來實現(xiàn)一些自動化 , 一年好幾百… 經(jīng)過測試這種方案也有一定可行性:

  • 1、首先通過 PD 創(chuàng)建 Ubuntu 之類的虛擬機
  • 2、在虛擬機里安裝好 Docker
  • 3、通過 cli 程序啟動虛擬機, 并且將 ~ rw 掛載到虛擬機里

基于這個方案我個人嘗試過, 曾經(jīng)寫過一個 PD 的小工具來輔助完成掛載動作. 但是這種工具有一些明顯的缺點:

  • 目前不支持 x86 的模擬, 可通過 binfmt 緩解, 但是不完善
  • 虛擬機要花錢且需要虛擬機 cli 支持完善

四、Colima 方案

Colima 號稱是專門為了解決 Mac 平臺容器化工具鏈的, 但是實際測試發(fā)現(xiàn)目前 Colima 還不算穩(wěn)定, 有時可能會有一些小問題; 當然 Colima 最大的問題是: 可自定義化程度不高, 底層基于 Lima. Colima 具體的使用方式啥的這里暫不詳細描述, 目前還不穩(wěn)定不太推薦.

五、Lima 方案

Lima 目前是基于 QEMU 的自動化 VM 方案, 當前由于其出色設(shè)計, 借助 Cloud Init 可以在很多階段幫助我們完成 hook; 所以不論是裝個 Docker 還是 k8s, 亦或是弄個其他的東西都很方便; 而且很多方案比如 docker 官方都有相關(guān)樣例, 我們可以直接照抄外加做點自定義.

5.1、Lima 安裝

Lima 在 Mac 下安裝相對簡單, 以下命令將安裝 master 分支版本.

brew install lima --HEADCopy

在正常情況下, 安裝 Lima 會附帶安裝 QEMU, 如果本機已經(jīng)安裝 QEMU, 可能需要執(zhí)行以下命令將 QEMU 升級到 7.0:

brew upgrade qemuCopy

為了使用 docker, 還需要通過 brew 安裝一下 docker cli:

brew install dockerCopy

5.2、Lima 使用

默認情況下 Lima 安裝完成后會生成一個 lima 的快捷命令, 目前不太推薦使用, 原因是看起來方便一點但是沒法控制太多參數(shù), 所以仍然建議使用標準的 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

5.3、Lima 配置文件

Lima 通過讀取一個 yaml 配置描述文件來決定如何創(chuàng)建一個虛擬機, 該文件基本結(jié)構(gòu)如下:

# 定義每個平臺架構(gòu)需要使用的啟動鏡像
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"
# 定義虛擬機需要使用哪個架構(gòu)啟動(對應上面的鏡像)
arch: "x86_64"
# CPU 數(shù)量
cpus: 4
# 內(nèi)存大小
memory: "16G"
# 磁盤大小
disk: "100G"
# 虛擬機與 macOS 宿主機掛載時使用的掛載技術(shù)
# 目前推薦 9p, 可換成 sshfs, 但是 sshfs 會有權(quán)限問題
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:
# 定義以什么權(quán)限在虛擬機內(nèi)執(zhí)行腳本
- 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 https://get.docker.com | 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
------
Copy

5.4、啟動 VM

limactl 命令提供了一個 start 子命令用于啟動一個虛擬機, 子命令接受一個參數(shù), 這個參數(shù)形式不同會產(chǎn)生不同的行為:

  • 如果參數(shù)為一個文件路徑, 則假定文件為一個 lima 虛擬機的 yaml 配置, 讀取并啟動
  • 如果參數(shù)是單純字符串, 首先嘗試從已存在的虛擬機中查找名字相同的, 找到則立即啟動
  • 如果參數(shù)是單純字符串, 且未找到已存在同名的虛擬機, 則嘗試通過內(nèi)置模版來創(chuàng)建一個新的虛擬機

以上面我自己定義的 docker 配置文件為例, 我們直接啟動這個配置既可以創(chuàng)建一個 docker 虛擬機:

limactl start ./docker-amd64.yamlCopy

啟動后會提示是否編輯然后再啟動, 這是為了使用同一個配置來啟動多個 vm 使用的, 所以不編輯直接啟動即可:

稍等片刻后虛擬機將啟動成功:

啟動完成后, 執(zhí)行最下面打印出的兩條命令, 即可在宿主機上完整的使用 docker. 其本質(zhì)上利用 docker context 功能, 然后通過將虛擬機中的 sock 文件掛載到宿主機, 并配置 docker context 來實現(xiàn)無縫使用 docker 命令.

5.5、虛擬機調(diào)整

某些情況下, 我們需要定制一些 VM 里的配置, 在定制時主要需要調(diào)整配置文件的 provision 部分; 在該部分中, 如果 mode 被定義為 system 則會以 root 用戶執(zhí)行相關(guān)命令, 否則以普通用戶來執(zhí)行命令. 需要注意的是, 我們定義的腳本需要具有冪等性, 因為腳本在每次都會執(zhí)行一次, 所以一般對于可能造成數(shù)據(jù)擦除動作的命令都要寫好判斷邏輯, 避免重復執(zhí)行.

關(guān)于文件掛載, 這里推薦使用 9p 類型, 未來 lima 將完全切換到該掛載方式; 同時經(jīng)過測試目前僅有 9p 掛載模式下, 本地目錄 rw 映射到虛擬機時不會出現(xiàn)權(quán)限問題, sshfs 方式掛載如果遇到 chown 之類的命令會造成權(quán)限錯誤, 可能導致容器啟動失敗(例如 mysql).

在測試虛擬機配置過程中, 可以直接使用 limactl delete -f xxxx 來強制刪除目標虛擬機, 然后重新啟動即可; 虛擬機名稱默認與 yaml 文件名相同, 可使用 limactl ls 命令查看.

5.6、多平臺兼容

在上面我的 docker 配置樣例中, 每次虛擬機啟動完成后會自動安裝 binfmt:

docker run --platform=linux/amd64 --privileged --rm tonistiigi/binfmt --install allCopy

這樣能保證無論 Lima 虛擬機原始架構(gòu)是什么, 都能運行其他平臺的 docker 鏡像; 典型的例如某些 openjdk8 鏡像只有 amd64 的版本, 但是在 lima 虛擬機為 aarch64 的情況下仍然可以使用.

除了這種 “速度較快” 的跨架構(gòu)運行方式, lima 還支持直接在 VM 中定義架構(gòu), 這樣在 qemu 啟動時則會直接從 VM 系統(tǒng)層模擬目標架構(gòu); 這種方式的好處是對目標架構(gòu)兼容性很好, 但是運行速度會更慢. 調(diào)整 VM 架構(gòu)只需要修改 arch 配置即可(注意, 目標架構(gòu)的鏡像一定要配置好):

# 定義每個平臺架構(gòu)需要使用的啟動鏡像
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"
# 定義本虛擬機需要使用哪個架構(gòu)啟動(對應會使用上面目標架構(gòu)的鏡像)
arch: "aarch64"Copy

六、總結(jié)

目前整體來看, Docker Desktop 在 mac 上基本上是很難用的, Colima 現(xiàn)在還不太成熟, 適合輕度使用 docker 的用戶; 而重度使用 docker 并且有定制化需求的用戶還是推薦 Lima 虛擬機; 同時 Lima 也支持很多操作系統(tǒng), 官方有大量的樣例模版(包括 k8s、k3s、podman 等), 非常適合重度容器使用者。

責任編輯:龐桂玉 來源: 奇妙的Linux世界
相關(guān)推薦

2015-10-20 16:48:06

AnsibleDocker可擴展設(shè)計

2014-07-29 09:30:10

Win 8

2019-07-12 16:28:32

MacKubernetes

2020-07-08 15:29:05

MacJava編程語言

2016-11-03 20:06:53

UbuntuGrafanaDocker

2021-09-15 08:00:00

Windows 11Windows微軟

2020-05-25 17:40:00

MacpyenvPython

2024-01-04 11:50:00

UbuntuDocker

2021-03-25 12:50:31

Linux磁盤命令

2020-11-30 11:55:07

Docker命令Linux

2017-02-16 10:15:43

Windows7docker變量

2014-12-01 11:27:54

CentOS 7Docker

2019-01-07 09:50:06

Linuxtarball命令

2019-11-26 16:58:51

Linuxpkgsrc

2021-07-25 10:34:17

FedoraPodmanLinux

2023-01-17 07:40:59

LinuxAppImage應用程序

2021-10-02 10:10:47

LinuxBusyBox命令

2015-07-31 15:35:09

Mac安裝Windows 10

2022-01-07 21:12:46

鴻蒙HarmonyOS應用

2020-08-24 12:37:54

Linuxxargs命令
點贊
收藏

51CTO技術(shù)棧公眾號