bhyve

FreeBSD 下的虚拟技术 bhyve (The BSD Hypervisor) 包含在了 FreeBSD 10.0 发行版中。而这个 xhyve 是基于 bhyve 的 Mac OS X 移植版本



https://github.com/machyve/xhyve



使用 git 下载源码后编译,运行 xhyverun.sh 后会启动一个简单的 Tiny Core Linux 虚拟机:



$ git clone https://github.com/mist64/xhyve.git
$ cd xhyve
$ make
$ ./xhyverun.sh

我们知道docker 是基于linux 系统的namespace + cgroup实现的进程隔离技术,在mac下并不能很好的支持,因此需要运行在虚拟机上,虚拟机和docker的区别在于,虚拟机多了一层hypervisor。FreeBSD 下的虚拟技术 bhyve (The BSD Hypervisor) 包含在了 FreeBSD 10.0 发行版中。而这个 xhyve 是基于 bhyve 的 Mac OS X 移植版本



https://github.com/machyve/xhyve



    Docker for Mac 也是在本地跑了一个虚拟机来运行 Docker,不过 Hypervisor 采用的是 xhyve,而 xhyve 又基于 Mac 自带的虚拟化方案 Hypervisor.framework,虚拟机里运行的发行版是 Docker 自己打包的 LinuxKit。HyperKit是一个具有hyperisor能力的工具集,包含了基于 xhyve - macOS平台的KVM/bhyve (轻量级虚拟机和容器部署) 的完整hypervisor。HyperKit设计成上层组件诸如 VPNKit 和 DataKit 的接口。


注解



VPNKit:嵌入式虚拟网络库,VPNKit 是一个工具和服务集合用于帮助HyperKit虚拟机和主机VPN配置协作。https://github.com/moby/vpnkit



HyperKit:OSX上运行的轻量级虚拟化工具包https://github.com/moby/hyperkit



DataKit:现代化分布式组件框架https://github.com/moby/datakit



linuxkit是一个docker自己打包的linux镜像,非常小有点类似apline



https://github.com/linuxkit/linuxkit



    总结起来:docker for mac 是运行在mac上的虚拟机xhyve里,linux镜像linuxkit的实例里。

那么我们如何进入linuxkit呢?整体上有两大类方法:1,通过宿主机的tty或者socket进入。2,在linuxkit上运行容器,通过enterns进入。



在早期的docker for mac 版本中,我们看到虚拟机的文件路径是:


/Users/Kamus/Library/Containers/com.docker.docker/Data/vms/0/Docker.raw
进入到这个文件的所在目录。可以看到tty这个软链接文件。



$ cd /Users/Kamus/Library/Containers/com.docker.docker/Data/vms/0
$ ls -l
total 31067864
srwxr-xr-x 1 Kamus staff 0 7 4 12:22 00000002.000005f4
srwxr-xr-x 1 Kamus staff 0 7 4 12:22 00000002.00001000
srwxr-xr-x 1 Kamus staff 0 7 4 12:22 00000002.00001001
srwxr-xr-x 1 Kamus staff 0 7 4 12:22 00000002.0000f3a5
srwxr-xr-x 1 Kamus staff 0 7 4 12:22 00000003.000005f5
srwxr-xr-x 1 Kamus staff 0 7 4 12:22 00000003.00000948
-rw-r–r–@ 1 Kamus staff 63999836160 7 7 12:51 Docker.raw
-rw-r–r– 1 Kamus staff 215040 7 4 12:22 config.iso
srwxr-xr-x 1 Kamus staff 0 7 4 12:22 connect
lrwxr-xr-x 1 Kamus staff 17 7 4 12:22 guest.000005f5 -> 00000003.000005f5
lrwxr-xr-x 1 Kamus staff 17 7 4 12:22 guest.00000948 -> 00000003.00000948
-rw-r–r– 1 Kamus staff 2303 7 4 12:22 hyperkit.json
-rw-r–r– 1 Kamus staff 4 7 4 12:22 hyperkit.pid
drwxr-xr-x 2 Kamus staff 64 11 21 2018 log
-rw-r–r– 1 Kamus staff 36 11 21 2018 nic1.uuid
lrwxr-xr-x 1 Kamus staff 12 7 4 12:22 tty -> /dev/ttys000
screen该文件即可连接到虚拟机的输出窗口中。



$ screen tty
在新的版本里(20.10.5)版本以后,使用socket代替了:



I think the new version of docker (my version is 20.10.5) uses socket instead of TTY to communicate with the virtual machine so you can use the nc command instead of the screen command.



nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock
?????uname -a
Linux docker-desktop 5.10.47-linuxkit #1 SMP PREEMPT Sat Jul 3 21:50:16 UTC 2021 aarch64 Linux
可以看到,运行的镜像是linuxkit



    还可以使用更优雅的方式,临时建一个最小化的debian容器,指定容器运行在pid=host命名空间下,然后该容器运行nsenter命令。


$ docker run -it –rm –privileged –pid=host debian nsenter -t 1 -m -u -n -i sh
Unable to find image ‘debian:latest’ locally
latest: Pulling from library/debian
6f2f362378c5: Pull complete
Digest: sha256:118cf8f3557e1ea766c02f36f05f6ac3e63628427ea8965fb861be904ec35a6f
Status: Downloaded newer image for debian:latest
# uname -a
Linux linuxkit-025000000001 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 Linux
详细解释一下这条命令为什么就会登录进macOS中作为宿主机的VM里面。
–rm表示在退出的时候就自动删除该容器;
–privileged表示允许该容器访问宿主机(也就是我们想要登录的VM)中的各种设备;
–pid=host表示允许容器共享宿主机的进程命名空间(namespace),或者通俗点儿解释就是允许容器看到宿主机中的各种进程;
这些是docker在启动容器时候的参数设置,但是仅仅依靠这些参数还无法让我们直接登录到宿主机VM中,接下来解释最主要的nsenter命令。



nsenter是一个小工具允许我们进入一个指定的namespace然后运行指定的命令,ns=namespace,enter=进入。
namespace是容器技术的根基,基本上可以认为namespace就是一组隔离的资源,不同的进程可以看到不同的系统资源这里和这里有比较详细的关于namespace的介绍。
可以从操作系统的/proc/[pid]/ns目录下一窥全貌。比如我们进入pid=1的ns目录下。可以看到有一共8种namespace。



pwd


/proc/1/ns


ls -l


total 0
lrwxrwxrwx 1 root root 0 Jul 8 12:51 cgroup -> cgroup:[4026531835]
lrwxrwxrwx 1 root root 0 Jul 8 12:51 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 Jul 8 12:51 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 Jul 8 12:51 net -> net:[4026531889]
lrwxrwxrwx 1 root root 0 Jul 8 12:51 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 Jul 8 12:51 pid_for_children -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 Jul 8 12:51 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Jul 8 12:51 uts -> uts:[4026531838]
最后解释一下nsenter命令的选项。回顾一下命令是:nsenter -t 1 -m -u -n -i sh
-t 1: 表示要进入哪个pid,1表示整个操作系统的主进程id
-m: 进入mount namespace,挂载点
-u: 进入UTS namespace,也就是上面我们演示的那个namespace
-n: 进入network namespace,网络
-i: 进入IPC namespace,进程间通信
sh: 表示运行/bin/sh



https://developer.aliyun.com/article/116675



https://cloud-atlas.readthedocs.io/zh_CN/latest/kvm/macos_xhyve/xhyve.html



https://www.kaifa99.com/GitHub/article_125375



https://medium.com/@hintcnuie/the-difference-between-xhyve-and-hyperkit-67a9f378ab97



https://github.com/moby/vpnkit



https://github.com/moby/datakit



https://www.nebulaworks.com/insights/posts/getting-started-linuxkit-mac-os-x-xhyve/



https://docs.docker.com/desktop/mac/



Docker for Mac 也是在本地跑了一个虚拟机来运行 Docker,不过 Hypervisor 采用的是 xhyve,而 xhyve 又基于 Mac 自带的虚拟化方案 Hypervisor.framework,虚拟机里运行的发行版是 Docker 自己打包的 LinuxKit



https://www.haoyizebo.com/posts/fd0b9bd8/



% brew install opam libev



opam init No configuration file found, using built-in defaults. Checking for available remotes: rsync and local, git.



you won’t be able to use mercurial repositories unless you install the hg command on your system.
you won’t be able to use darcs repositories unless you install the darcs command on your system.
<><> Fetching repository information ><><><><><><><><><><><><><><><><><><><> 🐫 Processing 1/1: [default: http]



https://github.com/linuxkit/linuxkit



https://github.com/linuxkit/kubernetes



https://blog.51cto.com/lullaby/2421309



https://tonybai.com/2021/03/23/io-fs-interface-is-an-excellent-design/



https://github.com/docker/for-mac



https://www.zhihu.com/question/40051989?sort=created



https://cleanmymac.cn/download https://www.pagetable.com/?p=831



https://github.com/Wang-Kai/cherish-today/issues/83



https://www.zhihu.com/question/454947910/answer/1841432604



https://github.com/moby/hyperkit. √



https://forums.docker.com/t/how-to-make-changes-to-xhyve-host/11820/5



https://github.com/machyve/xhyve



https://forums.docker.com/t/is-it-possible-to-ssh-to-the-xhyve-machine/17426



https://zhuanlan.zhihu.com/p/43237959



https://docs.docker.com/engine/reference/commandline/dockerd/



https://blog.csdn.net/zhangmenghao1983/article/details/82184957



https://blog.csdn.net/baidu_32656897/article/details/86504317



https://www.cnblogs.com/cag2050/p/10100899.html



https://www.dbform.com/2019/07/08/how-to-login-the-vm-of-docker-desktop-for-mac/



https://medium.com/carvago-development/my-docker-on-macos-part-1-setup-ubuntu-virtual-machine-both-intel-and-apple-silicon-cpu-5d886af0ebba



https://gist.github.com/BretFisher/5e1a0c7bcca4c735e716abf62afad389



https://www.modb.pro/db/5458



https://earthly.dev/blog/using-apple-silicon-m1-as-a-cloud-engineer-two-months-in/



2



I think the new version of docker (my version is 20.10.5) uses socket instead of TTY to communicate with the virtual machine so you can use the nc command instead of the screen command.



nc -U ~/Library/Containers/com.docker.docker/Data/debug-shell.sock



https://stackoverflow.com/questions/38532483/where-is-var-lib-docker-on-mac-os-x



?????uname -a Linux docker-desktop 5.10.47-linuxkit #1 SMP PREEMPT Sat Jul 3 21:50:16 UTC 2021 aarch64 Linux



https://www.krenger.ch/blog/docker-desktop-for-mac-ssh-into-the-docker-vm/



https://stackoverflow.com/questions/39739560/how-to-access-the-vm-created-by-dockers-hyperkit



https://www.jianshu.com/p/ab6f8be85470



https://collabnix.com/how-docker-for-mac-works-under-the-hood/



https://collabnix.com/how-docker-for-mac-works-under-the-hood/



https://gist.github.com/retraut/1dee3d6331c4b8eeb4ef54bfdce09d62



https://wongyouth.github.io/2019/04/28/xhyve-%E8%8B%B9%E6%9E%9C%E7%94%B5%E8%84%91%E4%B8%8B%E8%BD%BB%E9%87%8F%E7%BA%A7%E8%99%9A%E6%8B%9F%E6%9C%BA%E6%96%B9%E6%A1%88/



https://www.wavether.com/2016/09/docker-machine-xhyve-mac-os



/ # ^[[26;5Rctr version ctr version Client: Version: v1.3.4 Revision: 814b7956fafc7a0980ea07e950f983d0837e5578



Server: Version: v1.3.4 Revision: 814b7956fafc7a0980ea07e950f983d0837e5578 UUID: d0bdf2c7-b3d8-45f2-be9a-ffdd6c782cc5 / # ^[[26;5R^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@



hyperkit % make



% ./hyperkitrun.sh ~/source/hyperkit/test ~/source/hyperkit Downloading tinycore linux



~/source/hyperkit hv_vm_create HV_ERROR (unspecified error) ./hyperkitrun.sh: line 39: 84413 Abort trap: 6 build/hyperkit $ACPI $MEM $SMP $PCI_DEV $LPC_DEV $NET $IMG_CD $IMG_HDD $UUID -f kexec,$KERNEL,$INITRD,”$CMDLINE”



https://github.com/kubernetes/minikube/issues/10120



https://github.com/moby/hyperkit/issues/303#issuecomment-875122919



HyperKit是一个具有hyperisor能力的工具集,包含了基于 xhyve - macOS平台的KVM/bhyve (轻量级虚拟机和容器部署) 的完整hypervisor。HyperKit设计成上层组件诸如 VPNKit 和 DataKit 的接口。



注解



VPNKit 是一个工具和服务集合用于帮助HyperKit虚拟机和主机VPN配置协作。



DataKit 是一个使用类似Git的工作流来编排应用程序的工具,借鉴了UNIX管道(pipline)概念,使用了替代底层文本的树状结构数据的流。DataKit可以在版本控制数据上定义复杂的编译工作流。当前DataKit作为HyperKit的一个写作流,以及用于 DataKitCI 持续集成系统。



要激活块设备后端支持qcow,准备一个 OCaml OPAM开发环境。则需要通过 brew 安装 opam 和 libev 然后使用 opam 来安装相应的库:



brew install opam libev opam init eval opam config env opam install uri qcow.0.10.4 conduit.1.0.0 lwt.3.1.0 qcow-tool mirage-block-unix.2.9.0 conf-libev logs fmt mirage-unix prometheus-app



https://cloud-atlas.readthedocs.io/zh_CN/latest/docker/moby/hyperkit/run_hyperkit.html



HyperKit:OSX上运行的轻量级虚拟化工具包 DataKit:现代化分布式组件框架 VPNKit:嵌入式虚拟网络库



http://dockone.io/article/1329



https://github.com/moby/hyperkit



https://minikube.sigs.k8s.io/docs/drivers/hyperkit/


Category docker, k8s